Thursday, July 26, 2018
AEM 61 TouchUI Add Items to Multifield based on Select Drop Down value
AEM 61 TouchUI Add Items to Multifield based on Select Drop Down value
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
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>