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