A clean simple cross browser editable div.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Simple Editable Div</title>
<style>
div.textarea {
border: solid 1px #ccc;
border-radius: 4px;
height: auto;
line-height: 1.4;
font-size: 14px;
font-family: "Helvetica Neue", arial, sans-serif;
width: 100%;
transition: all 0.15s ease-in-out;
width: 100%;
transition: all 0.15s ease-in-out;
overflow: auto;
word-wrap: break-word;
color: #2a2e2e;
cursor: text;
display: block;
padding: 6px 10px 8px;
min-height: 100px;
}
div.textarea:focus {
outline: none;
box-shadow: 0 0 8px rgba(230, 210, 180, 1);
border-color: #aaa;
}
[contenteditable]:empty:not(:focus):before {
color: #687a86;
line-height: 30px;
font-size: 18px;
content: attr(aria-label);
display: block; /* For Firefox */
}
</style>
</head>
<body>
<div style="width: 800px">
<div contenteditable="true" tabindex="0" role="textbox" aria-multiline="true" data-role="editable" class="textarea plaintext" aria-label="Join the discussion..." id="comment-div" data-target="message"></div>
<input type="hidden" name="message" id="message" value="" />
<button id="submit">Submit</button>
</div>
</body>
<script>
var Haack = (function() {
// NodeList foreach Polyfill
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function(callback, thisArg) {
thisArg = thisArg || window;
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}
// Haack namespace object.
return {
ready: function(init) {
if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) {
window.setTimeout(init);
} else {
var completed = function() {
document.removeEventListener("DOMContentLoaded", completed);
window.removeEventListener("load", completed);
init();
};
document.addEventListener("DOMContentLoaded", completed);
window.addEventListener("load", completed);
}
},
get: function(elementId) {
return document.getElementById(elementId);
}
};
})();
Haack.ready(function() {
document.querySelectorAll("div[contenteditable].plaintext").forEach(function(editor) {
// Set up the content editable div
try {
editor.contentEditable = "PLAINTEXT-ONLY";
} catch (e) {
// Firefox hack to prevent rich text from being pasted.
editor.contentEditable = "true";
editor.addEventListener("paste", function(e) {
e.preventDefault();
if (e.clipboardData && e.clipboardData.getData) {
var text = e.clipboardData
.getData("text/plain")
.replace(/(?:\r\n|\r|\n)/g, "<br />");
document.execCommand("insertHTML", false, text);
} else if (window.clipboardData && window.clipboardData.getData) {
var text = window.clipboardData.getData("Text");
insertTextAtCursor(text);
}
});
}
var targetHiddenInput = Haack.get(editor.dataset.target);
if (targetHiddenInput) {
editor.oninput = e => {
targetHiddenInput.value = e.target.innerText;
};
}
});
});
Haack.ready(function() {
Haack.get("submit").onclick = () => {
alert('The value of the "message" input is ' + Haack.get("message").value);
};
});
</script>
</html>