Goal
Create a new Asset Metadata Editor Form field and attach Listeners
This post demonstrates adding a new form field to Asset metadata editor using the Metadata Schema feature of AEM 6
Demo | Package Install
Thank you Dave Chang for the PredicateBuilder logic
listeners node added under Serial metadata form field node
keypress listener shows error tooltip when user types-in a space
Solution
1) Add a new form field to Image asset metadata editor by accessing the Metadata schema form of image (http://localhost:4502/libs/dam/gui/content/metadataschemaeditor/schemadetails.html/dam/content/schemaeditors/forms/default/image)
2) Add a new form field Serial with property ./jcr:content/metadata/serial
3) Click done and the form field node can be found under /apps/dam/content/schemaeditors/forms/default/image in CRXDE Lite (http://localhost:4502/crx/de). In my CQ the node got created at /apps/dam/content/schemaeditors/forms/default/image/items/tabs/items/tab1/items/col2/items/1418939382969
4) Add a new node listeners of type nt:unstructured with property
Name: keypress
Type: String
Value: function(event) { ExperienceAEM.textOnly(event) }
5) The keypress event function attached to editor form field Serial executes when user keys-in any character. The javascript function ExperienceAEM.textOnly added in next steps checks for whitespace and shows error tooltip if user tries to enter spaces
6) In CRXDE Lite (http://localhost:4502/crx/de) create folder /apps/touch-ui-metadata-listeners
7) Create node /apps/touch-ui-metadata-listeners/clientlib of type cq:ClientLibraryFolder and add a String property categories with value dam.gui.metadataeditor
8) Create file (nt:file) /apps/touch-ui-metadata-listeners/clientlib/js.txt and add
attach-listeners.js
text-only.js
9) Create file (nt:file) /apps/touch-ui-metadata-listeners/clientlib/attach-listeners.js and add the following code. Here we are reading form fields, querying CRX for any listener nodes and attach event listeners. This is sample code for adding listeners on input elements and not guaranteed to work on every metadata editor element. Based on the form field element type (say select) the code needs to be adjusted...
(function(document, $) { "use strict"; var SCHEMA_EDITOR_PATH = "/apps/dam/content/schemaeditors"; var QUERY_BUILDER = "/bin/querybuilder.json"; var NODE_LISTENERS = "listeners"; var SEARCH_TEXT_IN_LISTENERS = "function"; function PredicateBuilder(defaults) { this.params = $.extend({}, defaults); this.numPredicates = 0; } PredicateBuilder.prototype = { fullText: function(value, relPath) { if (!value) { return this; } this.params[this.numPredicates + '_fulltext'] = value; if (relPath) { this.params[this.numPredicates + '_fulltext.relPath'] = relPath; } this.numPredicates++; return this; }, prop: function(name, value) { if (name && value) { this.params[this.numPredicates + '_property'] = name; if($.isArray(value)) { var that = this; $.each(value, function(i, item) { that.params[that.numPredicates + '_property.' + i + '_value'] = item; }); }else{ this.params[this.numPredicates + '_property.value'] = value; } this.numPredicates++; } return this; }, http: function(){ var builder = this; return $.ajax({ method: 'GET', url: QUERY_BUILDER, data: builder.params }); } }; var attachListeners = function(hits){ if(!$.isArray(hits)){ return; } var $ele; $.each(hits, function(i, hit){ $ele = $("[name='" + hit["name"] + "']"); $.each(hit.listeners, function(key, value){ if(key == "jcr:primaryType"){ return; } try{ $ele.on(key, eval("(" + value+ ")" ) ); }catch(err){ console.log("Error attaching listener : " + key + " - " + value); } }) }); }; $(document).on("foundation-contentloaded", function(e) { var $editables = $(".foundation-field-edit"); if($editables.length == 0 ){ return; } var builder = new PredicateBuilder({ 'path': SCHEMA_EDITOR_PATH, 'p.hits': 'full', 'p.nodedepth': 2, 'p.limit': 100 }); var values = []; $editables.find("input").each(function(i, value){ values.push($(value).attr("name")); }); builder.prop("name", values).fullText(SEARCH_TEXT_IN_LISTENERS, NODE_LISTENERS) .http().done(function(resp) { attachListeners(resp.hits); }); }); })(document, Granite.$);
10) Add the event listener fired on keypress (added in a different js file). Create file (nt:file) /apps/touch-ui-metadata-listeners/clientlib/text-only.js and add the following code
(function() { if (typeof window.ExperienceAEM == "undefined") { window.ExperienceAEM = {}; } var tooltip = null; ExperienceAEM.textOnly = function(event){ if(!tooltip){ tooltip = new CUI.Tooltip({ type: "error", target: event.target, content: "No spaces allowed", visible:false, arrow: "left", interactive: false }); } if(event.which === 32){ tooltip.show(); event.preventDefault(); }else{ tooltip.hide(); } } }());
Hi,
ReplyDeleteI am trying this in AEM 6.4 and it is not working. Can you please help?
Thanks