April 7, 2020
Estimated Post Reading Time ~

Touch UI dynamic selection of multiple drop downs in AEM 6.1



This article shows the use case of has multiple chained drops down in Touch UI. Values in the next dropdown depend on what has been selected on the previous one.


Brief on how it works:-
There are two drop-downs with the name Language and Country. When you select a Language from the drop-down, the Country drop-down gets populated with the name of the countries using that language. For example, if you select “German” as a language then all countries using German as a language will get populated in the second dropdown.

Select language as ‘German’


Countries names get populated


Values in Language drop-down gets populated using DataSource. Once the user selects a language, an ajax request is made to the URL http://localhost:4502/libs/wcm/core/resources/languages.2.json which gives the data for countries and languages. Returned data is filtered based on the language selected and countries dropdown is created dynamically.

DataSource for populating values in the language drop-down

<%@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("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);
%>

Next, we have an added client libs for the component with categories as cq:authoring.dialog

It contains a single JS file with the below code

(function($, $document) {
"use strict";

var LANGUAGE = "./language",
COUNTRY = "./country";

function adjustLayoutHeight() {
$(".coral-FixedColumn-column").css("height", "20rem");
}

$document.on("dialog-ready", function() {
adjustLayoutHeight();

// Getting reference of language drop down field
var language = $("[name='" + LANGUAGE + "']").closest(".coral-Select")

// Initializing country drop down field
var country = new CUI.Select({
element: $("[name='" + COUNTRY + "']").closest(".coral-Select")
});

if (_.isEmpty(country) || _.isEmpty(language)) {
return;
}

var langCountries = {};
country._selectList.children().not("[role='option']").remove();

function fillCountries(selectedLang, selectedCountry) {

var x = $("[name='./country']").closest(".coral-Select").find('option').remove().end();
_.each(langCountries, function(value, lang) {

if ((lang.indexOf(selectedLang) !== 0) || (value.country == "*")) {
return;
}

var test2 = $("[name='./country']")[0];

$("<option>").appendTo(test2).val(lang).html(value.country);
});

country = new CUI.Select({
element: $("[name='" + COUNTRY + "']").closest(".coral-Select")
});

if (!_.isEmpty(selectedCountry)) {
country.setValue(selectedCountry);
}
}

//listener on language select for dynamically filling the countries on language select
language.on('selected.select', function(event) {
console.log(event);
fillCountries(event.selected);
});

// Get the languages list from the source
$.getJSON("/libs/wcm/core/resources/languages.2.json").done(function(data) {
langCountries = data;

var $form = country.$element.closest("form");

//get the second select box (country) saved value
$.getJSON($form.attr("action") + ".json").done(function(data) {
if (_.isEmpty(data)) {
return;
}

// Passing values to populate countries list
fillCountries(language.val(), data.country);
})
});

});
})($, $(document));

JavaScript code in client lib is responsible for changing values in the second drop-down based on the first.


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.