How do I make a div element editable (like a textarea when I click it)?

JavascriptJquery

Javascript Problem Overview


This is my code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
	"http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
	<head> 
		<meta name="viewport" content="width=device-width, user-scalable=no"> 
	</head> 
<body> 
		<style type="text/css" media="screen"> 

		</style> 
		
		<!--<div id="map_canvas" style="width: 500px; height: 300px;background:blue;"></div>-->

		<div class=b style="width: 200px; height: 200px;background:pink;position:absolute;left:500px;top:100px;"></div>
		<script src="jquery-1.4.2.js" type="text/javascript"></script>
		<script src="jquery-ui-1.8rc3.custom.min.js" type="text/javascript"></script>
		<script type="text/javascript" charset="utf-8"> 

		</script> 
	</body> 
</html>

Thanks

Javascript Solutions


Solution 1 - Javascript

Let's work through it.

You can't make a div editable. There's no such thing as an editable div, at least for now. So the problem is finding out what to use for editing instead. A textarea works perfectly. So the idea is to somehow get a textarea where the div currently sits.

The question is how and from where do we get the textarea. There are various ways, but one of them is to dynamically create a textarea on the fly:

var editableText = $("<textarea />");

and replace it with the div:

$("#myDiv").replaceWith(editableText);

The textarea is in place now. But it is empty and we have just replaced the div and lost everything. So we need to preserve the text of the div somehow. One way is to copy the text/html inside the div before replacing it:

var divHtml = $("#myDiv").html(); // or text(), whatever suits.

Once we have the html from the div, we can populate the textarea and safely replace the div with the textarea. And set the focus inside the textarea as the user might want to start editing. Combining all the work upto this point, we get:

// save the html within the div
var divHtml = $("#myDiv").html();
// create a dynamic textarea
var editableText = $("<textarea />");
// fill the textarea with the div's text
editableText.val(divHtml);
// replace the div with the textarea
$("#myDiv").replaceWith(editableText);
// editableText.focus();

It's functional but nothing happens when a user clicks a div because we didn't setup any events. Let's wire up the events. When the user clicks any div $("div").click(..), we create a click handler, and do all of the above.

$("div").click(function() {
    var divHtml = $(this).html(); // notice "this" instead of a specific #myDiv
    var editableText = $("<textarea />");
    editableText.val(divHtml);
    $(this).replaceWith(editableText);
    editableText.focus();
});

This is good, but we'd want a way to get our div back when a user clicks out or leaves the textarea. There is a blur event for form controls that is triggered when a user leaves the control. That can be used to detect when a user leaves the textarea, and replace back the div. We do the exact reverse this time. Preserve the value of textarea, create a dynamic div, set it's html, and replace out the textarea.

$(editableText).blur(function() {
    // Preserve the value of textarea
    var html = $(this).val();
    // create a dynamic div
    var viewableText = $("<div>");
    // set it's html 
    viewableText.html(html);
    // replace out the textarea
    $(this).replaceWith(viewableText);
});

Everything is great, except that this new div will no longer convert into a textarea on click. This is a newly created div, and we'll have to setup the click event again. We already have the entire code, but better than repeating it twice, it's better to make a function out of it.

function divClicked() {
    var divHtml = $(this).html();
    var editableText = $("<textarea />");
    editableText.val(divHtml);
    $(this).replaceWith(editableText);
    editableText.focus();
    // setup the blur event for this new textarea
    editableText.blur(editableTextBlurred);
}

Since the whole operation is two-way reversible, we'll need to do the same for the textarea. Let's convert that into a function too.

function editableTextBlurred() {
    var html = $(this).val();
    var viewableText = $("<div>");
    viewableText.html(html);
    $(this).replaceWith(viewableText);
    // setup the click event for this new div
    $(viewableText).click(divClicked);
}


Wiring up everything together, we have 2 functions, divClicked, editableTextBlurred and the line below triggers everything:

$("div").click(divClicked);

Checkout this code at http://jsfiddle.net/GeJkU/. This is not the best way of writing editable divs by any means, but just one way to start and approach the solution step by step. Honestly I have learnt just as much as you in writing this long piece. Signing off, adios!

Solution 2 - Javascript

To make a <div> (or any element for that matter) editable you can use the contenteditable HTML attribute.

For example:

<div contenteditable="true">Anything inside this div will be editable!</div>

More info here: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/contenteditable

Solution 3 - Javascript

Use contenteditable="true" attributes for the division.

Solution 4 - Javascript

Based on the answer of Anurag I wrote a small jquery plugin:

https://github.com/zevero/jquery-html-editable

which allows you to make all 'div.myDiv' elements editable:

$('body').html_editable('div.myDiv');

Solution 5 - Javascript

contenteditable has some grave defects. The most damning in my view, is cross browser incompatability on Enter use. See this article for a description. In Firefox clicking Enter for a carriage return creates a new paragraph, effectively double spacing every line that isn't long enough to wrap. Very ugly.

Solution 6 - Javascript

For those looking for an on() version, this is based on Anurag's answer.

If, for some reason, you wanted to take the click event off the editable text input (eg for viewing editable and non editable versions of content), you could later apply $(document).off("click", ".editable_text");.

$(document).on("click", ".editable_text", function() {
  var original_text = $(this).text();
  var new_input = $("<input class=\"text_editor\"/>");
  new_input.val(original_text);
  $(this).replaceWith(new_input);
  new_input.focus();
});

$(document).on("blur", ".text_editor", function() {
  var new_input = $(this).val();
  var updated_text = $("<span class=\"editable_text\">");
  updated_text.text(new_input);
  $(this).replaceWith(updated_text);
});

.text_editor {
  border: none;
  background: #ddd;
  color: #000;
  font-size: 14px;
  font-family: arial;
  width: 200px;
  cursor: text;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p><span class="editable_text">Here is my original text.</span>
</p>

Solution 7 - Javascript

can you try this one

 <!DOCTYPE html>
    <html>
    <body>
    
    <div id="myP">This is a paragraph. Click the button to make me editable.</div>
    
    <button onclick="myFunction()">Try it</button>
    
    <p id="demo"></p>
    
    <script>
    function myFunction() {
        document.getElementById("myP").contentEditable = true;
        document.getElementById("demo").innerHTML = "The p element above is now editable. Try to change its text.";
    }
    </script>
    
    </body>
    </html>

Solution 8 - Javascript

Here's a simple solution:

$('div').click(function(e){
    this.contentEditable = 'true';
});

Working example at https://jsfiddle.net/pgdqhacj/2/. The only downside is that you have to double click to edit the text, not single click.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionzjm1126View Question on Stackoverflow
Solution 1 - JavascriptAnuragView Answer on Stackoverflow
Solution 2 - JavascriptNathanView Answer on Stackoverflow
Solution 3 - JavascriptDevendar RaoView Answer on Stackoverflow
Solution 4 - JavascriptzeveroView Answer on Stackoverflow
Solution 5 - Javascriptross.bendigoView Answer on Stackoverflow
Solution 6 - Javascriptuser1063287View Answer on Stackoverflow
Solution 7 - JavascriptVipin PandeyView Answer on Stackoverflow
Solution 8 - JavascriptPaul Chris JonesView Answer on Stackoverflow