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>