In this article, we will take a look at how we can add max character length validation to the richtext component, cq/gui/components/authoring/dialog/richtext, by introducing a maxlength attribute. The validation will be executed whenever AEM authors try to save or perform an on-key-up action after applying changes within the richtext input field. After implementing the solution, all richtext components within the installed AEM author environment will have this feature enabled.
1 2 3 4 5 6 7 8 9 10 | // to enable the max character limit, simply include the "maxlength" attribute <description jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog/richtext" fieldLabel="Description (max 100 chars)" name="./description" useFixedInlineToolbar="{Boolean}true" maxlength="100"> ... </description> |
We will be solving this problem by registering a new validator (foundation.validation.validator) to the foundation-registry (the foundation-registry is used in the Granite UI framework). In this solution we will be utilising the jQuery Validation library (the validation library used by Granite UI is achieved by using jQuery Validation plugin). A new client library will be introduced to inject JavaScript into our context page, and to execute the registry and scripts.
Steps for Enabling RichText Max Characters Validation
Step 1. Client Library
1.1 Create a new client library with the XML configurations below:
1 2 3 4 5 6 | <?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" jcr:primaryType="cq:ClientLibraryFolder" allowProxy="{Boolean}true" categories="[cq.authoring.editor.hook]" dependencies="[cq.authoring.editor.core]"/> |
1.2 Configure the client libraries js.txt
Create a js.txt file in the client library with the body content below:
1 2 | #base=js richtext-maxwidth-validation.js |
1.3 Register the new Validator with Javascript
Create create a folder named js, and under that, create the richtext-maxwidth-validation.js file with the script below:
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 | ;(function (window, $) { 'use strict'; /** * Rich-Text Editor Max Length Validation * * @class RichTextMaxLengthValidation * @classdesc registers a new validator to the foundation-registry service focused on the * cq/gui/components/authoring/dialog/richtext component. * * Usage: the attribute maxlength to the richtext component, example: maxlength="100" */ var RichTextMaxLengthValidation= function () { var CONST = { TARGET_GRANITE_UI: '.coral-RichText-editable', ERROR_MESSAGE: 'Your text length is {0} but character limit is {1}!', }; /** * Initializes the RichTextMaxLengthValidation */ function init() { // register the validator which includes the validate algorithm $(window).adaptTo('foundation-registry').register('foundation.validation.validator', { selector: CONST.TARGET_GRANITE_UI, validate: function (el) { var $rteField = $(el); var $field = $rteField.closest('.richtext-container').find('input.coral-Form-field'); var maxLength = $field.data('maxlength'); var textLength = $rteField.text().trim().length; if (maxLength && textLength > maxLength) { return Granite.I18n.get(CONST.ERROR_MESSAGE, [textLength, maxLength]); } return null; } }); // execute Jquery Validation onKeyUp $(document).on('keyup', CONST.TARGET_GRANITE_UI, function (e) { executeJqueryValidation($(this)); }); } /** * Execute foundation.validation.validator's validate algorithm. */ function executeJqueryValidation(el) { var validationApi = el.adaptTo('foundation-validation'); if (validationApi) { validationApi.checkValidity(); validationApi.updateUI(); } } return { init: init } }(); RichTextMaxLengthValidation.init(); })(window, Granite.$); |
Step 2. Include the maxlength Attribute
Within the Granite UI XML configure configuration, add the “maxlength” attribute, example: maxlength=”100″.
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 | <?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="RichText Max Characters" sling:resourceType="cq/gui/components/authoring/dialog"> <content jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/container"> <items jcr:primaryType="nt:unstructured"> <descriptionText1 jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog/richtext" fieldLabel="Description (max 100 chars)" maxlength="100" name="./description" useFixedInlineToolbar="{Boolean}true"> <rtePlugins jcr:primaryType="nt:unstructured"> <formats jcr:primaryType="nt:unstructured" features="*"/> <links jcr:primaryType="nt:unstructured" features="*"/> </rtePlugins> <uiSettings jcr:primaryType="nt:unstructured"> <cui jcr:primaryType="nt:unstructured"> <inline jcr:primaryType="nt:unstructured" toolbar="[links#modifylink,links#unlink,format#bold,format#italic]"/> <dialogFullScreen jcr:primaryType="nt:unstructured" toolbar="[links#modifylink,links#unlink,format#bold,format#italic]"/> </cui> </uiSettings> </descriptionText1> </items> </content> </jcr:root> |
Step 3. Done
When an AEM author exceeds the maximum character limit, the richtext component will display a default Granite UI error icon. Clicking on the error icon will display the error message, which the error message is configured in the JavaScript logic. Validation for the maximum character limit will be executed whenever an AEM author tries to save the form or during a keypress up event.
Result: