<#include "/org/alfresco/components/form/controls/common/utils.inc.ftl" /> <#include "/org/alfresco/components/form/controls/common/cascadingDropdownUtils.inc.ftl" /> <!– current value –> <#assign fieldValue=field.value> <!– handle default value for empty current value –> <#if fieldValue?string == "" && field.control.params.defaultValueContextProperty??> <#if context.properties[field.control.params.defaultValueContextProperty]??> <#assign fieldValue = context.properties[field.control.params.defaultValueContextProperty]> <#elseif args[field.control.params.defaultValueContextProperty]??> <#assign fieldValue = args[field.control.params.defaultValueContextProperty]> </#if> </#if> <div class="form-field"> <!– readonly mode. No action required, display the composed value as is –> <#if form.mode == "view"> <div class="viewmode-field"> <#if field.mandatory && !(fieldValue?is_number) && fieldValue?string == ""> <span class="incomplete-warning"><img src="${url.context}/res/components/form/images/warning-16.png" title="${msg("form.field.incomplete" )}" /><span> </#if> <span class="viewmode-label">${field.label?html}:</span> <#if fieldValue?string == ""> <#assign valueToShow=msg("form.control.novalue" )> <#else> <#assign valueToShow=fieldValue> <#if field.control.params.options?? && field.control.params.options != ""> <#list field.control.params.options?split(optionSeparator) as nameValue> <#if nameValue?index_of(labelSeparator) == -1> <#if nameValue == fieldValue?string || (fieldValue?is_number && fieldValue?c == nameValue)> <#assign valueToShow=nameValue> <#break> </#if> <#else> <#assign choice=nameValue?split(labelSeparator)> <#if choice[0] == fieldValue?string || (fieldValue?is_number && fieldValue?c == choice[0])> <#assign valueToShow=msgValue(choice[1])> <#break> </#if> </#if> </#list> </#if> </#if> <span class="viewmode-value">${valueToShow?html}</span> </div> <#else> <!– Editable mode. –> <!– let's keep a single label for both fields –> <label for="${fieldHtmlId}">${field.label?html}:<#if field.mandatory><span class="mandatory-indicator">${msg("form.required.fields.marker" )}</span></#if></label> <#if field.control.params.options?? && field.control.params.options != ""> <!– first select for the parent value –> <select id="parent-${fieldHtmlId}" tabindex="0" <#if field.description??>title="${field.description}"</#if> <#if field.control.params.size??>size="${field.control.params.size}"</#if> <#if field.control.params.styleClass??>class="${field.control.params.styleClass}"</#if> <#if field.control.params.style??>style="${field.control.params.style}"</#if> <#if field.disabled && !(field.control.params.forceEditable?? && field.control.params.forceEditable == "true" )>disabled="true"</#if>> </select> <!– second select for the child value –> <select id="child-${fieldHtmlId}" name="${field.name}" tabindex="0" <#if field.description??>title="${field.description}"</#if> <#if field.control.params.size??>size="${field.control.params.size}"</#if> <#if field.control.params.styleClass??>class="${field.control.params.styleClass}"</#if> <#if field.control.params.style??>style="${field.control.params.style}"</#if> <#if field.disabled && !(field.control.params.forceEditable?? && field.control.params.forceEditable == "true" )>disabled="true"</#if>> </select> <!– hidden field containing the final value (e.g. the one sent to the server and stored in database) –> <input type="hidden" id="${fieldHtmlId}" name="${field.name}" /> <@formLib.renderFieldHelp field=field /> <#else> <div id="${fieldHtmlId}" class="missing-options">${msg("form.control.selectone.missing-options" )}</div> </#if> </#if> </div> <!– IMPORTANT: this script must execute after the fields are created –> <script type="text/javascript">//<![CDATA[ setTimeout(function(){populateSelects("${field.control.params.options}", "${fieldValue}", "parent-${fieldHtmlId}", "child-${fieldHtmlId}", "${fieldHtmlId}");}, 1000); //]]></script>
<!– defines how the option list elements are separated when passed to the client –> <#if field.control.params.optionSeparator??> <#assign optionSeparator=field.control.params.optionSeparator> <#else> <#assign optionSeparator=","> </#if> <!– defines how the label list elements are separated when passed to the client –> <#if field.control.params.labelSeparator??> <#assign labelSeparator=field.control.params.labelSeparator> <#else> <#assign labelSeparator="|"> </#if> <script type="text/javascript">//<![CDATA[ <!– defines how the option list elements are separated when passed to the client –> <#if field.control.params.optionSeparator??> <#assign optionSeparator=field.control.params.optionSeparator> <#else> <#assign optionSeparator=","> </#if> <!– defines how the label list elements are separated when passed to the client –> <#if field.control.params.labelSeparator??> <#assign labelSeparator=field.control.params.labelSeparator> <#else> <#assign labelSeparator="|"> </#if> <script type="text/javascript">//<![CDATA[ /* string used to separate the parent from the child */ var OPTION_SEPARATOR = "/"; /** * Functions used to split and synchronize the data between the 2 lists. **/ /** * @param stringValues: string containing the available values for the given field * @returns a javascript object containing those values **/ function getValsArrayFromString(stringValues) { //array with the options var valsArray = stringValues.split("${optionSeparator}"); //remove the labels for (var i = 0; i < valsArray.length; i++) { if(valsArray.indexOf("${labelSeparator}") != -1) { valsArray = valsArray.substr(0,valsArray.indexOf("${labelSeparator}")); } } return valsArray; } /** * Extracts the parent value from the full value of the option **/ function getParentValue(fullValue) { return fullValue.substr(0,fullValue.indexOf(OPTION_SEPARATOR)); } /** * Extracts the child value from the full value of the option **/ function getChildValue(fullValue) { return fullValue.substr(fullValue.indexOf(OPTION_SEPARATOR) + 1); } /** * Parent value have been changed. * Reset the current total value, child value and updates the available child values **/ function onChangeParentValue(valsArray, parentId, childId, totalId) { var parentValue = document.getElementById(parentId).value; var childSelect = document.getElementById(childId); /* empty the child select */ while(childSelect.firstChild) { childSelect.removeChild(childSelect.firstChild); } /* fill the child select with the new values */ for (var i = 0; i < valsArray.length; i++) { if ( getParentValue(valsArray) == parentValue) { var childValue = getChildValue(valsArray); var childOption = document.createElement("option"); childOption.value = childValue; childOption.innerHTML = childValue; childSelect.appendChild(childOption); } } } /** * Child value have been changed. * Update the total value **/ function onChangeChildValue(parentId, childId, totalId) { var parentValue = document.getElementById(parentId).value; var childValue = document.getElementById(childId).value; document.getElementById(totalId).value = parentValue + OPTION_SEPARATOR + childValue; } /** * Initial filling of the parent values available * TODO: handle default value **/ function populateSelects(stringValues, initialValue, parentId, childId, totalId) { /* get an array from the string values */ var valsArray = getValsArrayFromString(stringValues); var parentSelect = document.getElementById(parentId); /* we only want to display each parent value once. This object keeps track of the already added ones */ var uniqueParentValues = {}; /* populate parent select */ for (var i = 0; i < valsArray.length; i++) { var realV = getParentValue(valsArray); if(!uniqueParentValues.hasOwnProperty(realV)) { uniqueParentValues[realV] = true; /* create new option for the parent select */ var parOption = document.createElement("option"); parOption.value = realV; parOption.innerHTML = realV; if(realV == getParentValue(initialValue)) { parOption.selected = "selected"; } parentSelect.appendChild(parOption); } } parentSelect.onchange = function(){onChangeParentValue(valsArray, parentId, childId, totalId);}; /* populate child select */ onChangeParentValue(valsArray, parentId, childId, totalId); /* sets the correct child value */ var childSelect = document.getElementById(childId); childSelect.value = getChildValue(initialValue); childSelect.onchange = function(){onChangeChildValue(parentId, childId, totalId);}; onChangeChildValue(parentId, childId, totalId); } //]]></script>
…Shall I call WebService from java script and get the JSON response and fill the dependent dropdown?
<?xml version="1.0" encoding="UTF-8"?> <!– Definition of new Model –> <model name="ccd:cascadingmodel" xmlns="http://www.alfresco.org/model/dictionary/1.0"> <!– Optional meta-data about the model –> <description>Cascading Model</description> <author>Cybage</author> <version>1.0</version> <!– Imports are required to allow references to definitions in other models –> <imports> <!– Import Alfresco Dictionary Definitions –> <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" /> <!– Import Alfresco Content Domain Model Definitions –> <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" /> <import uri="http://www.alfresco.org/model/system/1.0" prefix="sys" /> </imports> <!– Introduction of new namespaces defined by this model –> <namespaces> <namespace uri="http://www.cascading.com/model/content/1.0" prefix="ccd" /> </namespaces> <constraints> <constraint name="ccd:productList" type="com.mycomp.cascading.demo.ListOfValuesProductConstraint"> <parameter name="allowedValues"> <list> </list> </parameter> </constraint> <constraint name="ccd:trimList" type="com.mycomp.cascading.demo.ListOfValuesTrimConstraint"> <parameter name="allowedValues"> <list> </list> </parameter> </constraint> <constraint name="ccd:vehicleColorList" type="com.mycomp.cascading.demo.ListOfValuesVehicleColorConstraint"> <parameter name="allowedValues"> <list> </list> </parameter> </constraint> </constraints> <types> <!– Enterprise-wide generic document type –> <type name="ccd:doc"> <title>Cascading Document</title> <parent>cm:content</parent> </type> </types> <aspects> <aspect name="ccd:imageAsset"> <title>Cascading Aspect</title> <properties> <property name="ccd:producta"> <title>Product Name</title> <type>d:text</type> <constraints> <constraint ref="ccd:productList" /> </constraints> </property> <property name="ccd:trima"> <title>Trim</title> <type>d:text</type> <constraints> <constraint ref="ccd:trimList" /> </constraints> </property> <property name="ccd:vehicleColora"> <title>Vehicle Color</title> <type>d:text</type> <constraints> <constraint ref="ccd:vehicleColorList" /> </constraints> </property> </properties> </aspect> </aspects> </model>
package com.mycomp.cascading.demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import javax.faces.model.SelectItem; import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.generator.BaseComponentGenerator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class ListOfValuesProductConstraint extends SearchBasedListConstraint { private static Log logger = LogFactory.getLog(BaseComponentGenerator.class); private static final long serialVersionUID = 1; private Node node = null; public Node getNode() { return node; } public void setNode(Node node) { this.node = node; } private List<String> allowedLabels; public void setAllowedValues(List allowedValues) { } public void setCaseSensitive(boolean caseSensitive) { } public void initialize() { super.setCaseSensitive(false); this.loadDB(); } public List<String> getAllowedLabels() { return this.allowedLabels; } public void setAllowedLabels(List<String> allowedLabels) { this.allowedLabels = allowedLabels; } public List<SelectItem> getSelectItemList() { List<SelectItem> result = new ArrayList<SelectItem>(this .getAllowedValues().size()); for (int i = 0; i < this.getAllowedValues().size(); i++) { result.add(new SelectItem((Object) this.getAllowedValues().get(i), this.allowedLabels.get(i))); } return result; } protected void loadDB() { String driverName = "org.gjt.mm.mysql.Driver"; String serverName = "localhost"; String mydatabase = "cascading"; String username = "root"; String password = "root"; List<String> av = new ArrayList<String>(); List<String> al = new ArrayList<String>(); Connection connection = null; Statement stmt = null; ResultSet rs = null; try { Class.forName(driverName); String url = "jdbc:mysql://" + serverName + "/" + mydatabase; connection = DriverManager.getConnection(url, username, password); stmt = connection.createStatement(); rs = stmt.executeQuery("select distinct product from imageasset"); av.add("–Select–"); while (rs.next()) { av.add(rs.getString("product")); //al.add(rs.getString("label")); } } catch (Exception e) { } finally { try { if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (connection != null && !connection.isClosed()) connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } super.setAllowedValues(av); //this.setAllowedLabels(al); } }
<#include "/org/alfresco/components/form/controls/common/utils.inc.ftl" /> <script language="JavaScript" type="text/javascript"> function getProduct(frm,selectedValue) { var xmlhttp; if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } else { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function() { var ticket; if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { //var jsonString = xmlhttp.responseText; //var myFirstJSON = eval('(' + jsonString + ')'); var theSel = frm.prop_ccd_trima; theSel.disabled = false; removeAllOptions(theSel); //alert(selectedValue +" "+ myFirstJSON[0][0]); //insertOldSchool(theSel,myFirstJSON[0][0],myFirstJSON[0][0]); var resp = xmlhttp.responseText; var respArr = resp.split(','); for(var i=0;i<respArr.length;i++){ insertOldSchool(theSel,respArr[i],respArr[i]); } } }; xmlhttp.open("GET","http://jimitj/alfresco/service/demo/cascading?field=trim&key=product&value='+selectedValue ,true); xmlhttp.send(); } </script> <#if field.control.params.optionSeparator??> <#assign optionSeparator=field.control.params.optionSeparator> <#else> <#assign optionSeparator=","> </#if> <#if field.control.params.labelSeparator??> <#assign labelSeparator=field.control.params.labelSeparator> <#else> <#assign labelSeparator="|"> </#if> <div class="form-field"> <#if form.mode == "view"> <div class="viewmode-field"> <#if field.mandatory && !(field.value?is_number) && field.value?string == ""> <span class="incomplete-warning"><img src="${url.context}/res/components/form/images/warning-16.png" title="${msg("form.field.incomplete")}" /><span> </#if> <#if field.control.params.options?? && field.control.params.options != ""> <span class="viewmode-label">${field.label?html}:</span> <#if field.value?string == ""> <#assign valueToShow=msg("form.control.novalue")> <#else> <#assign valueToShow=field.value> <#list field.control.params.options?split(optionSeparator) as nameValue> <#if nameValue?index_of(labelSeparator) == -1> <#if nameValue == field.value?string || (field.value?is_number && field.value?c == nameValue)> <#assign valueToShow=nameValue> <#break> </#if> <#else> <#assign choice=nameValue?split(labelSeparator)> <#if choice[0] == field.value?string || (field.value?is_number && field.value?c == choice[0])> <#assign valueToShow=msgValue(choice[1])> <#break> </#if> </#if> </#list> </#if> <span class="viewmode-value">${valueToShow?html}</span> </#if> </div> <#else> <#if field.control.params.options?? && field.control.params.options != ""> <label for="${fieldHtmlId}">${field.label?html}:<#if field.mandatory><span class="mandatory-indicator">${msg("form.required.fields.marker")}</span></#if></label> <select id="${fieldHtmlId}" name="${field.name}" tabindex="0" ONCHANGE="getProduct(this.form,this.options[this.selectedIndex].value);" <#if field.description??>title="${field.description}"</#if> <#if field.control.params.size??>size="${field.control.params.size}"</#if> <#if field.control.params.styleClass??>class="${field.control.params.styleClass}"</#if> <#if field.control.params.style??>style="${field.control.params.style}"</#if> <#if field.disabled && !(field.control.params.forceEditable?? && field.control.params.forceEditable == "true")>disabled="true"</#if>> <#list field.control.params.options?split(optionSeparator) as nameValue> <#if nameValue?index_of(labelSeparator) == -1> <option value="${nameValue?html}"<#if nameValue == field.value?string || (field.value?is_number && field.value?c == nameValue)> selected="selected"</#if>>${nameValue?html}</option> <#else> <#assign choice=nameValue?split(labelSeparator)> <option value="${choice[0]?html}"<#if choice[0] == field.value?string || (field.value?is_number && field.value?c == choice[0])> selected="selected"</#if>>${msgValue(choice[1])?html}</option> </#if> </#list> </select> <@formLib.renderFieldHelp field=field /> <#else> </#if> </#if> </div>
config evaluator="node-type" condition="cm:content"> <forms> <!– Default form configuration used on the document details and edit metadata pages –> <form> <field-visibility> <show id="ccd:producta"/> <show id="ccd:trima"/> <show id="ccd:vehicleColora"/> </field-visibility> <appearance> <field id="ccd:producta" label="Product"> <control template="controls/selectoneCustom.ftl"> </control> </field> <field id="ccd:trima" label="Trim"> <control template="controls/selectoneDepenedentDisable.ftl"> </control> </field> <field id="ccd:vehicleColora" label="Vehicle Color"> <control template="controls/selectoneDisable.ftl"> </control> </field> </appearance> </form> <!– Document Library pop-up Edit Metadata form –> <form id="doclib-simple-metadata"> <field-visibility> <show id="ccd:producta"/> <show id="ccd:trima"/> <show id="ccd:vehicleColora"/> </field-visibility> <edit-form template="../documentlibrary/forms/doclib-simple-metadata.ftl" /> <appearance> <field id="ccd:producta" label="Product"> <control template="controls/selectoneCustom.ftl"> </control> </field> <field id="ccd:trima" label="Trim"> <control template="controls/selectoneDepenedentDisable.ftl"> </control> </field> <field id="ccd:vehicleColora" label="Vehicle Color"> <control template="controls/selectoneDisable.ftl"> </control> </field> </appearance> </form> <!– Document Library Inline Edit form –> <form id="doclib-inline-edit"> <field-visibility> <show id="ccd:producta"/> <show id="ccd:trima"/> <show id="ccd:vehicleColora"/> </field-visibility> </form> </forms> </config>
package com.mycomp.cascading.demo; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.servlet.http.HttpServletRequest; import org.springframework.extensions.webscripts.AbstractWebScript; import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptResponse; import org.springframework.extensions.webscripts.servlet.WebScriptServletRequest; public class CascadingWebScript extends AbstractWebScript { public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException { String driverName = "org.gjt.mm.mysql.Driver"; String serverName = "localhost"; String mydatabase = "cascading"; String username = "root"; String password = "root"; Connection connection = null; Statement stmt = null; ResultSet rs = null; try { HttpServletRequest httpReq = ((WebScriptServletRequest) req) .getHttpServletRequest(); String field = httpReq.getParameter("field"); String key = httpReq.getParameter("key"); String value = httpReq.getParameter("value"); System.out.println("Debugg : " + field + ":" + key + ":" + value); Class.forName(driverName); String url = "jdbc:mysql://" + serverName + "/" + mydatabase; connection = DriverManager.getConnection(url, username, password); stmt = connection.createStatement(); rs = stmt.executeQuery("select distinct " + field + " from imageasset where " + key + "= '" + value + "'"); String response = "–Select–,"; while (rs.next()) { if (rs.isLast()) response += rs.getString(field); else response += rs.getString(field) + ","; } System.out.println("Debugg : " + response); res.getWriter().write(response); } catch (Exception e) { e.printStackTrace(); res.getWriter().write("Error"); } finally { try { if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (connection != null && !connection.isClosed()) connection.close(); } catch (SQLException e) { e.printStackTrace(); res.getWriter().write("Error"); } } } }
<webscript> <shortname>Cascading Web script </shortname> <description>Get values from database</description> <url>/demo/cascading?field={field}&key={key}&value={value}</url> <authentication>none</authentication> <format default="json">argument</format> </webscript>
<bean id="webscript.org.alfresco.demo.cascading.get" class="com.mycomp.cascading.demo.CascadingWebScript" parent="webscript"> </bean>
<constraints> <constraint name="sample:parentConstraint" type="LIST"> <parameter name="allowedValues"> <list> <value></value> <value>1 - VALUE A</value> <value>2 - VALUE B</value> <value>3 - VALUE C</value> </list> </parameter> </constraint> <constraint name="sample:constraintOne" type="LIST"> <parameter name="allowedValues"> <list> <value></value> <value>1 - SUBVALUE ONE AX</value> <value>1 - SUBVALUE ONE AY</value> <value>1 - SUBVALUE ONE AZ</value> <value>2 - SUBVALUE ONE BX</value> <value>2 - SUBVALUE ONE BY</value> <value>3 - SUBVALUE ONE CY</value> <value>3 - SUBVALUE ONE CZ</value> </list> </parameter> </constraint> <constraint name="sample:constraintTwo" type="LIST"> <parameter name="allowedValues"> <list> <value></value> <value>1.2.3 - SUBVALUE TWO ABCX</value> <value>2.3 - SUBVALUE TWO BCX</value> <value>2.3 - SUBVALUE TWO BCY</value> <value>2.3 - SUBVALUE TWO BCZ</value> <value>3 - SUBVALUE TWO CX</value> <value>3 - SUBVALUE TWO CY</value> <value>3 - SUBVALUE TWO CZ</value> </list> </parameter> </constraint> </constraints>
<form> <field-visibility> <show id="sample:mainProperty" /> <show id="sample:propertyOne" /> <show id="sample:propertyTwo" /> <show id="sample:propertyThree" /> </field-visibility> <appearance> <field id="sample:mainProperty"> <control template="/org/alfresco/components/form/controls/parent-filter-selectone.ftl"> <control-param name="filteredProperty">sample_propertyOne,sample_propertyTwo</control-param> </control> </field> <field id="sample:propertyOne"> <control template="/org/alfresco/components/form/controls/filtered-selectone.ftl"/> </field> <field id="sample:propertyTwo"> <control template="/org/alfresco/components/form/controls/filtered-selectone.ftl"/> </field> </appearance> </form>
<parameter name="allowedValues"> <list> <value>parent1/test1</value> <value>parent1/test2</value> <value>parent1/test3</value> <value>parent2/test4</value> <value>parent2/test5</value> </list </parameter
<#include "/org/alfresco/components/form/controls/common/utils.inc.ftl" /> <!– defines how the option list elements are separated when passed to the client –> <#if field.control.params.optionSeparator??> <#assign optionSeparator=field.control.params.optionSeparator> <#else> <#assign optionSeparator=","> </#if> <!– defines how the label list elements are separated when passed to the client –> <#if field.control.params.labelSeparator??> <#assign labelSeparator=field.control.params.labelSeparator> <#else> <#assign labelSeparator="|"> </#if> <!– current value –> <#assign fieldValue=field.value> <!– handle default value for empty current value –> <#if fieldValue?string == "" && field.control.params.defaultValueContextProperty??> <#if context.properties[field.control.params.defaultValueContextProperty]??> <#assign fieldValue = context.properties[field.control.params.defaultValueContextProperty]> <#elseif args[field.control.params.defaultValueContextProperty]??> <#assign fieldValue = args[field.control.params.defaultValueContextProperty]> </#if> </#if> <script type="text/javascript"> /* string used to separate the parent from the child */ var OPTION_SEPARATOR = "/"; /** * Scripts used to split and synchronize the data between the 2 lists. **/ /** * @param stringValues: string containing the available values for the given field * @returns a javascript object containing those values **/ function getValsArrayFromString(stringValues) { //array with the options var valsArray = stringValues.split("${optionSeparator}"); //remove the labels for (var i = 0; i < valsArray.length; i++) { if(valsArray.indexOf("${labelSeparator}") != -1) { valsArray = valsArray.substr(0,valsArray.indexOf("${labelSeparator}")); } } return valsArray; } /** * Extracts the parent value from the full value of the option **/ function getParentValue(fullValue) { return fullValue.substr(0,fullValue.indexOf(OPTION_SEPARATOR)); } /** * Extracts the child value from the full value of the option **/ function getChildValue(fullValue) { return fullValue.substr(fullValue.indexOf(OPTION_SEPARATOR) + 1); } /** * Parent value have been changed. * Reset the current total value, child value and updates the available child values **/ function onChangeParentValue(stringValues, parentId, childId, totalId) { /* get an array from the string values */ var valsArray = getValsArrayFromString(stringValues); var parentValue = document.getElementById(parentId).value; var childSelect = document.getElementById(childId); /* empty the child select */ while(childSelect.firstChild) { childSelect.removeChild(childSelect.firstChild); } /* fill the child select with the new values */ for (var i = 0; i < valsArray.length; i++) { if ( getParentValue(valsArray) == parentValue) { var childValue = getChildValue(valsArray); var childOption = document.createElement("option"); childOption.value = childValue; childOption.innerHTML = childValue; childSelect.appendChild(childOption); } } } /** * Child value have been changed. * Update the total value **/ function onChangeChildValue(stringValues, parentId, childId, totalId) { var parentValue = document.getElementById(parentId).value; var childValue = document.getElementById(childId).value; document.getElementById(totalId).value = parentValue + OPTION_SEPARATOR + childValue; } /** * Initial filling of the parent values available * TODO: handle default value **/ function populateSelects(stringValues, initialValue, parentId, childId, totalId) { /* get an array from the string values */ var valsArray = getValsArrayFromString(stringValues); var parentSelect = document.getElementById(parentId); /* we only want to display each parent value once. This object keeps track of the already added ones */ var uniqueParentValues = {}; /* populate parent select */ for (var i = 0; i < valsArray.length; i++) { var realV = getParentValue(valsArray); if(!uniqueParentValues.hasOwnProperty(realV)) { uniqueParentValues[realV] = true; /* create new option for the parent select */ var parOption = document.createElement("option"); parOption.value = realV; parOption.innerHTML = realV; if(realV == getParentValue(initialValue)) { parOption.selected = "selected"; } parentSelect.appendChild(parOption); } } /* populate child select */ onChangeParentValue(stringValues, parentId, childId, totalId); /* sets the correct child value */ var childSelect = document.getElementById(childId); childSelect.value = getChildValue(initialValue); onChangeChildValue(stringValues, parentId, childId, totalId); } </script> <div class="form-field"> <!– readonly mode. No action required, display the composed value as is –> <#if form.mode == "view"> <div class="viewmode-field"> <#if field.mandatory && !(fieldValue?is_number) && fieldValue?string == ""> <span class="incomplete-warning"><img src="${url.context}/res/components/form/images/warning-16.png" title="${msg("form.field.incomplete")}" /><span> </#if> <span class="viewmode-label">${field.label?html}:</span> <#if fieldValue?string == ""> <#assign valueToShow=msg("form.control.novalue")> <#else> <#assign valueToShow=fieldValue> <#if field.control.params.options?? && field.control.params.options != ""> <#list field.control.params.options?split(optionSeparator) as nameValue> <#if nameValue?index_of(labelSeparator) == -1> <#if nameValue == fieldValue?string || (fieldValue?is_number && fieldValue?c == nameValue)> <#assign valueToShow=nameValue> <#break> </#if> <#else> <#assign choice=nameValue?split(labelSeparator)> <#if choice[0] == fieldValue?string || (fieldValue?is_number && fieldValue?c == choice[0])> <#assign valueToShow=msgValue(choice[1])> <#break> </#if> </#if> </#list> </#if> </#if> <span class="viewmode-value">${valueToShow?html}</span> </div> <#else> <!– Editable mode. –> <!– let's keep a single label for both fields –> <label for="${fieldHtmlId}">${field.label?html}:<#if field.mandatory><span class="mandatory-indicator">${msg("form.required.fields.marker")}</span></#if></label> <#if field.control.params.options?? && field.control.params.options != ""> <!– first select for the parent value –> <select id="parent-${fieldHtmlId}" tabindex="0" <#if field.description??>title="${field.description}"</#if> <#if field.control.params.size??>size="${field.control.params.size}"</#if> <#if field.control.params.styleClass??>class="${field.control.params.styleClass}"</#if> <#if field.control.params.style??>style="${field.control.params.style}"</#if> <#if field.disabled && !(field.control.params.forceEditable?? && field.control.params.forceEditable == "true")>disabled="true"</#if> onchange="onChangeParentValue('${field.control.params.options}', 'parent-${fieldHtmlId}', 'child-${fieldHtmlId}', '${fieldHtmlId}');" > </select> <!– second select for the child value –> <select id="child-${fieldHtmlId}" name="${field.name}" tabindex="0" <#if field.description??>title="${field.description}"</#if> <#if field.control.params.size??>size="${field.control.params.size}"</#if> <#if field.control.params.styleClass??>class="${field.control.params.styleClass}"</#if> <#if field.control.params.style??>style="${field.control.params.style}"</#if> <#if field.disabled && !(field.control.params.forceEditable?? && field.control.params.forceEditable == "true")>disabled="true"</#if> onchange="onChangeChildValue('${field.control.params.options}', 'parent-${fieldHtmlId}', 'child-${fieldHtmlId}', '${fieldHtmlId}');" > </select> <!– hidden field containing the final value (e.g. the one sent to the server and stored in database) –> <input type="hidden" id="${fieldHtmlId}" name="${field.name}" /> <@formLib.renderFieldHelp field=field /> <#else> <div id="${fieldHtmlId}" class="missing-options">${msg("form.control.selectone.missing-options")}</div> </#if> </#if> </div> <!– IMPORTANT: this script must execute after the fields are created –> <script type="text/javascript"> setTimeout(function(){populateSelects("${field.control.params.options}", "${fieldValue}", "parent-${fieldHtmlId}", "child-${fieldHtmlId}", "${fieldHtmlId}");}, 1000); </script>
<field id="my:cascadingProperty" label-id="workflow.field.cascadingProperty"> <control template="/org/alfresco/components/form/controls/cascading-dropdowns.ftl" /> </field>
i want the source code ,could you send it to my email (chenzixia@fiberhome.com) ,thanks
Hi Kevin,
I have used https://github.com/douglascrp/alfresco-value-assistance this
project for cascading dropdown. Please try this.
Thanks
Hiten Rastogi
Sr. Software Engineer
Mobile: +91 9899586608
Email: hiten.rastogi@eisenvault.com <vipul.swarup@eisenvault.com>
thank you very much, it's worked
Hello Friend,
I'm new in Alfresco. How Can I do to implement this github solution working on my Alfresco Communit.
What I have to do? What steps I have to fallow in order to get it working? Where I have to put this folders ( alfresco-value-assistance-repo and alfresco-value-assistance-share) into Alfresco ?
Thanks in advance for your help.
Regards,
Geovanny C.