'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)

Reply via email to