Dynamically Modify the Data Source on an Embedded Form in XPages

With inspiration from awesome XSnippet posted by Sven Hasselbach, I’ve found a much better way to work with embedded forms of related documents on an XPage.

Managing the Data Source with Scope Variables

I recently worked on an application that had a view of related documents embedded within a parent document page, along with an embedded form to work with the related documents. This concept applies to child/response documents as well as separate documents, related based on common piece of information. (By “embedded form”, I’m referring to a custom control with it’s own data source based on a separate Notes client form, displayed within the context of the parent page.)

As with any type of document data source, creating, viewing, and editing are the three types of data source actions.

By default, the embedded form is blank and can be used to submit a new related document. However, if the user clicks on a related document in the embedded view, they should have the ability to view or edit the selected document, based on their rights.

Along with the action, the document ID needs to be managed. It either needs to be blank (in the case of a new document) or set to the UNID of the document selected in the view.

Initial Implementation

The following steps were taken to implement this functionality:

  • Compute the data source’s action from a scope variable (defaulting to createDocument if no other variable was specified)
  • Compute the data source’s documentId from a scope variable
  • Set the data source’s ignoreRequestParams attribute to true
  • Set the links in the view to set the selected document’s UNID in a scope variable and also determine whether the form should be opened or edited and set the appropriate action in a scope variable (openDocument or editDocument, respectively)
  • Set the links in the view to trigger a partial refresh on the form panel in order to update the document in the embedded form
  • Set the Save button on the embedded form to clear the embedded form fields after saving a new or edited document
  • Hope that no one would try to view and create documents within the same page view

The Biggest Challenge

The biggest challenge I ran into was creating a new document with the embedded form after viewing or editing an existing document. No matter what I did, it would always update the previously-edited document with any changes that were made.

The Solution

Fortunately, I was able to solve that problem by scoping the data source to the request, so it stopped hanging onto the previous document and allowed for the creation of new documents. This was done via the scope property of the data source, found under All Properties > data > data > dominoDocument[0] > scope.

Managing the Data Source Dynamically

This method works, manipulating the data source directly makes it much simpler to implement and manage! With a few lines of code, you can replace the need for computed data source values, leaving all of the logic in the link that opens the form.

In my case, I’m attaching the data source to a panel on the page. Sven’s snippet shows how to attach the data source to the page itself.

This response from Sven to a question on Stack Overflow shows how you can clear all data sources and add a new one (to work around the same problem I was facing). Note: If you do that, be sure to set the variable name of the new data source the same as when you first bound fields to it, so all field bindings remain in tact.

I did some testing and found that I didn’t even need to remove and re-create the data source. I’ve been testing just updating the parameters of the data source and it seems to work well. One caveat I’ve seen so far is that if I try to open a document in edit mode, close it, then re-open in read mode before changing the documentId of the source to another document, it sticks with the first mode. If you have a case where you need to do that in succession, then maybe removing the data source and re-creating it altogether would do the trick.

The Code

Now, I have a ‘New’ button at the top and a repeat control with links to open and edit each document.

New Document

var ds = getComponent('panelName').getData()[0]; 
ds.setDocumentId(''); 
ds.setAction('createDocument'); 

Open Document (varRepeat is the repeat control variable)

var ds = getComponent('panelName').getData()[0]; 
ds.setDocumentId(varRepeat.getDocument().getUniversalID().toString()); 
ds.setAction('openDocument');

Edit Document (varRepeat is the repeat control variable)

 
var ds = getComponent('panelName').getData()[0]; 
ds.setDocumentId(varRepeat.getDocument().getUniversalID().toString()); 
ds.setAction('editDocument'); 

Two other things are required for this to work:

  1. The ignoreRequestParams property of the data source must be set to true, or the embedded form will pick up the id of the parent document from the URL. If you want to be sure it’s set properly, include this line: ds.setIgnoreRequestParams(true);
  2. Set the button or link to partially-refresh the panel that includes the embedded form and data source

This is much easier to maintain that all of the steps that the other method required.

Advertisements

7 responses to “Dynamically Modify the Data Source on an Embedded Form in XPages”

  1. Steven Rieger says :

    Brad, I am struggling with a similar issue albeit much simpler.
    I have an xpage with a tabbed panel. Each tab is a custom control. When I go to access the xspdocument from one tab to the other the xspdocument is null
    Anyway I can chat with you to try and figure this out?

    • Brad Balassaitis says :

      If you use Skype, you can reach out to me there and we should be able to figure out a time that works.

      • riegesl says :

        Hi Brad,
        Thank you for the offer. I just figure out what my issue was. Embarrassingly simple but working none the less.

        Can I get your SkypeID for future reference?

        Thanks. And thank you for all that you do for the community!

  2. Michele says :

    Hello Brad,
    what if I have to create a response? is there any setParentId to use?
    Thanks!

  3. Michele says :

    Ah sorry, forget it, I found in the original code snipped.

  4. carlo mejia says :

    Thanks for the post, this really helped!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: