Goal
Configure emptyText property in Rich Text Editor (RTE) configuration to show placeholder text before entering content...
Another way is probably using CSS hack like below and setting data-eaem-placeholder attribute on the RTE div (however, it does not show the placeholder when there are empty tags in RTE, with no text content)...
[data-cq-richtext-editable="true"]:empty:before { content:attr(data-eaem-placeholder); color:gray }
Demo | Package Install | Github
Configure emptyText
/apps/core/wcm/components/text/v2/text/cq:dialog/content/items/tabs/items/properties/items/columns/items/column/items/text
emptyText=Experience AEM - This richtext editor is empty, add some text...
Placeholder Text in RTE
Solution
1) Login to CRXDE Lite (http://localhost:4502/crx/de), create folder /apps/eaem-rte-empty-text
2) Create node /apps/eaem-rte-empty-text/clientlib of type cq:ClientLibraryFolder, add String[] property categories with value [cq.authoring.dialog.all], String[] property dependencies with value lodash.
3) Create file (nt:file) /apps/eaem-rte-empty-text/clientlib/css.txt, add
rte-empty-text.css
4) Create file (nt:file) /apps/eaem-rte-empty-text/clientlib/rte-empty-text.css, add the following code
.eaem-rte-placeholder{ color: gray; display: block; }
5) Create file (nt:file) /apps/eaem-rte-empty-text/clientlib/js.txt, add
rte-empty-text.js
6) Create file (nt:file) /apps/eaem-rte-empty-text/clientlib/rte-empty-text.js, add the following code
(function($, $document){ var RTE_SEL = "[data-cq-richtext-editable='true']", DATA_PLACE_HOLDER = "data-eaem-rte-placeholder", PLACE_HOLDER_CSS = "eaem-rte-placeholder"; $document.on("dialog-ready", function(){ $(RTE_SEL).each(addPlaceHolderTextInData); }); $document.on("click", ".cq-dialog-submit", handleBeforeSubmit); function handleBeforeSubmit(e){ e.stopPropagation(); e.preventDefault(); $(RTE_SEL).each(clearPlaceholderText); var $form = $(this).closest("form.foundation-form"), $rteInputs = $form.find("[data-cq-richtext-input='true']"); _.each($rteInputs, function(input){ var $input = $(input), val = $input.val(); if(!val.includes(PLACE_HOLDER_CSS)){ return; } $input.val(getPlaceHolderTextRemovedFromRTEInput(val)); }); $form.submit(); } function getPlaceHolderTextRemovedFromRTEInput(val){ //todo: when there is no text, placeholder is getting saved, find a better way to remove return val.substring(val.indexOf("</div>") + 6); } function addPlaceholderText(){ var $rte = $(this), text = $rte.text().trim(), placeholderText = $rte.attr(DATA_PLACE_HOLDER); if(!placeholderText){ return; } if(text){ $rte.find("." + PLACE_HOLDER_CSS).remove(); }else{ $rte.prepend(getPlaceholder(placeholderText)); } } function clearPlaceholderText(){ $(this).find("." + PLACE_HOLDER_CSS).remove(); } function getPlaceholder(text){ return "<div class='" + PLACE_HOLDER_CSS + "'>" + text + "</div>"; } function addPlaceHolderTextInData(index, rte){ var $rte = $(rte), configPath = $rte.attr("data-config-path"); if(!configPath){ return; } $.ajax(configPath).done(function(data){ var emptyText = data["emptyText"]; if(!emptyText){ return; } $rte.attr(DATA_PLACE_HOLDER, emptyText); $rte.change(addPlaceholderText); $rte.click(clearPlaceholderText); addPlaceholderText.call($rte[0]); }) } }(jQuery, jQuery(document)));
The code is really helpful. Just 1 suggestion, it would be better to use custom value for categories instead of "[cq.authoring.dialog.all]" and add the same in extraClientlibs property of dialog. Using the "[cq.authoring.dialog.all]" might interfere with the existing OOTB JS/JQuery.
ReplyDelete