AEM 62 - Support Required (Validator) on FileUpload (Image) in Touch UI Dialog


Touch UI extension to support required on FileUpload widget - /libs/granite/ui/components/foundation/form/fileupload using Granite validator. For validation api check documentation

For a similar extension on 61 supporting required on RTE check this post

Dialog of foundation image component /libs/foundation/components/image/cq:dialog/content/items/column/items/file was modified for demonstration purposes only

Demo | Package Install

File Upload widget - required = true

Validation Error


1) Login to CRXDE Lite (http://localhost:4502/crx/de) and create folder /apps/eaem-touchui-image-required

2) Create node /apps/eaem-touchui-image-required/clientlib of type cq:ClientLibraryFolder and add a String property categories with value cq.authoring.dialog and dependencies to underscore

3) Create file (nt:file) /apps/eaem-touchui-image-required/clientlib/js.txt and add


4) Create file (nt:file) /apps/eaem-touchui-image-required/clientlib/image-required.js and add the following code

(function ($, $document, gAuthor) {
    var EAEM_IMAGE_REQ_FIELD_ID_PREFIX = "eaem-img-required-",
        FILE_UPLOAD = ".coral-FileUpload",
        FILE_UPLOAD_CLEAR = ".cq-FileUpload-clear",
        DATA_ATTR_FILE_UPLOAD = "fileUpload",
        FILE_UPLOAD_SEL = ".coral-FileUpload-input",
        FILE_NAME = "./fileName",
        COMPONENT = "foundation/components/image",
        FIELD_ERROR_EL = $("<span class='coral-Form-fielderror coral-Icon coral-Icon--alert " +
                            "coral-Icon--sizeS' data-init='quicktip' data-quicktip-type='error'>" +

    $document.on('dialog-ready', checkFileRequired);

    function checkFileRequired(){
        var $fileUpload = $(FILE_UPLOAD),
            $fileName = $("[name='" + FILE_NAME + "']"),
            fileReqId = EAEM_IMAGE_REQ_FIELD_ID_PREFIX + getStringAfterLastSlash(FILE_NAME),
            editable = gAuthor.DialogFrame.currentDialog.editable;

        //if not an image component dialog, return
        if((editable.type !== COMPONENT) || _.isEmpty($fileName)){

        //fileName field is hidden input, for the validator to work, add a invisible text field
        //holding the file name
        $fileUpload.append("<input type=text style='display:none' id='" + fileReqId + "'/>");

        var cuiFileUpload = $,
            $fileReqInvisibleField = $("#" + fileReqId);

        addValidatorIfRequiredSet(editable, cuiFileUpload, $fileReqInvisibleField);

    function addValidatorIfRequiredSet(editable, cuiFileUpload, $fileReqInvisibleField){
        var $fileUploadInput = cuiFileUpload.$element.find(FILE_UPLOAD_SEL);

        if ($fileUploadInput.attr("aria-required") !== "true") {

        //user can either drop or upload an image; with required set to true
        //validator with selector: ".coral-FileUpload-input"
        //in /libs/granite/ui/components/foundation/clientlibs/foundation.js
        //always checks if there is a file queued for upload, so workaround it by removing
        //the required attribute on file upload input
        $fileUploadInput.removeAttr( "aria-required" );

        cuiFileUpload.$element.find(FILE_UPLOAD_CLEAR).on("click tap", function (e) {
            performRequiredCheck($fileReqInvisibleField, '');

        cuiFileUpload.$element.on("fileuploadsuccess", function (event) {

        cuiFileUpload.$element.on("assetselected", function (event) {
            performRequiredCheck($fileReqInvisibleField, event.path);


        initRequiredField($fileReqInvisibleField, editable.path);

    function initRequiredField($fileReqInvisibleField, path){
        var fileName = getStringAfterLastSlash(FILE_NAME);

        $.ajax(path + ".json").done(function(data){
            var value = data[fileName];

                value = data["fileReference"];


                value = getStringAfterLastSlash(value);


    function performRequiredCheck($fileReqInvisibleField, value){

    function addValidator($fileReqInvisibleField){
            selector: "#" + $fileReqInvisibleField.attr("id"),

            validate: validate ,

            show: show ,

            clear: clear

        function validate($fileReqInvisibleField) {
            if (_.isEmpty($fileReqInvisibleField.val())) {
                return "Drop or upload an image";

            return null;

        function show($fileReqInvisibleField, message) {
            var $fileUploadField = $fileReqInvisibleField.closest(FILE_UPLOAD),
                arrow = $fileUploadField.closest("form").hasClass("coral-Form--vertical") ? "right" : "top",
                $error = $fileUploadField.nextAll(".coral-Form-fielderror");

            if (!_.isEmpty($error)) {

                .attr("data-quicktip-arrow", arrow)
                .attr("data-quicktip-content", message)

        function clear($fileReqInvisibleField) {
            var $fileUploadField = $fileReqInvisibleField.closest(FILE_UPLOAD);

    function getStringAfterLastSlash(str){
        if(!str || (str.indexOf("/") == -1)){
            return "";

        return str.substr(str.lastIndexOf("/") + 1);
}(jQuery, jQuery(document),;

1 comment:

  1. Hi Sreekanth ,

    I was trying this in my component. It was successfully implemented and the validations are implementing correctly without any fail.

    But when i am dragging and dropping the image component on the same page . These validations are implemented in the image component also.
    I have implemented validations in my custom component only. Not in the image component.

    if((editable.type !== COMPONENT) || _.isEmpty($fileName)){

    above piece of code is also not working:
    I have given COMPONENT="apps/myproject/components/mycustomcomponent"

    Please give some pointers on this.