Goal
Create a composite multifield comprised of rich text editors (widgets of type cq/gui/components/authoring/dialog/richtext)
For AEM 62 check this post
Demo | Package Install
Solution
1) Login to CRXDE Lite, create folder (nt:folder) /apps/touchui-rte-multifield
2) Create clientlib (type cq:ClientLibraryFolder) /apps/touchui-rte-multifield/clientlib and set a property categories of String type to cq.authoring.dialog, dependencies of type String[] with value underscore
3) Create file ( type nt:file ) /apps/touchui-rte-multifield/clientlib/js.txt, add the following
rte-multifield.js
4) Create file ( type nt:file ) /apps/touchui-rte-multifield/clientlib/rte-multifield.js, add the following code
(function () { var DATA_EAEM_NESTED = "data-eaem-nested"; var CFFW = ".coral-Form-fieldwrapper"; var RTE_CONTAINER = "richtext-container"; function setSelect($field, value){ var select = $field.closest(".coral-Select").data("select"); if(select){ select.setValue(value); } } function setHiddenOrRichText($field, value){ $field.val(value); var $parent = $field.parent(); if(!$parent.hasClass(RTE_CONTAINER)){ return; } $field.next(".editable").empty().append(value); } function setCheckBox($field, value){ $field.prop( "checked", $field.attr("value") == value); } //reads multifield data from server, creates the nested composite multifields and fills them function addDataInFields() { function getMultiFieldNames($multifields){ var mNames = {}, mName; $multifields.each(function (i, multifield) { mName = $(multifield).children("[name$='@Delete']").attr("name"); mName = mName.substring(0, mName.indexOf("@")); mName = mName.substring(2); mNames[mName] = $(multifield); }); return mNames; } function buildMultiField(data, $multifield, mName){ if(_.isEmpty(mName) || _.isEmpty(data)){ return; } _.each(data, function(value, key){ if(key == "jcr:primaryType"){ return; } $multifield.find(".js-coral-Multifield-add").click(); _.each(value, function(fValue, fKey){ if(fKey == "jcr:primaryType"){ return; } var $field = $multifield.find("[name='./" + fKey + "']").last(), type = $field.prop("type"); if(_.isEmpty($field)){ return; } //handle single selection dropdown if(type == "select-one"){ setSelect($field, fValue); }else if(type == "checkbox"){ setCheckBox($field, fValue); }else if(type == "hidden"){ setHiddenOrRichText($field, fValue); }else{ $field.val(fValue); } }); }); } $(document).on("dialog-ready", function() { var $multifields = $("[" + DATA_EAEM_NESTED + "]"); if(_.isEmpty($multifields)){ return; } var mNames = getMultiFieldNames($multifields), $form = $(".cq-dialog"), actionUrl = $form.attr("action") + ".infinity.json"; $.ajax(actionUrl).done(postProcess); function postProcess(data){ _.each(mNames, function($multifield, mName){ buildMultiField(data[mName], $multifield, mName); }); } }); } //collect data from widgets in multifield and POST them to CRX function collectDataFromFields(){ function fillValue($form, fieldSetName, $field, counter){ var name = $field.attr("name"); if (!name) { return; } //strip ./ if (name.indexOf("./") == 0) { name = name.substring(2); } var value = $field.val(); if( $field.prop("type") == "checkbox" ){ value = $field.prop("checked") ? $field.val() : ""; } $('<input />').attr('type', 'hidden') .attr('name', fieldSetName + "/" + counter + "/" + name) .attr('value', value ) .appendTo($form); //remove the field, so that individual values are not POSTed $field.remove(); } $(document).on("click", ".cq-dialog-submit", function () { var $multifields = $("[" + DATA_EAEM_NESTED + "]"); if(_.isEmpty($multifields)){ return; } var $form = $(this).closest("form.foundation-form"), $fieldSets, $fields; $multifields.each(function(i, multifield){ $fieldSets = $(multifield).find("[class='coral-Form-fieldset']"); $fieldSets.each(function (counter, fieldSet) { $fields = $(fieldSet).children().children(CFFW); $fields.each(function (j, field) { fillValue($form, $(fieldSet).data("name"), $(field).find("[name]"), (counter + 1)); }); }); }); }); } $(document).ready(function () { addDataInFields(); collectDataFromFields(); }); })();
This comment has been removed by the author.
ReplyDeleteThanks for the post Sreekanth.
ReplyDeleteCould you please let me know if there is a way to add plugins to the RTE. I tried adding paraformat, styles and special char plugins to the component attached here, but could not see them while editing.
hi Srikanth, can you upload the dialog xml to google drive or dropbox and post the link here....
DeleteHi Sreekanth,
DeleteHere is the dropbox link to touch ui dialog package.
https://www.dropbox.com/sh/ua5sa6h5rczfpnb/AACUTq9rNfX0-C-GoRMUpVcqa?dl=0
you can do something like this for adding plugins to RTE:
Deletehttps://paste.ubuntu.com/24236317/
Hi Sreekanth,
ReplyDeleteI don't see my custom rtePlugin configuration in the dialog
https://www.dropbox.com/s/9281412i90tk95n/Attachment.zip?dl=0
Hi Sreekant , Is it possible to provide the height to the rich text editor ?? how ??
ReplyDeleteDo you have a sightly version? When I try to display the result using sightly, it retains the html characters.
ReplyDeleteHi Jonathan,
DeleteSet the display context to 'html' so that content is free of html tags. For example ${properties.description @ context = 'html'}
Thank you Srikanth. That worked.
DeleteHas anyone been able to get the RTE plugins to appear when the editor is inside of a TouchUI dialog?
ReplyDeleteposted above
Deletei am also not able to see custom RTE plugins
ReplyDeletehow to add paragraph formats of H1 H2 i tried the same way srikant pogula tried but its not coming
ReplyDeletehi, with the cq-6.1.0-featurepack-6563-1.0.0.zip the dialog load dont fill the RTE field. have a fix?
ReplyDeleteHi, ive found your post very useful, but there is a way to add rtePlugins to this richtexts textfields? Because i have already tried a million ways and i cannot achieve any results, if there is a way, could you please show me how to do it?
ReplyDeletemy email is: rgabrielruiz@gmail.com
Hi, I have a rich text field which is part of multi field in classic UI as well as touch UI. When I enter values in rich text field of classic UI, it doesn't load the very same values in rich text editor of touch UI. It remains blank in touch UI.
ReplyDeleteNote: This issue occurs only when the rich text editor is present in multi field.
Any solution for this ?
I am also facing same issue
DeleteThis code is not working for RTE in the multifield. This throws script error with longer execution time and breaks the page
ReplyDeleteThanks to Sreekanth for this sample. We had a requirement of multifield touch ui but data to be persisted as an array of fields rather than separate child nodes. I have modified the library to suit my requirement and available here.
ReplyDeletehttps://drive.google.com/file/d/0B6B1_xLyCcy6cElsblhRTjgyT0k/view?usp=sharing
Sharing if anyone else have similar requirement.
Hi, I used ur shared component but after that classic UI breaks, due u have something which works both on classic as well as touch UI
DeleteHI Sreekanth,
ReplyDeleteIs there any method to restrict the items in the multifield??
Thanks,
Aswathi
Aswathi - http://experience-aem.blogspot.com/2015/11/aem-61-sample-granite-widget-in-touch-ui-extending-multifield-to-limit-items.html
DeleteThanks Sreekanth!!
ReplyDeleteHi Sreekanth,
ReplyDeleteCan you please let me know which AEM this plugin supports, its 6.2 or 6.1