Add Placeholder to Multiple Child Elements of Contenteditable Div

Edited by Doug Collins, Patrick Murphy, Maria Quinney, Nathan eddings and 3 others

This article will show you how to add placeholder text on multiple child elements within a contenteditable div. This is really handy when you want to have placeholder text on various fields within the contenteditable div.

Problem

Once you set a div to contenteditable='true' the child elements (divs) no longer get input events. This means you don't know when the user has edited a particular element. In this article we will create a way to identify the active element being edited. In addition we will be adding placeholder text that will dissappear when the user types over it.

HTML

<div contenteditable='true' class='editable'>
  <div id='frog' class="frog" child-placeholder='Enter some text 1'><br>
  </div>
  <div style='background:yellow'>
    Some non content editable field is here.  On both sides we have placeholder text you can edit.
  </div>
  <div id='toad' class="toad" child-placeholder='Enter some text 2'>
    <br>
  </div>
</div>

CSS

div[contenteditable]>div[child-placeholder]:not([divPlaceholderContent]):before {
  content: attr(child-placeholder);
  position: absolute;
  font-weight: bold;
  font-size: 14px;
  color: #999;
  
}

.editable {
  padding:5px;
}

Javascript / JQuery

function getActiveDiv() {
  var sel = window.getSelection();
  var range = sel.getRangeAt(0);
  var node = document.createElement('span');
  range.insertNode(node);
  range = range.cloneRange();
  range.selectNodeContents(node);
  range.collapse(false);
  sel.removeAllRanges();
  sel.addRange(range);
  var activeDiv = node.parentNode;
  node.parentNode.removeChild(node);
  return activeDiv;
}

(function($) {
  $(document).on('input', 'div[contenteditable]', function() {
    $(this).find("div[child-placeholder]").each(function() {

      if ($(this).text() != '') {
        if ($(this).attr('id') == getActiveDiv().id) {
          $(this).attr('divPlaceholderContent', 'true'); //hide placeholder
        }
      } else {
        $(this).removeAttr('divPlaceholderContent'); //show placeholder
      }
    });
  });
})(jQuery);

JSFIDDLE with all the code working

Note: I have updated the code in this jsfiddle to support non div elements but I don't have time to update this document. So take a look at the fiddle code.

https://jsfiddle.net/doug99collins/ts4wdynb/

Sources

Not all the code is my own but it is derivatives of chunks of code I found all over the internet.

Add a Simple Placeholder to contenteditable div. (Doesn't handle child placeholder elements.) https://community.idera.com/developer-tools/b/blog/posts/faking-a-placeholder-attribute-for-an-editable-div-and-some-css-tricks

If you have problems with any of the steps in this article, please ask a question for more help, or post in the comments section below.

Comments

Article Info

Recent edits by: Richard, Stephenwalker277, Nathan eddings

Share this Article:

Thanks to all authors for creating a page that has been read 55 times.

x

Thank Our Volunteer Authors.

Would you like to give back to the community by fixing a spelling mistake? Yes | No