AEM 61 - TouchUI Date Picker Validator Comparing Two Date Fields in Dialog

Goal


Add a Validator on Granite (Coral) Date Picker in TouchUI Dialogs

Page properties dialog has two fields OnTime and OffTime for Activation / Deactivation; for demo purposes, validator here checks if date of OffTime is lesser than OnTime

Demo shows dialog of foundation page component modified to add the eaemCheckDateAfter config (/libs/foundation/components/page/cq:dialog/content/items/tabs/items/basic/items/column/items/onofftime/items/offdate). This is just for demonstration only (on Geometrixx pages), ideally the foundation components should never be altered

Demo | Package Install


Configuration

Set the property eaemCheckDateAfter value to the name of dialog property to check against. Here its set to ./onTime



Inline Dialog - Error Shown when Off Time < On Time



Full Screen Dialog - Error Shown when Off Time < On Time



Solution


1) Login to CRXDE Lite, create folder (nt:folder) /apps/touchui-date-picker-validator

2) Create clientlib (type cq:ClientLibraryFolder/apps/touchui-date-picker-validator/clientlib and set a property categories of String type to cq.authoring.dialogdependencies of type String[] with value underscore

3) Create file ( type nt:file ) /apps/touchui-date-picker-validator/clientlib/js.txt, add the following

                         date-validator.js

4) Create file ( type nt:file ) /apps/touchui-date-picker-validator/clientlib/date-validator.js, add the following code

(function ($) {
    var EAEM_CHECK_DATE_AFTER = "eaemcheckdateafter",
        fieldErrorEl = $("<span class='coral-Form-fielderror coral-Icon coral-Icon--alert coral-Icon--sizeS' " +
                            "data-init='quicktip' data-quicktip-type='error' />");

    $.validator.register({
        selector: "input",
        validate: validate, //if validate() returns a non empty value, show() is called
        show: show,
        clear: clear
    });

    function validate($el){
        //if not date widget or widget value is empty, return
        if(!$el.parent().hasClass("coral-DatePicker") || _.isEmpty($el.val())){
            return;
        }

        var $datePicker = $el.parent(),
            $form = $datePicker.closest("form"),
            checkDateAfter = $datePicker.data(EAEM_CHECK_DATE_AFTER);

        if(_.isEmpty(checkDateAfter)){
            return;
        }

        var $toCompareField = $form.find("[name='" + checkDateAfter + "']");

        if(_.isEmpty($toCompareField) || _.isEmpty($toCompareField.val())){
            return;
        }

        var toCompareMillis = new Date($toCompareField.val()).getTime(),
            compareWithMillis = new Date($el.val()).getTime(),
            text = $toCompareField.closest(".coral-Form-fieldwrapper").find(".coral-Form-fieldlabel").html();

        return ( compareWithMillis < toCompareMillis) ? "Should not be less than '" + text + "'" : null;
    }

    function show($el, message){
        if(!$el.parent().hasClass("coral-DatePicker")){
            return;
        }

        var $datePicker = $el.parent();

        this.clear($el);

        var arrow = $datePicker.closest("form").hasClass("coral-Form--vertical") ? "right" : "top";

        $el.attr("aria-invalid", "true").toggleClass("is-invalid", true);

        fieldErrorEl.clone()
            .attr("data-quicktip-arrow", arrow)
            .attr("data-quicktip-content", message)
            .insertAfter($datePicker);
    }

    function clear($el){
        if(!$el.parent().hasClass("coral-DatePicker")){
            return;
        }

        var $datePicker = $el.parent();

        $el.removeAttr("aria-invalid").removeClass("is-invalid");

        $datePicker.nextAll(".coral-Form-fielderror").tooltip("hide").remove();
    }
}(jQuery));

2 comments:

  1. this.clear($el); this not a function.

    ReplyDelete
  2. to solve delete the 'this.' before the clear and will work.... for readability I also moved the clear function above the show()

    ReplyDelete