Add Placeholder to Multiple Child Elements of Contenteditable Div

Edited by Doug Collins, Patrick Murphy, Maria Quinney, Nathan eddings and 1 other

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.

Was this helpful? Yes | No| I need help

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.

Was this helpful? Yes | No| I need help

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

Was this helpful? Yes | No| I need help

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

VisiHow welcomes all comments. If you do not want to be anonymous, register or log in. It is free.

Article Info

Recent edits by: Nathan eddings, Maria Quinney, Patrick Murphy

Share this Article:

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