AEM: Setting maximum items for a multifield
2018-07-13
There is an Adobe published article that shows how to set a max on the amount of items allowd in a multifield, you can find it here. The content of the article is fine if you are using the older CoralUI 2-based dialog components, in this tutorial I'll show you how its done for the CoralUI 3-based dialog components.
NOTE: You can find the migration guide here
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
... <?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:granite="http://www.adobe.com/jcr/granite/1.0" ... <colors jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/multifield" fieldDescription="Click 'Add field' to add a new color" fieldLabel="Colors" composite="{Boolean}true"> <granite:data jcr:primaryType="nt:unstructured" max-items="2"/> <field jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container" name="./colors"> <items jcr:primaryType="nt:unstructured"> <color jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/textfield" fieldDescription="Fill in a hex value: # and 6 characters" fieldLabel="Color" name="color"/> </items> </field> </colors> ...
We specify a max-items attribute in the granite:data part of the xml so that we can later on use it in our clientlib. You can see here that the multifield now has that data- attribute:
The clientlib
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
(function ($, $document) { "use strict"; // ************************************************************************** // ** CONSTANTS // ************************************************************************** const EVENT_CLICK = "click"; const ATTRIBUTE_MULTIFIELD_ADD = "coral-multifield-add"; const ATTRIBUTE_MULTIFIELD_MAX_ITEMS = "data-max-items"; const SELECTOR_MULTIFIELD_ADD_ITEM_BUTTON = `button[${ATTRIBUTE_MULTIFIELD_ADD}]`; const SELECTOR_MULTIFIELD_ITEM = "coral-multifield-item"; // ************************************************************************** // ** CLASSES // ************************************************************************** class Listener { constructor(selector, event, handler) { this.selector = selector; this.event = event; this.handler = handler; } getSelector() { return this.selector; } getEvent() { return this.event; } getHandler() { return this.handler; } } // ************************************************************************** // ** LISTENER HANDLERS // ************************************************************************** function multifieldMaxItemsHandler(context) { const $field = $(context).parent(); const maxSize = $field.attr(ATTRIBUTE_MULTIFIELD_MAX_ITEMS); if (maxSize) { const ui = $(window).adaptTo("foundation-ui"); const currentSize = $field.children(SELECTOR_MULTIFIELD_ITEM).length; if (currentSize >= maxSize) { ui.alert("Warning", "Maximum " + maxSize + " items are allowed!", "notice"); return false; } } } // ************************************************************************** // ** LISTENERS // ************************************************************************** const listeners = []; listeners.push(new Listener(SELECTOR_MULTIFIELD_ADD_ITEM_BUTTON, EVENT_CLICK, multifieldMaxItemsHandler)); // ************************************************************************** // ** REGISTER LOGIC // ************************************************************************** $document.on("dialog-ready", function () { $.each(listeners, function (index, listener) { $(listener.getSelector()).on(listener.getEvent(), function () { return listener.getHandler()(this); }) }); }); })($, $(document));
The JavaScript is really straightforward:
- Add a click listener to the add button.
- Read the data-max-items attribute from the multifield.
- Check the current items in the multifield, if this is larger than the maximum amount of items allowed -> show an error message.