Goal
Show simple Metadata Form in the Upload Dialog of Touch UI Assets Console; With this extension users can add metadata while uploading files
For AEM 65 check this post
For AEM 62 check this post
Demo | Package Install
Metadata Form in Upload Dialog
Metadata Validation
Metadata in CRX
Solution
1) Login to CRXDE Lite (http://localhost:4502/crx/de), create folder /apps/eaem-assets-file-upload-with-metadata
2) Metadata form shown in Upload Dialog is an Authoring Dialog; Create the dialog /apps/eaem-assets-file-upload-with-metadata/dialog, add metadata form nodes
Dialog XML
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/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" sling:resourceType="granite/ui/components/foundation/container"> <layout jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns" margin="{Boolean}false"/> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/container"> <items jcr:primaryType="nt:unstructured"> <title jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/textfield" fieldDescription="Enter Title" fieldLabel="Title" name="./eaemTitle" required="{Boolean}true"/> <useBy jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/datepicker" class="field" displayedFormat="YYYY-MM-DD HH:mm" fieldLabel="Use By" name="./eaemUseBy" type="datetime"/> <onlyForWeb jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/checkbox" name="./eaemOnlyForWeb" text="Only for web?"/> <type jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/select" fieldDescription="Select Size" fieldLabel="Size" name="./eaemSize"> <items jcr:primaryType="nt:unstructured"> <def jcr:primaryType="nt:unstructured" text="Select Size" value=""/> <small jcr:primaryType="nt:unstructured" text="Small" value="small"/> <medium jcr:primaryType="nt:unstructured" text="Medium" value="medium"/> <large jcr:primaryType="nt:unstructured" text="Large" value="large"/> </items> </type> <tags jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/common/tagspicker" allowCreate="{Boolean}true" fieldLabel="Tags" name="./eaemTags"/> </items> </column> </items> </jcr:root>
3) Create node /apps/eaem-assets-file-upload-with-metadata/clientlib of type cq:ClientLibraryFolder, add String[] property categories with value dam.gui.coral.fileupload String[] property dependencies with value underscore
4) Create file (nt:file) /apps/eaem-assets-file-upload-with-metadata/clientlib/js.txt, add
fileupload-with-metadata.js
5) Create file (nt:file) /apps/eaem-assets-file-upload-with-metadata/clientlib/fileupload-with-metadata.js, add the following code
(function($, $document) { var METADATA_DIALOG = "/apps/eaem-assets-file-upload-with-metadata/dialog.html", METADATA_PREFIX = "eaem", UPLOAD_LIST_DIALOG = "#uploadListDialog", ACTION_CHECK_DATA_VALIDITY = "ACTION_CHECK_DATA_VALIDITY", ACTION_POST_METADATA = "ACTION_POST_METADATA", url = document.location.pathname; if( url.indexOf("/assets.html") == 0 ){ handleAssetsConsole(); }else if(url.indexOf(METADATA_DIALOG) == 0){ handleMetadataDialog(); } function handleAssetsConsole(){ $document.on("foundation-contentloaded", handleFileAdditions); } function handleMetadataDialog(){ $(function(){ _.defer(styleMetadataIframe); }); } function registerReceiveDataListener(handler) { if (window.addEventListener) { window.addEventListener("message", handler, false); } else if (window.attachEvent) { window.attachEvent("onmessage", handler); } } function styleMetadataIframe(){ var $dialog = $("coral-dialog"); if(_.isEmpty($dialog)){ return; } $dialog.css("overflow", "hidden"); $dialog[0].open = true; var $header = $dialog.css("background-color", "#fff").find(".coral-Dialog-header"); $header.find(".cq-dialog-actions").remove(); $dialog.find(".coral-Dialog-wrapper").css("margin","0").find(".coral-Dialog-content").css("padding","0"); registerReceiveDataListener(postMetadata); function postMetadata(event){ var message = JSON.parse(event.data); if( message.action !== ACTION_CHECK_DATA_VALIDITY ){ return; } var $dialog = $(".cq-dialog"), $fields = $dialog.find("[name^='./']"), data = {}, $field, $fValidation, name, value, values, isDataInValid = false; $fields.each(function(index, field){ $field = $(field); name = $field.attr("name"); value = $field.val(); $fValidation = $field.adaptTo("foundation-validation"); if($fValidation && !$fValidation.checkValidity()){ isDataInValid = true; } $field.updateErrorUI(); if(_.isEmpty(value)){ return; } name = name.substr(2); if(!name.indexOf(METADATA_PREFIX) === 0){ return } if(!_.isEmpty(data[name])){ if(_.isArray(data[name])){ data[name].push(value); }else{ values = []; values.push(data[name]); values.push(value); data[name] = values; data[name + "@TypeHint"] = "String[]"; } }else{ data[name] = value; } }); sendValidityMessage(isDataInValid, data); } function sendValidityMessage(isDataInValid, data){ var message = { action: ACTION_CHECK_DATA_VALIDITY, data: data, isDataInValid: isDataInValid }; parent.postMessage(JSON.stringify(message), "*"); } } function handleFileAdditions(){ var $fileUpload = $("coral-chunkfileupload"), $metadataIFrame, $uploadButton, validateUploadButton, metadata; $fileUpload.on('coral-fileupload:fileadded', addMetadataDialog); $fileUpload.on('coral-fileupload:loadend', postMetadata); function sendDataMessage(message){ $metadataIFrame[0].contentWindow.postMessage(JSON.stringify(message), "*"); } function addMetadataDialog(){ _.debounce(addDialog, 500)(); } function addDialog(){ var $dialog = $(UPLOAD_LIST_DIALOG); if(!_.isEmpty($dialog.find("iframe"))){ return; } var iFrame = '<iframe width="550px" height="450px" frameborder="0" src="' + METADATA_DIALOG + '"/>', $dialogContent = $dialog.find("coral-dialog-content"); $metadataIFrame = $(iFrame).appendTo($dialogContent.css("max-height", "600px")); $dialogContent.find("input").css("width", "30rem"); $dialogContent.closest(".coral-Dialog-wrapper").css("top", "30%").css("left", "50%"); addValidateUploadButton($dialog); } function addValidateUploadButton($dialog){ var $footer = $dialog.find("coral-dialog-footer"); $uploadButton = $footer.find("coral-button-label:contains('Upload')").closest("button"); validateUploadButton = new Coral.Button().set({ variant: 'primary' }); validateUploadButton.label.textContent = Granite.I18n.get('Upload'); validateUploadButton.classList.add('dam-asset-upload-button'); $footer[0].appendChild(validateUploadButton); $uploadButton.hide(); validateUploadButton.hide(); validateUploadButton.on('click', function() { checkDataValidity(); }); $metadataIFrame.on('load', function(){ validateUploadButton.show(); }); registerReceiveDataListener(isMetadataValid); } function isMetadataValid(event){ var message = JSON.parse(event.data); if( (message.action !== ACTION_CHECK_DATA_VALIDITY)){ return; } if(message.isDataInValid){ return; } metadata = message.data; validateUploadButton.hide(); $uploadButton.click(); } function checkDataValidity(){ var message = { action: ACTION_CHECK_DATA_VALIDITY }; sendDataMessage(message); } function postMetadata(event){ var detail = event.originalEvent.detail, folderPath = detail.action.replace(".createasset.html", ""), assetMetadataPath = folderPath + "/" + detail.item.name + "/jcr:content/metadata"; //jcr:content/metadata created by the DAM Update asset workflow may not be available when the below post //call executes; ideally, post the parameters to aem, a scheduler runs and adds the metadata when metadata //node becomes available $.ajax({ type : 'POST', url : assetMetadataPath, data : metadata }) } } })(jQuery, jQuery(document));
Hi Sreekanth, if part of the metadata is a pathbrowser field which allows user to select which folder the image should be saved, how do you change the action path dynamically?
ReplyDeleteIn point 6) you mention that the node may not exist. I think this is the case as your sample code never adds the metadata to an asset. Can you point me in the right direction for how to modify this code to actually work and update the asset. Any help is much appreciated. thanks
ReplyDeletegreat
ReplyDelete