Tuesday, August 21, 2018
AEM 62 Touch UI Assets Console add Metadata while Uploading Files
AEM 62 Touch UI Assets Console add Metadata while Uploading Files
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 63 check this post
Demo | Package Install
Bug Fixes
Support for Metadata Validity - Demo | Package Install
Bug Fix - Metadata Validity

Metadata Schema
Add a new tab to Image metadata schema form (how-to documentation) for showing the metadata entered while uploading Image assets

Metadata Form in Upload Dialog

Metadata Display

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 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
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"
fieldLabel="Title"
name="./eaemTitle"/>
<alt
jcr_primaryType="nt:unstructured"
sling_resourceType="granite/ui/components/foundation/form/textfield"
fieldDescription="(leave empty to use the title defined above)"
fieldLabel="Alt Text"
name="./eaemAltText"/>
</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, cq.authoring.dialog 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",
ACTION_CHECK_DATA_VALIDITY = "ACTION_CHECK_DATA_VALIDITY",
ACTION_POST_METADATA = "ACTION_POST_METADATA",
url = document.location.pathname,
metadataDialogAdded = false;
if( url.indexOf("/assets.html") == 0 ){
handleAssetsConsole();
}else if(url.indexOf(METADATA_DIALOG) == 0){
handleMetadataDialog();
}
function handleAssetsConsole(){
$document.on("foundation-contentloaded", handleFileAdditions);
}
function handleMetadataDialog(){
$document.on("foundation-contentloaded", styleMetadataIframe);
}
function registerReceiveDataListener(handler) {
if (window.addEventListener) {
window.addEventListener("message", handler, false);
} else if (window.attachEvent) {
window.attachEvent("onmessage", handler);
}
}
function styleMetadataIframe(){
$(".cq-dialog-actions").remove();
registerReceiveDataListener(postMetadata);
function postMetadata(event){
var message = JSON.parse(event.data);
if( (message.action !== ACTION_CHECK_DATA_VALIDITY) && (message.action !== ACTION_POST_METADATA)){
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;
}
});
if(message.action === ACTION_CHECK_DATA_VALIDITY){
sendValidityMessage(isDataInValid);
}else{
$.ajax({
type : POST,
url : message.path,
data : data
})
}
}
function sendValidityMessage(isDataInValid){
var message = {
action: ACTION_CHECK_DATA_VALIDITY,
isDataInValid: isDataInValid
};
parent.postMessage(JSON.stringify(message), "*");
}
}
function handleFileAdditions(){
var $fileUpload = $("coral-chunkfileupload"),
$metadataIFrame, $uploadButton, validateUploadButton;
$fileUpload.on(coral-fileupload:fileadded, addMetadataDialog);
$fileUpload.on(coral-fileupload:loadend, postMetadata);
function sendDataMessage(message){
$metadataIFrame[0].contentWindow.postMessage(JSON.stringify(message), "*");
}
function addMetadataDialog(){
if(metadataDialogAdded){
return;
}
metadataDialogAdded = true;
_.debounce(addDialog, 500)();
}
function addDialog(){
var $dialog = $("coral-dialog-header:contains(Upload)").closest("coral-dialog"),
iFrame = <iframe width="550px" height="450px" 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", "27%").css("left", "40%");
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);
$footer.append(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;
}
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._file.name + "/jcr:content/metadata";
var message = {
action: ACTION_POST_METADATA,
path: assetMetadataPath
};
sendDataMessage(message);
}
}
})(jQuery, jQuery(document));