Kent Miller
Kent Miller

Reputation: 509

jQuery: Editing tag only works once

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

Answers (5)

hari
hari

Reputation: 1963

Demo try this,

your viewableText.click(editDiv); not calling your function back.

   viewableText.click(function(){
        editDiv($("#profile_description p"), true);
   });

Upvotes: 0

Warrenn enslin
Warrenn enslin

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

user1103596
user1103596

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

Hugo Sousa
Hugo Sousa

Reputation: 1926

You can use delegated event, switching to

$(document).on('click', '#profile_description p', function() { ... }

Demo

Upvotes: 0

Tommi
Tommi

Reputation: 3247

You replace your p, so click handler don't work anymore. The easiest way to fix it is to use event delegation. Change event handler declaration inside document ready to

$('#profile_description').on('click', "p", function() {

Demo

Upvotes: 1

Related Questions