Re-control dynamic linking

In the purchase order module, we need to ask certain questions depending on the source selection method, type of tender and the total cost of the software. These issues are likely to change over time and between different database instances.

So, I have a view containing questions, so that I can dynamically add questions to my XPage without changing the code. The answer to each question will be saved in the field. Thus, the document containing this question has a FieldName field that is used to provide the name of the field to be used. Unfortunately, I was not lucky to associate these dynamic fields with the document.

<xp:this.data> <xp:dominoView var="competitionQuestionView" viewName="CompetitionQuestions"> </xp:dominoView> </xp:this.data> <xp:repeat id="repeat2" rows="30" var="rowData" style="width:700px" value="#{competitionQuestionView}"> <xp:label id="label1"> <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("Question");}]]></xp:this.value> </xp:label> <xp:inputText id="inputText1"> <xp:this.rendered><![CDATA[#{javascript:rowData.getColumnValue("FieldType") == "Text Box"; }]]></xp:this.rendered> <xp:this.value><![CDATA[#{javascript:poDoc[rowData.getColumnValue ("FieldName")];}]]></xp:this.value> </xp:inputText> </xp:repeat> 

I tried various ways to do this, including creating a custom dynamicInputText element to pass in the field name, but with no luck. The closest I got is when I used this:

 <xp:this.value> <![CDATA[#{javascript:tmp = rowData.getColumnValue ("FieldName");'#{poDoc.'+tmp+'}';}]]> </xp:this.value> 

This gave me something like # {poDoc.justification}, which is exactly what I wanted to pass to the "binding", but in the end it was displayed as a text value.

I tried using $ to calculate the load value, but I assume that it did not work, because my (and rowData) view is not available at loading. Ultimately, this will create a problem when I want to use partial updates because of updates by criteria, the fields of which I want to display in any case.

Some answers to other questions looked promising, but there was no code, so I could not understand.

+4
source share
1 answer

Behind the scenes, all data sources use the getValue and setValue to (respectively) read and write data. For a Domino document data source, the expression #{currentDocument.fieldName} converted at run time to currentDocument.getValue('fieldName') or currentDocument.setValue('fieldName', postedValue) , depending on whether the current operation is reading or writing .

If you set the value attribute on another editable component to bind the SSJS value, it will not be able to perform this automatic translation ... therefore, it simply treats each operation as read.

In other words, for reading / writing to work, it must be a β€œprefix” expression.

There are several ways to handle this, but the easiest way is to use a data context to map an SSJS expression to a single variable. Data contexts can be attached to the root of the view or to the panel, so in your example you want to wrap the contents of the replay in the panel:

 <xp:repeat id="repeat2" rows="30" var="rowData" style="width:700px" value="#{competitionQuestionView}"> <xp:panel> <xp:this.dataContexts> <xp:dataContext var="fieldName"> <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue ("FieldName");}]]></xp:this.value> </xp:dataContext> </xp:this.dataContexts> <xp:label id="label1"> <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("Question");}]]> </xp:this.value> </xp:label> <xp:inputText id="inputText1" value="#{poDoc[fieldName]}"> <xp:this.rendered><![CDATA[#{javascript:rowData.getColumnValue("FieldType") == "Text Box"; }]]></xp:this.rendered> </xp:inputText> </xp:panel> </xp:repeat> 

So, for each repeat member, fieldName becomes the column value for this row. Then the array syntax is used in the value attribute of the input component (instead of the usual dot syntax), since we want to use a variable to specify the field name instead of hardcoding name.

In theory, however, you should be able to completely skip the data context and simply set the expression value for the field to the following:

#{poDoc[rowData.FieldName]}

In the context of an EL detector, by default ("prefixless") rowData.FieldName should return exactly the same value that rowData.getColumnValue("FieldName") returns in the context of an SSJS expression.

Finally, I would recommend reading this expression language tutorial to familiarize yourself with all the things you can do mostly EL without resorting to SSJS.

+10
source

All Articles