XPages - SSJS - Get ALL profile documents - xpages

With LotusScript I can use Set notesDocumentCollection = db.GetProfileDocCollection() to get a collection of ALL the profile documents in a database. I would like to do the same using SSJS. However, database.getProfileDocCollection(profileName) obliges me to use a specific profile name. Is there any way in SSJS of getting a collection of ALL profile documents in a database (as is the case with LotusScript)?

You can get all profile documents with
var dc:NotesDocumentCollection = database.getProfileDocCollection(null);
Just set null as parameter. Tested it with Domino 8.5.3 FP6 and 9.0.1 FP1.

Looking at the Help, in Java there is only the method corresponding to the SSJS version you mentioned, passing a profile form name. It doesn't look like there's a Java equivalent to the LotusScript option of not passing a form name. So there will not be an in-built option.
Profile documents tend to get cached and it is a more significant issue on the web. I hit significant problems when I started with profile documents in XPages Help Application. That's why I changed to creating "pseudo-profile documents" by changing the UNID. See http://www.thenorth.com/apblog4.nsf/0/63F5C6B1F08957AC8525747D005AA429 and http://avatar.red-pill.mobi/nathan/escape.nsf//D6Plinks/NTFN-7GA4FJ

The NoteCollection class should let you find all profiles in a single search.

Related

extension library rest control Xpages

I am using extension library Rest controls ViewJsonservice to provide the data from Notes database, is there a easy way using same control I can provide the data from two databases, I can put the similar view from dbA to dbB
Short answer: no
Long answer:
I presume you want the data from 2 views available in a single endpoint. Either after each other (appended) or somehow merged.
You can do that using code. Check this article for basic info.
In a nutshell: use the ViewNavigator class in both databases to retrieve results and append or merge the data before you return it.
Nice side effect : you can return all the data.

calling Lotusscript libary from javascript library which return NotesDocumentCollection xpages

Is there anyway to call Lotusscript library from server javascript library which return NotesDocumentCollection xpages.
My Old lotusscript library are used in agents and now I am migrating my application to xpages so needed to call these lotusscript for code reuse.
You can't exchange arbitrary objects directly like that. However, they did add the ability to run an agent with runWithDocumentContext to pass in a designated in-memory Document to use as context, which is a bit more flexible than the older NoteID parameter. You can use that to create a doc in-memory, pass it to the agent, have the agent fill it with info (say, the note IDs of the collection as a multi-value text or RT item), and then read the value back out XPages-side.
Granted, this is more awkward than your immediate desire, but it's the tool we have that doesn't resort to Ajax round-trips.

How can I read the translation labels from profile documents in XPages?

I am xpages enabling an old Notes application which is using profile documents to store translated labels. The translated lables in the notes form are read from the profile document using #GetProfileField depending on which language the user have selected in their profile.
I have read that profile documents are not recommended to use with xpages so I need a better solution for my xpages users. but it is important that users using Notes client still use the "old" profile document solution.
How can I provide these translation lables to my xpages users?
Thanks
Thomas
In addition to Knut's answer there is also the option to "double" your translated labels via the way to prefer in XPages dev by using the localization options as described here: http://www-10.lotus.com/ldd/ddwiki.nsf/dx/UsingLocalizationOptions.htm
You need to split the task into two. First have a function that is called inside the XPage to get the label you are looking for, secondly have a way to provide that value inside the function.
Making a direct call to the profile isn't a good idea since it fixes the way you provide the data (besides potentially creating a memory leak if you don't recycle dilligently). I would see 4 potential solutions:
Define your profile document as additional data source and simply bind the labels to items in the document. Saves you most of the recycling work, but couples tight
Use a SsJS function: getLabel(name). It would check for a scope variable (a Map) and if not found load it - currently from your profile. If application scope is good enough, you touch the profile once only- speed. If you change the loader later on - you don't need to change anything in the XPage.
Use a managed bean. Same approach as #2, only now you can use el data binding. Your bean needs to implement Map
If the labels hardly change do a design time conversion and write the profile doc out into properties files (works nicely with ODP) and use XPages internal mechanism for internationalization
Let us know how it goes
You can use profile documents for this use case as the content gets changed only with new versions of your project probably. So, you can easily live with profile document's caching.
You get the label translation from a profile document with
var doc = database.getProfileDocument("LabelsEnglish", "");
var label = doc.getItemValueString("label1");
doc.recycle();
return label;
You could read all labels in an application scope variable Map too and do your own caching. This way profile documents would get read only once.
if (!applicationScope.labels) {
var map = new java.util.HashMap();
var doc = database.getProfileDocument("LabelsEnglish", "");
var allItems = doc.getItems();
for (var i = 0; i < allItems.size(); i++) {
var item = allItems.elementAt(i);
item.getName();
map.put(item.getName(), item.getValueString());
item.recycle();
}
doc.recycle();
applicationScope.labels = map;
}
Execute the SSJS code above in a custom control which is included in every XPage (e.g. application layout custom control) in before page load event so you can be sure application scope variable "labels" is initialized when you want to use it. You can access the labels easily with EL
applicationScope.labels.label1

Xpage dynamic Id for data update or validation(CSJS)

Before describing the problem, I would like to add that I have looked for this problem on google and have found many solutions but none related to XPAGES. Since, Xpage have a unique method to generate the field id I am facing this problem. I have also posted the same question here on IBM forum and awaiting the reply there(http://www-10.lotus.com/ldd/ndseforum.nsf/xpTopicThread.xsp?documentId=EDEBB14BDF2E804F85257BE8001E4F76):
Problem:
I am trying to pass dynamic id to the default function getElementById with no success. To explain it clearly, I have a front end validation for specific fields. This fields are stored n database. So, I have a for loop running for all the fields. The problem here is that XPages generates the Id dynamically and hence for the same form if there is a hierarchical tabbed panel then the Id also included the tabbed panel Id in it.
Here is the code view of the problem:
The standard method to retrieve the value(CSJS) is:
document.getElementById("#{id:inputText1}").value;
However, if I try to pass in a dynamic id. It doesn't work. I have tried "n" number of approaches I found on Google but none regarding this problem. One solution I tried here was:
var x = "inputText1";
document.getElementById("#{id:"+x+"}").value;
Any help would really be appreciated. Really eager to hear some good suggestion.
The "#{id:inputText1}" part is computed at the server before the page is served so it's too late to set the ID in client side JS.
To set the ID in SSJS you can do this:
document.getElementById("#{javascript:var x='inputText1'; getClientId(x)}").value;
With getClientId you can also build a CSJS array of IDs in in SSJS. Then you can loop that array in CSJS. You would build the array this way:
var strIDs = ${javascript:'["a","b","c"]'};

Dynamic field binding inside a repeat control

I have a strange thing, I'm using dynamic field binding in a custom control.
The field binding is created like this.
XPage (Datasource "document" is placed here)
Custom Control (String passed in)
(to get errors if there are any)
Repeat (CompositeData is passed to a bean that returns the strings for Rows,columns)
Repeat (repeat 1 variable used for Columns)
Custom Control (fieldname is passed in)
field binding is done like this
#{document[compositeData.fieldName]}
The problem is that when I save the XPage I get an error in the messages control
Document has been saved by another user - Save created a new document as a response to that modified document.
And all fields are cleared.
Any ideas how to debug this or is there something I'm missing?
The "Document has been saved by another user" error is only tip of the iceberg - there are some really strange problems with reapeats that repeats fields that are bound and repeatControls property is set to false. The decoding part of xpages lifecycle cannot handle it properly - the controls will be losing data. You should use repeatControls set to true as Martin suggests.
"Repeat control variable doesn't exists" is probably caused by the property that removes repeats set to true. You can solve this by either changing it to false or by adding additional data context that will keep repeated value.
And finally for this to have add/remove functionality You can use Dynamic Content Control and show(null) hack to rebuild the repeat content.
To manage this complexity better I would advise You to stop using document data source and start creating some managed beans.
If You will follow my suggestions I guarantee that You will get the functionality You are looking for as I have few apps that works great and have this kind of complex data editors in them.
I don't know if it'll help you, but I pass both the document datasource and the field name as parameters to a DynamicField control, and use it like this:
compositeData.dataSource[compositeData.fieldName]
The type of the datasource is com.ibm.xsp.model.DataSource, it's listed as dataInterface under Data Sources.
Do you have repeatControls="true" set for the repeat control?
It sounds like you've got the datasource defined multiple times on the XPage (plus custom controls). Either that or the save button has save="true" but the code saves the document back-end, or code in multiple places saves the same document. I've used the same method of passing the datasource down to the custom control, but that may just be because that was what I saw on a blog.

Resources