We have a possible upcoming project where one of the requirements is to allow users to define data-entry forms with an arbitrary number of fields, and specify the data-type and UI control for each field, without using Designer or doing any programming.
I have attempted to produce a basic proof-of-concept as follows, which doesn't work:
- Three custom controls, each containing an Edit Box with a different display type: Date/Time, Number, and Text. Each custom control also has a string property for specifying the field name to bind to.
- An xpage with a document data source associated with a form that has no fields.
- The xpage's beforePageLoad event creates two arrays in viewScope from multi-value fields in another document. One array contains field names; the other contains data-types specified as "d" for date/time, "n" for number, and "t" for text
- A repeat control is bound to the array of field names, and specifies an index variable.
- The repeat control contains all three custom controls, with the rendered property computed depending on the data-type for the current index.
Here is the SSJS in beforePageLoad:
var cfgDoc=database.getDocumentByID('2536'); //hard-coded noteId for testing
viewScope.xpcNames=cfgDoc.getItemValue('FieldNames').toArray();
viewScope.xpcTypes=cfgDoc.getItemValue('FieldTypes').toArray();
Here is the XML source for the repeat control:
<xp:repeat id="repeat1" rows="#{javascript:viewScope.xpcNames.length}"
value="#{javascript:viewScope.xpcNames}" indexVar="xpcRow">
<xc:xcCustomText>
<xc:this.fieldName><![CDATA[#{javascript:viewScope.xpcNames[xpcRow]}]]></xc:this.fieldName>
<xc:this.rendered><![CDATA[#{javascript:viewScope.xpcTypes[xpcRow]=='t'}]]></xc:this.rendered>
</xc:xcCustomText>
<xc:xcCustomNumber>
<xc:this.fieldName><![CDATA[#{javascript:viewScope.xpcNames[xpcRow]}]]></xc:this.fieldName>
<xc:this.rendered><![CDATA[#{javascript:viewScope.xpcTypes[xpcRow]=='n'}]]></xc:this.rendered>
</xc:xcCustomNumber>
<xc:xcCustomDT>
<xc:this.fieldName><![CDATA[#{javascript:viewScope.xpcNames[xpcRow]}]]></xc:this.fieldName>
<xc:this.rendered><![CDATA[#{javascript:viewScope.xpcTypes[xpcRow]=='d'}]]></xc:this.rendered>
</xc:xcCustomDT>
<br />
</xp:repeat>
Here is the XML source for the Edit Box in one of the custom controls:
<xp:inputText id="inputText1" value="${javascript:'#{currentDocument.'+compositeData.fieldName+'}';}">
</xp:inputText>
When I open the xpage in a browser, the result is this error message:
Error while executing JavaScript computed expression
Script interpreter error, line=1, col=11: [ReferenceError] 'xpcRow' not found
JavaScript code
1: viewScope.xpcNames[xpcRow]
This seems to be caused by the value binding in the Exit Box being computed on page load.
I can remove the error by changing the binding to computed dynamically, but then the xpage just shows text in place of the fields.
Does anyone know how I might get this working?