Replace contenteditable with textarea
Working on my WordPress plugin, Dashboard Widgets Suite, I needed a solid way of replacing contenteditable with a textarea
on form submit. Here is a simple solution along with some bonus notes on dealing with certain HTML tags.
HTML
First, add the following HTML:
<form method="post" action="">
.
.
.
<textarea name="example" class="hidden"></textarea>
<div class="example" contenteditable="true"></div>
.
.
.
</form>
This markup represents your form with a textarea
and contenteditable
div
included. The form can contain whatever else you need, but these two elements are required for this technique. Also make sure that the page includes a hidden class to hide the textarea
. It will be hidden and used only when the form is submitted.
jQuery
Once the HTML is in place, add the following jQuery:
$('form').on('submit', function() {
var textarea = $(this).find('textarea');
var content = $(this).find('.example').text();
textarea.val(content);
});
This jQuery snippet copies the value of the contenteditable
div
to the textarea
when the form is submitted. So whatever content the user adds to the contenteditable
div
will be submitted along with the form via the textarea
.
Notes
When using jQuery’s .text()
function as in the previous technique, HTML tags are preserved only for the first/initial form submission. This is fine for one-time forms, but forms designed for multiple submissions (e.g., content editing forms) will lose the HTML tags if the content is submitted more than once.
Fortunately, using jQuery’s .html()
function escapes and retains the HTML tags. This enables us to enhance our previous jQuery function:
$('form').on('submit', function() {
var textarea = $(this).find('textarea');
var content = $(this).find('.example').html();
var escaped = decode_html(content);
var escaped = remove_tags(escaped, 'textarea');
textarea.val(escaped);
});
..this script calls the following two functions:
function decode_html(html) {
var txt = document.createElement('textarea');
txt.innerHTML = html;
return txt.value;
}
function remove_tags(text, selector) {
var wrapped = $('<div>' + text + '</div>');
wrapped.find(selector).remove();
return wrapped.html();
}
The first of these two extra functions decodes any HTML included in the passed string. The second function removes problematic tags such as textarea
, which otherwise could break page layout.