Wow. Thank you so much for this explanation, I really appreciate it :)
On Mar 10, 5:35 pm, mkmanning <michaell...@gmail.com> wrote: > '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)