Search
Categories

Entries in data source (2)

Tuesday
18Aug2009

Saving One out of Many Data Sources on an XPage and How to Create a New Document On Each Submission

Over on Julian's Blog, he asked a question on how to submit only one data source out of multiple ones on an XPage, and then create a new document for that data source so that the next submission will create yet another new document. I put together a quick sample for him, but thought I'd detail it more here for everyone.

First, a quick description of the back end of the design. I created three documents, "Form 1", "Form 2", and "Form 3" ... each with a single uniquely named field. Then I created three views, one for each form, that displayed only that form, and the first column had the appropriate field for each form.

Now, we can create the XPage. Drop three panels on the form, and name them updateRegion1, updateRegion2, and updateRegion3 respectively. In each panel, and a view component, based on each of the respective views for each form.

You should have an XPage that so far looks similar to this:

Now, at the bottom of each of the updateRegionX panels, lets add another panel. for this panel, define a data source that is a new document of each panel's document (Form 1 for updateRegion1, Form 2 for updateRegion2, etc) called "documentX", again replacing the X with the form number, i.e. document1, document2, etc....

After you define the panel's data sources, add a field inside the new panel, binding it to that panel's datasource and the associated form's unique field, and add a button labeled "Save Form X", replacing X with the appropriate form number. You should have something like this:

At this point, you could set a simple action to "save document" to submit a single data source, or "save data sources" to submit all three. However, we want to be able to independantly submit each data source, update just that view, AND create a new document for that data source, so when it gets submitted again, it will submit as a new document.

So here's what you do. Select the button "Save Form 1", go to the Events tab, and change the "Server Options" to "Partial Update", and select "updateRegion1" for the IDs. Change the Server actions to "Script Editor" and enter the following lines of code:

document1.save();
document1.getDocument().replaceItemValue("FieldA", "")

The first line saves the document, and the second line clears the value of FieldA... This is important because in the next step, we'll tell the xPage to create a new document everytime the form is submitted, however, it won't clear the values of the previous submission... This line does that (if you had more fields, you'd add a line for each field you wan't to clear.) Here's a screen shot of the server event:

Ok, now here's the hidden gem to make this all work. Back on the panel where we created the document1 data source. Go to All Properties, and expand Data > data > dominoDocument and change the scope to "request"

Now, everytime the form is submitted, a new document is created. Repeat this for each of the other updateRegions. Then, just to prove there isn't any other trickery going on, or to make sure it isn't saving the other data sources when we save the a single source, add one more button to the bottom of the XPage labeled "Full Refresh, No Document Save" ... on the Events for that button, change the Server Options to "Full Update", and check the "Do not validate or update data" checkbox. That way you can force the page to refresh, and see that no other documents are getting created or saved.

Here's what it should look like on the web, after a bit of data has been created:

Now, if you've gotten this far and have been following along, and creating the database as you go, my apologies, because you can download the full working sample here.

 

UPDATE: Apparently the post/query events do not get called if you use document1.save(), so if you need them to run, change back from "Script Editor" to "Simple Actions" on your button, and an action group, add a "Save Document" action, followed by an "Execute Script" action to clear out your fields, as below:

Monday
17Aug2009

XPages - How to pass a Document Data Source to a Custom Control

In a previous article on my blog, I explained how you can use the undocumented currentDocument data source object to get the data source for the XPage from a Custom Control. This works great if the XPage has one data source. What if you have multiple data sources? For example, you want to include a custom control within a repeat control that is accessing multiple documents from a document collection or a view. The currentDocument variable would only point to the first data source on the XPage.

At first glance, looking at the data types that are available for parameters in a Custom Control, you cannot pass a data source object. The type list drop down is a list of standard JavaScript variable types.






But, if you click on the folder icon next to the Type field you will see an extended list of type available.



Then from your XPage you can pass the datasource using computed JavaScript, such as: "OrderDetails.getDocument();"
*updated - see note below
 

Binding fields on a Custom Control to a dynamic datasource
The second part of this can be tricky. On your Custom Control you cannot use the "Simple Data Binding" option to bind your fields since you have no datasource set for the Custom Control, the datasource is dynamic.

The perfect solution for this is to use the Advanced -> Expression Language (EL) binding. For example, to bind the field to the "Comment" field, we would use "compositeData.docdatasource.Comment". Where....
- compositeData holds all the parameters for the Custom Control
- docdatasource is the parameter that we created that receives the datasource
- Comment is the field name on the Notes form

 

Now, with that said, there is an issue with this in 8.5. DDE tries to convert the EL expression to a Simple data binding when you save and reopen the Custom Control. So it works the first time you enter it, but loses the binding when you edit the Custom Control. However, it looks like this is fixed in 8.5.1.

BUT, no sweat, I have a workaround. If you select JavaScript for the binding type, select "Compute on page load", and then enter the formula as '#{compositeData.docdatasource.Comment}' it will continue to work.

 


Here's an example of the Custom Control used with multiple Data Sources in action:

 

You can download this example here.

*update - by passing the NotesXSPDocument instead of the NotesDocument, the fields will automatically handle whether the document is in read or edit mode.

To do this, select "ModelDataSource" as the type for the property.  Then when passing the datasource from your XPage change the JavaScript from "OrderDetails.getDocument()" to just "OrderDetails".


-John