Goal
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
Solution
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
image-required.js
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'>" + "</span>"); if(!gAuthor){ return; } $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)){ return; } //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 = $fileUpload.data(DATA_ATTR_FILE_UPLOAD), $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") { return; } //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) { performRequiredCheck($fileReqInvisibleField, event.item.file.name); }); cuiFileUpload.$element.on("assetselected", function (event) { performRequiredCheck($fileReqInvisibleField, event.path); }); addValidator($fileReqInvisibleField); initRequiredField($fileReqInvisibleField, editable.path); } function initRequiredField($fileReqInvisibleField, path){ var fileName = getStringAfterLastSlash(FILE_NAME); $.ajax(path + ".json").done(function(data){ var value = data[fileName]; if(_.isEmpty(value)){ value = data["fileReference"]; if(_.isEmpty(value)){ return; } value = getStringAfterLastSlash(value); } $fileReqInvisibleField.val(value); }) } function performRequiredCheck($fileReqInvisibleField, value){ $fileReqInvisibleField.val(value); $fileReqInvisibleField.checkValidity(); $fileReqInvisibleField.updateErrorUI(); } function addValidator($fileReqInvisibleField){ $.validator.register({ 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)) { return; } FIELD_ERROR_EL.clone() .attr("data-quicktip-arrow", arrow) .attr("data-quicktip-content", message) .insertAfter($fileUploadField); } function clear($fileReqInvisibleField) { var $fileUploadField = $fileReqInvisibleField.closest(FILE_UPLOAD); $fileUploadField.nextAll(".coral-Form-fielderror").remove(); } } function getStringAfterLastSlash(str){ if(!str || (str.indexOf("/") == -1)){ return ""; } return str.substr(str.lastIndexOf("/") + 1); } }(jQuery, jQuery(document), Granite.author));
Hi Sreekanth ,
ReplyDeleteI 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)){
return;
}
above piece of code is also not working:
I have given COMPONENT="apps/myproject/components/mycustomcomponent"
Please give some pointers on this.