Sunday, August 5, 2018

AEM 63 Touch UI Assets Console add Metadata while Uploading Files

AEM 63 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 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
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));

6) #212 is for demo purposes only; in real world implementations, the metadata node created by DAM Update Asset workflow may not exist yet, when the ajax post metadata call executes. Replace this direct call with a servlet temporarily storing the form metadata and update the metadata node (when it becomes available) in a scheduler or listener


visit link download