AEM RichText Max Characters Length Validation

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

Client Library programmatic setup

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:
Touch UI dialogue - Rich Text max-character-limit result


Looking for Help? Or need a mentor?

If you need help to super drive your AEM career road map, you can hire me for a one-hour session on codementor.io; We can work together on a price works just for you. https://www.codementor.io/@briankasingli. I'd be happy to help you along your way to becoming a high-quality AEM full-stack engineer.

Was this post helpful?

Hello, I am an enthusiastic Adobe Community Advisor and a seasoned Lead AEM Developer. I am currently serving as an AEM Technical Lead at MNPDigital.ca, bringing over a decade of extensive web engineering experience and more than eight years of practical AEM experience to the table. My goal is to give back to the AEM Full Stack Development community by sharing my wealth of knowledge with others. You can connect with me on LinkedIn.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top