wissel.net

Usability - Productivity - Business - The web - Singapore & Twins

Document dependent inline forms


In Notes client applications we are used to opening any document from a view and get it redered with the form specified in the Form (or the view's form formula). XPages behaves in a similar fashion when using the view control. However both approached open a new page (a tab in the Notes client, replaceing the current window in a browser).
Modern applications however expect a Single page application behavior, where only parts of the screen are replaced with new information. The XPages Extension library makes this easy, by providing the InPlace Form custom control.
Looking at the source code of the example page, it looks easy enough. However a real life application needs a few more considerations:
  • I want to open a (different) form depending on the current document
  • That form needs to be stored in its own control, so it can be reused
  • It is OK to enumerate the possible forms in the page (not fully flexible)
  • When saving an edit the form needs to disappear
With the help of the devine Maire Kehoe, this is the solution I came up with:

<xp:eventHandler event="onclick"
    submit="true" refreshMode="partial"
    refreshId="dynamicCell">
 <xp:this.action><![CDATA[#{javascript:var formId = getSubform(aViewEntry);
          getComponent(formId).toggle();}]]>
 </xp:this.action>
</xp:eventHandler>

The code above is the event handler that goes into the link or button that triggers the edit action. In my case inside a repeat based on a view. The code to find the form is simple.

function getSubform(ve:NotesXspViewEntry) {
 // Put real logic here, like looking at the form
 // var form = ve.getDocument().getItemValueString("Form");
 // return "inPlace"+form;
 var fruit = ve.getColumnValue("Subject");
 var subform = ("Durian"===fruit) ? "inPlaceDurian" : "inPlaceFruit";
 return subform;
}

The snippet of code that determines what control to load lists all possible forms. To make this useful you should stick to the inPlace and inLine prefixes. The former lives only inside your page, but the later would be a distinct control. Also note, that I hand over the documentUniqueId, so my control can load the appropriate document.

<xp:td id="dynamicCell" colspan="3">
 <xe:inPlaceForm id="inPlaceFruit" partialEvents="true">
  <xc:inlineFruit fruitID="#{javascript:fruitList.getUniversalID();}">
  </xc:inlineFruit>
 </xe:inPlaceForm>
 <xe:inPlaceForm id="inPlaceDurian" partialEvents="true">
  <xc:inlineDurian fruitID="#{javascript:fruitList.getUniversalID();}">
  </xc:inlineDurian>
 </xe:inPlaceForm>
</xp:td>

The last 2 pieces in the puzzle are the save button and the mechanism that hides the inline form again. The button is simple:

<xp:button value="Save" id="button1">
 <xp:eventHandler event="onclick" submit="true"
  refreshMode="partial" refreshId="oneRecord">
  <xp:this.action><![CDATA[#{javascript:saveAndClose(document1, this);}]]></xp:this.action>
 </xp:eventHandler>
</xp:button>

While the JS code is a little trickier. The control doesn't "know" that it is in a inline edit form, nor does it know the name, so a "getComponent" would be a wild guess. It might work for convention over code, but I opted for a different approach: travel up the component tree until I hit a com.ibm.xsp.extlib.component.dynamiccontent.UIInPlaceForm and if I find it, toggle it:

function saveAndClose(doc:NotesXspDocument, uiControl) {
 doc.save();
 var parent = uiControl.getParent();
 while (parent != null && parent.getClass().getName() !=
                    "com.ibm.xsp.extlib.component.dynamiccontent.UIInPlaceForm") {
  parent = parent.getParent();
 }
 if (parent != null) {
  parent.toggle();
 }
}

There are a few variations one could think of: provide the control name as component parameter, provide another parameter for the (partial update - which would need to be the repeat control) and general layout considerations. From an interaction view, the inline forms beat any dialog, because users are not limited to have only one form open at a time.
As usual YMMV

Posted by on 02 January 2015 | Comments (0) | categories: XPages

Comments

  1. No comments yet, be the first to comment