views:

30

answers:

1

I have some jQuery code, where you click on text and it changes into an input and when it blurs (looses focus) it changes back to text and visa versa, however on the third call is completely breaks and I have no idea why?

Does someone have any idea?

Code at http://jsfiddle.net/Pezmc/x2fQP/4/

Copy

$(document).ready(function() {
    function editfield() { //Handles swapping to textbox
        var element = $(this);
        alert(element.text());
        element.css('cursor', 'auto');
        element.css('display', 'inline-block');
        element.html('<input type="text" size="25" value="' + element.text() + '" style="width:' + element.width() + 'px;height:' + element.height() + 'px;border:none;padding:0px;margin:0px;">');
        element.children('input').focus();
        $(element).delegate("input", "focus", function() {
            $(element).delegate("input", "blur", function() {
                element.html(element.children('input:text').val());
                element.css('cursor', 'pointer');
                element.one("click", editfield);
            });
        });

    }

    ////////////////////////////////
    $(".field").css('cursor', 'pointer');
    $(".field").one("click", editfield);
});​
+1  A: 

You're assigning another redundant .delegate() handler every time focus handler is called.

Remove the blur delegate from inside the handler.

      // element is already a jQuery object, so no need to wrap it with $()
   element.delegate("input", "focus", function() {
        // do whatever on focus
    })
     .delegate("input", "blur", function() {
            element.html(element.children('input:text').val());
            element.css('cursor', 'pointer');
            element.one("click", editfield);
    });

Also, I'm note sure why you're waiting to assign the handlers until you click.

You may able to assign them right away. Not sure the exact situation here.

If you're trying to swap text for an <input> with each click, then I would just place the .delegate() on the .field once with a click to place the text field, and a blur to replace it with the value of the text.

Something like this:

Your example updated: http://jsfiddle.net/x2fQP/8/

$(document).ready(function() {
    $(".field").css('cursor', 'pointer')

     .click(function() {
        var element = $(this);
          // Consolidated the 2 .css() calls into one by passing an object literal
        element.css({cursor:'auto', display: 'inline-block'});
        element.html('<input type="text" size="25" value="' + element.text() + '" style="width:' + element.width() + 'px;height:' + element.height() + 'px;border:none;padding:0px;margin:0px;">');
        element.children('input').focus();

    })
     .delegate("input", "blur", function() {
        $(this).parent().html(this.value).css('cursor', 'pointer');
    });
});​

Also, I'd recommend having both the text (in a span) and the <input> always present, and just toggle them to show/hide the proper ones.

This would be more efficient, and will remove the need to keep changing the .css() properties.

EDIT:

Ultimately, you'll be better off starting off with the text in its own <span> that is a sibling to the <input>. You simply show/hide the <span> and <input> on a delegate click and blur.

Like this: http://jsfiddle.net/x2fQP/14/

$(document).ready(function() {
    $(".field").delegate('span', 'click', function() {
        var $th = $(this).hide().css('size', "25");
       $th.siblings('input')
           .val($th.text()).show().focus();

    }).delegate("input", "blur", function() {
        $(this).hide()
            .siblings('span')
            .html(this.value).show();
    });
});​

HTML

<div id="thingy" class="field">
    <span>Text field one</span>
    <input type='text' />
</div><br />
patrick dw
If you click on a input more than once your second method wipes the text, me working on fix :-P But many many thanks for your help!
Pez Cuckow
@Pez - Yes it does. :o) I'd place the the text in its own span, and instead of creating/destroying elements, just show and hide them. Here's an example: http://jsfiddle.net/x2fQP/14/
patrick dw