In this page we provide samples to have a selection widget with 3 levels by contributing a "template widget" in Studio. Each sample code below is the sample for one widget that has a different behavior (described before the code).
To create and use a new widget:
Copy-paste the sample of your choice in a file that you call, for instance, "3_level_select_widget.xhtml".
Of course you can modify the samples below to add other levels, or other behaviors. You just need to be familiar with facelets and JSF.
- Upload this file in the Resources > Widgets section. The widget is created. You can now use it on layouts and forms.
- In the layout of the document type where you want to use the widget, drag and drop the Template widget from the Advanced Widgets category on the right.
- Edit the properties of the widget.
Here are the properties specific to custom widgets that you need to fill in.
- Template: choose the XHTML file you have just uploaded.
- Fields: add one field and put the XPath of the field you want to update. For instance, "dc:coverage".
- Custom properties configuration: in our sample, you can (should) add those three properties labels and put the value you need:
- localize
- required
- directoryName (should be the name of the vocabulary that holds the values that are displayed).
Widget Samples
Mono-Select 3-Level Widget
Sample example on 3 levels with widget property directoryName
filled with the directory name (mono select):
<f:subview
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:nxu="http://nuxeo.org/nxweb/util"
xmlns:nxdir="http://nuxeo.org/nxdirectory"
xmlns:nxl="http://nuxeo.org/nxforms/layout"
xmlns:nxp="http://nuxeo.org/nxweb/pdf"
id="#{widget.id}">
<c:if test="#{nxl:isLikeViewMode(widget.mode)}">
<nxdir:chainSelect id="#{widget.id}_viewselect" size="3" value="#{field}"
displayValueOnly="true" defaultRootKey="">
<nxdir:chainSelectListbox index="0" size="0" directoryName="#{widget.properties['directoryName']}"
localize="true" id="#{widget.id}_parent" displayObsoleteEntries="true" />
<nxdir:chainSelectListbox index="1" size="0" directoryName="#{widget.properties['directoryName']}"
localize="true" id="#{widget.id}_parent2" displayObsoleteEntries="true" />
<nxdir:chainSelectListbox index="2" size="0" directoryName="#{widget.properties['directoryName']}"
localize="true" id="#{widget.id}_child" displayObsoleteEntries="true" />
<nxdir:chainSelectStatus display="value" id="#{widget.id}_status" />
</nxdir:chainSelect>
</c:if>
<c:if test="#{widget.mode == 'edit'}">
<nxdir:chainSelect size="3" value="#{field}"
id="#{widget.id}_editselect" multiSelect="false"
multiParentSelect="false"
allowBranchSelection="#{widgetProperty_allowBranchSelection}"
defaultRootKey="" required="#{widgetProperty_required}">
<a4j:region id="#{widget.id}_region">
<nxdir:chainSelectListbox index="0" size="1"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent" ordering="label">
<f:ajax event="change"
render="#{widget.id}_parent2 #{widget.id}_child #{widget.id}_message"
execute="@this" />
</nxdir:chainSelectListbox>
<nxdir:chainSelectListbox index="1" size="1"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent2" ordering="label">
<a4j:ajax event="change"
render="#{widget.id}_child #{widget.id}_message"
execute="@region" />
</nxdir:chainSelectListbox>
</a4j:region>
<nxdir:chainSelectListbox size="1" index="2"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_child" ordering="label" />
</nxdir:chainSelect>
<h:message styleClass="errorMessage" for="#{widget.id}_editselect"
id="#{widget.id}_message" />
</c:if>
</f:subview>
Multi-Select 3-Level Widget
Sample example on 3 levels with widget property directoryName
filled with the directory name (multi select):
<f:subview
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:nxu="http://nuxeo.org/nxweb/util"
xmlns:nxdir="http://nuxeo.org/nxdirectory"
xmlns:nxl="http://nuxeo.org/nxforms/layout"
xmlns:nxp="http://nuxeo.org/nxweb/pdf"
id="#{widget.id}">
<c:if test="#{nxl:isLikeViewMode(widget.mode)}">
<nxdir:chainSelect id="#{widget.id}_viewselect" size="3"
value="#{field}" displayValueOnly="true" multiSelect="true"
defaultRootKey="">
<nxdir:chainSelectListbox index="0" size="4"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent" />
<nxdir:chainSelectListbox size="4"
directoryName="#{widget.properties['directoryName']}" index="1"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent2" />
<nxdir:chainSelectListbox size="4"
directoryName="#{widget.properties['directoryName']}" index="2"
localize="#{widget.properties['localize']}"
id="#{widget.id}_child" />
<nxdir:chainSelectStatus display="value" id="#{widget.id}_status" />
</nxdir:chainSelect>
</c:if>
<c:if test="#{widget.mode == 'edit'}">
<a4j:region id="#{widget.id}_region" renderRegionOnly="true">
<nxdir:chainSelect size="3" value="#{field}"
id="#{widget.id}_editselect" multiSelect="true"
multiParentSelect="true"
allowBranchSelection="#{widgetProperty_allowBranchSelection}"
defaultRootKey="" required="#{widgetProperty_required}">
<nxdir:chainSelectListbox index="0" size="4"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent" ordering="label">
<a4j:ajax event="change"
render="#{widget.id}_parent2 #{widget.id}_child #{widget.id}_message"
execute="@this" />
</nxdir:chainSelectListbox>
<nxdir:chainSelectListbox index="1" size="4"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent2" ordering="label">
<a4j:ajax event="change"
render="#{widget.id}_child #{widget.id}_message"
immediate="true" />
</nxdir:chainSelectListbox>
<nxdir:chainSelectListbox size="4" index="2"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_child" ordering="label" />
<a4j:commandButton value="#{messages['command.add']}"
styleClass="button" immediate="true"
actionListener="#{chainSelectActions.add}"
render="#{widget.id}_status #{widget.id}_message"
id="#{widget.id}_add" />
<br />
<nxdir:chainSelectStatus display="value"
entryCssStyle="background-color: #DDEEFF"
label="#{messages['label.chainSelect.selection']}"
id="#{widget.id}_status">
<f:facet name="removeButton">
<a4j:commandButton
actionListener="#{chainSelectActions.delete}"
execute="@this" render="#{widget.id}_status"
image="/icons/toggle_minus.png"
id="#{widget.id}_delete" />
</f:facet>
</nxdir:chainSelectStatus>
</nxdir:chainSelect>
</a4j:region>
<h:message styleClass="errorMessage" for="#{widget.id}_editselect"
id="#{widget.id}_message" />
</c:if>
</f:subview>
Complete Examples with CSV (Plain) and PDF Rendering
Mono-Select Widget
<f:subview
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:nxu="http://nuxeo.org/nxweb/util"
xmlns:nxdir="http://nuxeo.org/nxdirectory"
xmlns:nxl="http://nuxeo.org/nxforms/layout"
xmlns:nxp="http://nuxeo.org/nxweb/pdf"
id="#{widget.id}">
<c:if test="#{nxl:isLikePlainMode(widget.mode)}">
<f:subview rendered="#{not empty field}"><nxdir:directoryEntryOutput
directoryName="#{widget.properties['directoryName']}"
value="#{fn:split(field, '/')[0]}"
localize="#{widget.properties['localize']}" />/<nxdir:directoryEntryOutput
directoryName="#{widget.properties['directoryName']}"
value="#{fn:split(field, '/')[1]}"
localize="#{widget.properties['localize']}" />/<nxdir:directoryEntryOutput
directoryName="#{widget.properties['directoryName']}"
value="#{field}"
localize="#{widget.properties['localize']}"
keySeparator="/" />
</f:subview>
</c:if>
<c:if test="#{widget.mode == 'pdf'}">
<nxp:html>
<nxdir:chainSelect id="#{widget.id}_viewselect" size="3" value="#{field}"
displayValueOnly="true" defaultRootKey="">
<nxdir:chainSelectListbox index="0" size="0" directoryName="#{widget.properties['directoryName']}"
localize="true" id="#{widget.id}_parent" displayObsoleteEntries="true" />
<nxdir:chainSelectListbox index="1" size="0" directoryName="#{widget.properties['directoryName']}"
localize="true" id="#{widget.id}_parent2" displayObsoleteEntries="true" />
<nxdir:chainSelectListbox index="2" size="0" directoryName="#{widget.properties['directoryName']}"
localize="true" id="#{widget.id}_child" displayObsoleteEntries="true" />
<nxdir:chainSelectStatus display="value" id="#{widget.id}_status" />
</nxdir:chainSelect>
</nxp:html>
</c:if>
<c:if test="#{nxl:isLikeViewMode(widget.mode)}">
<nxdir:chainSelect id="#{widget.id}_viewselect" size="3" value="#{field}"
displayValueOnly="true" defaultRootKey="">
<nxdir:chainSelectListbox index="0" size="0" directoryName="#{widget.properties['directoryName']}"
localize="true" id="#{widget.id}_parent" displayObsoleteEntries="true" />
<nxdir:chainSelectListbox index="1" size="0" directoryName="#{widget.properties['directoryName']}"
localize="true" id="#{widget.id}_parent2" displayObsoleteEntries="true" />
<nxdir:chainSelectListbox index="2" size="0" directoryName="#{widget.properties['directoryName']}"
localize="true" id="#{widget.id}_child" displayObsoleteEntries="true" />
<nxdir:chainSelectStatus display="value" id="#{widget.id}_status" />
</nxdir:chainSelect>
</c:if>
<c:if test="#{widget.mode == 'edit'}">
<nxdir:chainSelect size="3" value="#{field}"
id="#{widget.id}_editselect" multiSelect="false"
multiParentSelect="false"
allowBranchSelection="#{widgetProperty_allowBranchSelection}"
defaultRootKey="" required="#{widgetProperty_required}">
<a4j:region id="#{widget.id}_region">
<nxdir:chainSelectListbox index="0" size="1"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent" ordering="label">
<f:ajax event="change"
render="#{widget.id}_parent2 #{widget.id}_child #{widget.id}_message"
execute="@this" />
</nxdir:chainSelectListbox>
<nxdir:chainSelectListbox index="1" size="1"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent2" ordering="label">
<a4j:ajax event="change"
render="#{widget.id}_child #{widget.id}_message"
execute="@region" />
</nxdir:chainSelectListbox>
</a4j:region>
<nxdir:chainSelectListbox size="1" index="2"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_child" ordering="label" />
</nxdir:chainSelect>
<h:message styleClass="errorMessage" for="#{widget.id}_editselect"
id="#{widget.id}_message" />
</c:if>
</f:subview>
Multi-Select Widget
<f:subview
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:nxu="http://nuxeo.org/nxweb/util"
xmlns:nxdir="http://nuxeo.org/nxdirectory"
xmlns:nxl="http://nuxeo.org/nxforms/layout"
xmlns:nxp="http://nuxeo.org/nxweb/pdf"
id="#{widget.id}">
<c:if test="#{nxl:isLikePlainMode(widget.mode)}"><nxu:inputList
value="#{field}" model="chainModel"><nxdir:directoryEntryOutput
directoryName="#{widget.properties['directoryName']}"
value="#{fn:split(chainModel.rowData, '/')[0]}"
localize="#{widget.properties['localize']}" />/<nxdir:directoryEntryOutput
directoryName="#{widget.properties['directoryName']}"
value="#{fn:split(chainModel.rowData, '/')[1]}"
localize="#{widget.properties['localize']}" />/<nxdir:directoryEntryOutput
directoryName="#{widget.properties['directoryName']}"
value="#{chainModel.rowData}"
localize="#{widget.properties['localize']}"
keySeparator="/" /><h:outputText
rendered="#{chainModel.rowIndex != chainModel.rowCount -1}" value=", " /></nxu:inputList>
</c:if>
<c:if test="#{widget.mode == 'pdf'}">
<nxp:html>
<nxdir:chainSelect id="#{widget.id}_viewselect" size="3"
value="#{field}" displayValueOnly="true" multiSelect="true"
defaultRootKey="">
<nxdir:chainSelectListbox index="0" size="4"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent" />
<nxdir:chainSelectListbox size="4"
directoryName="#{widget.properties['directoryName']}" index="1"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent2" />
<nxdir:chainSelectListbox size="4"
directoryName="#{widget.properties['directoryName']}" index="2"
localize="#{widget.properties['localize']}"
id="#{widget.id}_child" />
<nxdir:chainSelectStatus display="value" id="#{widget.id}_status" />
</nxdir:chainSelect>
</nxp:html>
</c:if>
<c:if test="#{nxl:isLikeViewMode(widget.mode)}">
<nxdir:chainSelect id="#{widget.id}_viewselect" size="3"
value="#{field}" displayValueOnly="true" multiSelect="true"
defaultRootKey="">
<nxdir:chainSelectListbox index="0" size="4"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent" />
<nxdir:chainSelectListbox size="4"
directoryName="#{widget.properties['directoryName']}" index="1"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent2" />
<nxdir:chainSelectListbox size="4"
directoryName="#{widget.properties['directoryName']}" index="2"
localize="#{widget.properties['localize']}"
id="#{widget.id}_child" />
<nxdir:chainSelectStatus display="value" id="#{widget.id}_status" />
</nxdir:chainSelect>
</c:if>
<c:if test="#{widget.mode == 'edit'}">
<a4j:region id="#{widget.id}_region" renderRegionOnly="true">
<nxdir:chainSelect size="3" value="#{field}"
id="#{widget.id}_editselect" multiSelect="true"
multiParentSelect="true"
allowBranchSelection="#{widgetProperty_allowBranchSelection}"
defaultRootKey="" required="#{widgetProperty_required}">
<nxdir:chainSelectListbox index="0" size="4"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent" ordering="label">
<a4j:ajax event="change"
render="#{widget.id}_parent2 #{widget.id}_child #{widget.id}_message"
execute="@this" />
</nxdir:chainSelectListbox>
<nxdir:chainSelectListbox index="1" size="4"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_parent2" ordering="label">
<a4j:ajax event="change"
render="#{widget.id}_child #{widget.id}_message"
immediate="true" />
</nxdir:chainSelectListbox>
<nxdir:chainSelectListbox size="4" index="2"
directoryName="#{widget.properties['directoryName']}"
localize="#{widget.properties['localize']}"
id="#{widget.id}_child" ordering="label" />
<a4j:commandButton value="#{messages['command.add']}"
styleClass="button" immediate="true"
actionListener="#{chainSelectActions.add}"
render="#{widget.id}_status #{widget.id}_message"
id="#{widget.id}_add" />
<br />
<nxdir:chainSelectStatus display="value"
entryCssStyle="backgroundcolor: #DDEEFF"
label="#{messages['label.chainSelect.selection']}"
id="#{widget.id}_status">
<f:facet name="removeButton">
<a4j:commandButton
actionListener="#{chainSelectActions.delete}"
execute="@this" render="#{widget.id}_status"
image="/icons/toggle_minus.png"
id="#{widget.id}_delete" />
</f:facet>
</nxdir:chainSelectStatus>
</nxdir:chainSelect>
</a4j:region>
<h:message styleClass="errorMessage" for="#{widget.id}_editselect"
id="#{widget.id}_message" />
</c:if>
</f:subview>