When developing an XPages Custom Control you may encounter the issue:
Error while executing JavaScript action expression
'compositeData' not found
If your custom control contains only a single control that is one of these tags:
- xp:viewColumn (View Column),
- xp:column (Column),
- xp:eventHandler (Event Handler),
- xp:selectItem (Select Item),
- xp:selectItems(Select Items)
then the compositeData is not available in "Compute Dynamically" bindings,
only in "Compute on Page Load" bindings.
Normally when a custom control is inserted into an XPage, it leaves a panel-like control
in the control tree, the UIIncludeComposite. That panel provides functionality:
- it publishes the compositeData to be available in compute dynamically bindings
- it publishes any data sources that were defined on the root of the custom control page,
and handles the other data-related properties (readonly, acl etc)
- it provides a clientId naming scope.
So if you have a custom control containing
and an outer page containing:
<xp:myCustom>
<xp:myCustom>
it ensures the 2 divs have different ids in the HTML source:
<div id="view:_id1:_id2:div1"></div>
<div id="view:_id1:_id3:div1"></div>
(the first custom control panel is _id2, and the 2nd custom control panel is _id3)
- etc. It provides all of the non-load-time custom control behavior.
The controls listed above depend on their parent container tag,
and do not work a panel is inserted in the tree between that control and their parent.
For example, for xp:column if you have
<xp:dataTable>
<xp:panel>
<xp:column>
</xp:panel>
<xp:dataTable>
then the dataTable does not find the column in its direct children,
so the column would not be output as part of the dataTable.
Hence when you create a custom control that only contains one of the tags above,
the panel will be automatically removed after the contents are loaded,
so the compositeData will not be available during dynamic bindings.
If you do want the panel to be removed, then the workaround for the "compositeData not found"
error is to use a load-time binding (in the JavaScript editor, choose "Compute on Page Load").
If you do not want the panel to be removed, you can either
add some content to the custom control page (like a <xp:br/> or a <xp:text value=" "/>),
or you can programmatically prevent the autoRemove, by adding this code to the custom control:
<xp:this.beforePageLoad><![CDATA[#{javascript:
this.setAutoRemove(false);
}]]></xp:this.beforePageLoad>
There was also a reported issue where the "compositeData not found" problem occurred
when evaluating Type Ahead suggestions list.
The solution there is to change:
<xp:typeAhead mode="partial" minChars="1" ignoreCase="true">
to
<xp:typeAhead mode="full" minChars="1" ignoreCase="true">
In releases 8.5.0, 8.5.1, the difference between typeAhead partial and typeAhead full was that
Type Ahead full would process the entire control tree server-side, so that the data (and compositeData)
would be available when computing the typeAhead suggestions.
Type Ahead partial would jump straight to the typeAhead control, so that
only value typed in to the edit box was available - the rest of the submitted form data
and the data sources would not be available.
That has been changed in 8.5.2, so that Type Ahead partial will have access
to the data sources in the page (and compositeData), though it still will not submit
nor process other values the user may have typed into other fields in the web browser.