Reputation: 509
I want to make a <p>
tag editable by clicking it. My problem: It can only be edited once. After a second click, I get an error message in my console.
See the fiddle here: http://jsfiddle.net/LnD8d/1/
HTML:
<div id="profile_description"><p>Click to add description</p></div>
JAVASCRIPT:
function editDiv(element_to_be_edited, update_description) {
var divHtml = element_to_be_edited.text();
var editableText = $("<textarea />");
editableText.val(divHtml);
element_to_be_edited.replaceWith(editableText);
editableText.focus();
// setup the blur event for this new textarea
editableText.on('blur', function() {
var html = $(this).val();
var viewableText = $("<p>");
viewableText.html(html);
$(this).replaceWith(viewableText);
// setup the click event for this new div
viewableText.click(editDiv);
// if update_description=true, update description ...
if (update_description == true) {
console.log('description has been updated');
}
});
} // /function editDiv();
$(document).ready(function() {
$('#profile_description p').on('click', function() {
console.log('click on p tag');
var element_to_be_edited = $(this);
var update_description = true;
editDiv(element_to_be_edited, update_description);
});
});
Can anyone see the reason why the tag can only be edited once and not on a second click?
Upvotes: 0
Views: 53
Reputation: 1963
Demo try this,
your viewableText.click(editDiv);
not calling your function back.
viewableText.click(function(){
editDiv($("#profile_description p"), true);
});
Upvotes: 0
Reputation: 1036
When you rewire the click event for the new element created in the editDiv, the editDiv function will not have the element_to_be_edited, update_description parameters populated with values. A possible approach would be to have an onclick function that you can use the first time you wire up the click event and then use it again in the editDiv.
function editDiv(element_to_be_edited, update_description) {
var divHtml = element_to_be_edited.text();
var editableText = $("<textarea />");
editableText.val(divHtml);
element_to_be_edited.replaceWith(editableText);
editableText.focus();
// setup the blur event for this new textarea
editableText.on('blur', function() {
var html = $(this).val();
var viewableText = $("<p>");
viewableText.html(html);
$(this).replaceWith(viewableText);
// setup the click event for this new div
viewableText.click(onClick);
// if update_description=true, update description ...
if (update_description == true) {
console.log('description has been updated');
}
});
} // /function editDiv();
function onClick(){
console.log('click on p tag');
var element_to_be_edited = $(this);
var update_description = true;
editDiv(element_to_be_edited, update_description);
}
$(document).ready(function() {
$('#profile_description p').on('click', onClick);
});
Upvotes: 0
Reputation:
When you create the new paragraph, you set up the event listener again using:
viewableText.click(editDiv);
That will call editDiv() with no parameters (i.e. element_to_be_edited
and update_description
will be undefined).
You can do as Tommi suggested, or another option is to simply update the existing element you already had, i.e. on your blur handler, something like:
element_to_be_edited.text(html);
$(this).replaceWith(element_to_be_edited);
element_to_be_edited
will still have the original event handler bound to it, so subsequent clicks will work exactly like the first.
Also means you don't have to create another new DOM element.
Upvotes: 0
Reputation: 1926
You can use delegated event, switching to
$(document).on('click', '#profile_description p', function() { ... }
Upvotes: 0