WP-Mix

A fresh mix of code snippets and tutorials

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.

★ Pro Tip:

Wizard’s SQL Recipes for WordPressSAC ProThe Tao of WordPress