Goal
In a Touch UI dialog, add items to Multifield dynamically, based on the value selected in Drop Down (Select) widget. In this sample, countries are added in multifield /libs/granite/ui/components/foundation/form/multifield based on the language selected /libs/granite/ui/components/foundation/form/select
Demo | Package Install
Solution
1) Login to CRXDE Lite (http://localhost:4502/crx/de) and create folder /apps/touchui-dynamic-select-multifield
2) Create node /apps/touchui-dynamic-select-multifield/clientlib of type cq:ClientLibraryFolder and add a String property categories with value cq.authoring.dialog
3) Create file (nt:file) /apps/touchui-dynamic-select-multifield/clientlib/js.txt and add
dynamic-multifield.js
4) Create file (nt:file) /apps/touchui-dynamic-select-multifield/clientlib/dynamic-multifield.js and add the following code
(function ($, $document) {
"use strict";
var LANGUAGE = "./language", COUNTRY = "./country";
$document.on("dialog-ready", function() {
var langCountries = {},
$language = $("[name='" + LANGUAGE + "']"),
$countryDelete = $("[name='" + COUNTRY + "@Delete']"),
cuiLanguage = $language.closest(".coral-Select").data("select"),
cuiCountry = $countryDelete.closest(".coral-Multifield").data("multifield"),
$countryAdd = cuiCountry.$element.find(".js-coral-Multifield-add");
cuiLanguage.on('selected.select', function(event){
var $country;
cuiCountry.$element.find(".js-coral-Multifield-remove").click();
_.each(langCountries[event.selected], function(country){
$countryAdd.click();
$country = cuiCountry.$element.find("[name='" + COUNTRY + "']:last");
$country.val(country);
});
});
function fillCountries(data){
var countries;
_.each(data, function(country, code){
if(!_.isObject(country) || (country.country === "*") ){
return;
}
code = getLangCode(code);
countries = langCountries[code] || [];
countries.push(country.country);
langCountries[code] = countries;
});
}
$.getJSON("/libs/wcm/core/resources/languages.2.json").done(fillCountries);
});
function getLangCode(code){
if(code.indexOf("_") != -1){
code = code.substring(0, code.indexOf("_"));
}
return code;
}
})(jQuery, jQuery(document));
5) Create a simple datasource for languages - /apps/touchui-dynamic-select-multifield/datasource/language/language.jsp
<%@include file="/libs/granite/ui/global.jsp"%>
<%@ page import="com.adobe.granite.ui.components.ds.DataSource" %>
<%@ page import="com.adobe.granite.ui.components.ds.ValueMapResource" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="org.apache.sling.api.wrappers.ValueMapDecorator" %>
<%@ page import="com.adobe.granite.ui.components.ds.SimpleDataSource" %>
<%@ page import="org.apache.commons.collections.iterators.TransformIterator" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.LinkedHashMap" %>
<%@ page import="org.apache.commons.collections.Transformer" %>
<%@ page import="org.apache.sling.api.resource.*" %>
<%
final Map<String, String> languages = new LinkedHashMap<String, String>();
languages.put("", "Select");
languages.put("ar", "Arabic");
languages.put("en", "English");
languages.put("de", "German");
final ResourceResolver resolver = resourceResolver;
DataSource ds = new SimpleDataSource(new TransformIterator(languages.keySet().iterator(), new Transformer() {
public Object transform(Object o) {
String language = (String) o;
ValueMap vm = new ValueMapDecorator(new HashMap<String, Object>());
vm.put("value", language);
vm.put("text", languages.get(language));
return new ValueMapResource(resolver, new ResourceMetadata(), "nt:unstructured", vm);
}
}));
request.setAttribute(DataSource.class.getName(), ds);
%>
6) Touch UI dialog xml - /apps/touchui-dynamic-select-multifield/fill-multifield-on-select-component/cq:dialog
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Sample Dynamic Select Multifield Component"
sling:resourceType="cq/gui/components/authoring/dialog"
helpPath="en/cq/current/wcm/default_components.html#Text">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<fieldset
jcr:primaryType="nt:unstructured"
jcr:title="Sample Select"
sling:resourceType="granite/ui/components/foundation/form/fieldset">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<language
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/select"
fieldLabel="Language"
name="./language">
<datasource
jcr:primaryType="nt:unstructured"
sling:resourceType="/apps/touchui-dynamic-select-multifield/datasource/language"
addNone="{Boolean}true"/>
</language>
<country
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/multifield"
fieldLabel="Country">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
name="./country"/>
</country>
</items>
</column>
</items>
</fieldset>
</items>
</column>
</items>
</content>
</jcr:root>