Recently, we had the need for an authoring experience where, an author can re-order a list of fixed tabs to their desired order. The only Granite widget that allows drag-n-drop ordering is the multifield, but we don’t need a multifield, we just wanted the ability to order a fixed list. An Existing solution ACS Commons has this Draggable Lists Widget but I did not want to include ACS commons just for that widget. Additionally, I looked at the implementation for that widget and it seemed to be complex granted it might be solving a different problem. It also used Coral UI 2; we are on AEM 6.4 where Coral UI 3 is the latest Coral version. A Simple Solution If you look at Coral UI 3 documentation, the only component that allows drag-n-drop ordering is the Coral.Table component. Which means, we can create a Granite widget that uses that UI to render a list! Here is the widget JSP impl: (Java 8) for the purpose of this post, I’ve created /apps/widgets/orderedList/orderedList.jsp Here, I render each item in the list as a hidden field with the same “name”. The order of the hidden fields in the HTML is what determines the saved order in the JCR content node/prop. This also means that we dont need ANY custom JS to make this work! just the OOTB CUI3 Table component! <%-- Renders a List of items for ordering purposes only --%><% %><%@ include file="/libs/granite/ui/global.jsp" %><% %><%@ page session="false" import="java.util.Iterator, com.adobe.granite.ui.components.AttrBuilder, com.adobe.granite.ui.components.Tag, com.adobe.granite.ui.components.Config, org.apache.sling.api.resource.ValueMap, java.util.stream.StreamSupport, java.util.stream.Collectors, java.util.*" %> <%--### Ordered List ==== // TODO .. granite:servercomponent:: widgets/orderedList Renders a List of items for ordering purposes only It has the following content structure: + myList - sling:resourceType = "widgets/orderedList" - name = "./myList" - title = "My List" + items + item1 - text = "Item 1" - value = "item1" + item 2 - text = "Item 2" - value = "item2" ###--%> <% if (!cmp.getRenderCondition(resource, false).check()) { return; } Tag tag = cmp.consumeTag(); AttrBuilder attrs = tag.getAttrs(); attrs.addClass("coral-Well"); cmp.populateCommonAttrs(attrs); Config cfg = cmp.getConfig(); String title = cfg.get("title", String.class); String name = cfg.get("name", String.class); // the easy way to do this... String cleanName = name != null ? name.replace(".", "").replace("/", "") : ""; String tableId = "order-table-" + cleanName; String hiddenInputId = "order-input-" + cleanName; String[] values = cmp.getValue().getContentValue(name, new String[0]); List valuesList = Arrays.asList(values); Iterator itemsIterator = cmp.getItemDataSource().iterator(); // server-side ordering of values based on already saved order List items = StreamSupport.stream( Spliterators.spliteratorUnknownSize(itemsIterator, Spliterator.ORDERED), false ).sorted( Comparator.comparing(item -> { ValueMap vm = ((Resource) item).getValueMap(); String val = vm.get("value", ""); return valuesList != null ? valuesList.indexOf(val) : 0; }) ).map(Resource::getValueMap) .collect(Collectors.toList()); %>
<%=title%> | |
---|---|
<%=vm.get("text", "") %> "/> |
Please use this thread to ask the related questions.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes