'el' and 'spn' variables are both so we can cache the jQuery object and save having to do the traversal again later in the function; this is generally a good practice from a performance perspective. The 'spn' variable chains the hide() method to the selector, since the selector still returns the jQuery object; this gets us the span element and hides it at the same time.
We then use the find() method on variable 'el' (which is the li element) to get the input with a class of '.wtf' and assign it to the 'edit' variable. If this is the first time a user has double-clicked the li, then the result of that selector will be an empty jQuery object (which will then have a length of 0; the jQuery object is array-like). We check for that with a ternary statement, assigning the result to the 'edit' variable: if we found the input, then we just assign 'edit' to itself, since that's the input, or if we don't find the input we: 1. create it using $('<input>') //note the <>, that tells jQuery to create an element 2. we assign attributes to it with .attr() //in this case the type attribute of text 3. we add the 'wtf' class with .addClass() 4. we append the element to the 'el' variable (the LI in the DOM), using appendTo() //we use appendTo as it allows us to retain the input element and continue chaining jQuery methods 5. we chain the blur() method for handling the onblur event, passing an anonymous function to it. As this function is bound to the input we created, the keyword 'this' inside the function refers to that input. We use the 'spn' variable (the cached SPAN), adding the .text() method and passing it the value of the input. As with hiding the span originally, we can hide the input and get its text value at the same time by wrapping it with $() as $(this).hide().val(). (If we had just wanted the value, we could have simply said 'this.value' without having to resort to jQuery). We then chain the show() method to the 'spn' to make it visible again. Steps 1-5 above are just to create the input and assign the onblur event handler and callback. The last part of the dblcick function assigns the text of the SPAN to the input's value, calls the show() method (if we just created the input it will already be visible when we append it to the LI, so show will just be a no-op, doing nothing). In order to ensure that the input is focused, we access the actual element with [0], the first (and only) element in the jQuery object (remember it's array-like, so you can access its members with [n] notation), and then call the focus () method on it. Note that the latter is different than the jQuery focus() method, which attaches an onfocus() event handler, whereas .focus() on the input element itself simply focuses it (same for blur()) Hope that's all clear :) On Mar 10, 7:54 am, bart <b...@ivwd.nl> wrote: > Thank you both for posting :) > > mkmanning, your code works very well! I'm still somewhat of a noob > with jQuery syntax, care to explain your code a little more thorough? > > //The children of the matched element -filtered down to the span > element- get hidden, what does the ", spn" part do exactly? > var el = $(this), spn = el.children('span').hide(); > > //look for the textfield with the wtf class inside the span > var edit = el.find('input.wtf'); > > //check for edit variable (in other words if a textfield was found in > the span). If not append one with a type="text" attribute to the span > if the blur event is fired on the textfield, something happens but you > lost me there > edit = edit.length>0?edit:$('<input>').attr('type','text').addClass > ('wtf').appendTo(el).blur(function() > { > spn.text($(this).hide().val()).show(); > > }); > > //?? > edit.val(spn.text()).show()[0].focus(); > > On Mar 10, 1:15 am, mkmanning <michaell...@gmail.com> wrote: > > > Typo: last line should be: > > > edit.val(spn.text()).show()[0].focus(); > > > otherwise you'll grab text outside the span. > > > On Mar 9, 5:07 pm, mkmanning <michaell...@gmail.com> wrote: > > > > A couple of notes. Rather than create and then re-create the input and > > > span with every double-click and constantly reattach the blur event, > > > you can just create the input once, and then show/hide the span/input. > > > > Here's a suggested refactoring: > > > > //turn all titles into textfields > > > $('ul li').dblclick(function(){ > > > var el = $(this), spn = el.children('span').hide(); > > > var edit = el.find('input.wtf'); > > > edit = > > > edit.length>0?edit:$('<input>').attr('type','text').addClass > > > ('wtf').appendTo(el).blur(function(){ > > > spn.text($(this).hide().val()).show(); > > > }); > > > edit.val(el.text()).show()[0].focus(); > > > > }); > > > > On Mar 9, 5:00 pm, Hector Virgen <djvir...@gmail.com> wrote: > > > > > Try focusing the text field right after it is created by calling focus() > > > > directly on the element. That's the only way to make sure blur is fired > > > > when > > > > the user clicks somewhere else. > > > > > -Hector > > > > > On Mon, Mar 9, 2009 at 4:18 PM, bart <b...@ivwd.nl> wrote: > > > > > > Hi all, > > > > > > I've set something up which runs at > > > > >http://www.vliegendepijl.nl/pages/test/ > > > > > > As you can see it's an unordered list with some list items in it. If > > > > > you doubleclick the list item the text in it is being replaced by a > > > > > textfield with the same value in it. This works like it should, no > > > > > problems. > > > > > > Now what I'd like to have is that as soon as the field is not focussed > > > > > anymore (blur?) it's should go back to the text in the list item again > > > > > only then with the updated info (assuming the textfield value has been > > > > > changed). This is the point where it doesn't behave as I'd like it to. > > > > > > When I doubleclick the first and immediately after that the second > > > > > they're both left "open", so I guess the blur(). method is not > > > > > completely doing the trick. How can I improve my code so that there > > > > > can be no more than one textfield "open"? > > > > > > Safari 3.2.1 (mac os 10.5) gets it right as it is now, the rest of > > > > > browsers I've tested on all work like I've described. (firefox, opera, > > > > > camino, chrome, IE)