tags:

views:

193

answers:

2

I'm trying to create a new div each time a text field contained in the last div loses focus, but a new div is added only when the text field in the first div loses focus (instead of the last)... Please I need help urgently. Thanks a lot. Here's my code:

    $(function() {
          $(':text:last').blur(function() {
            $('<div class="line"><span>data: </span><input type="text"/></div>')
            .appendTo($('#lineStack'));
        });
    }); 

HTML:

<div id="lineStack">
    <div class="line">
        <span>data: </span><input type="text" />
    </div>
</div>

Answered: Thanks Nick! Your answer worked. I've been trying to mark your post as answer but it's not working. Don't know why :)

+4  A: 

You can do this instead (requires jQuery 1.4+, otherwise blur bubble isn't handled):

$(function() { 
  $(':text:last').live('blur', function() { 
    $('#lineStack').append('<div class="line"><span>data: </span><input type="text"/></div>'); 
  }); 
});

Your current selector gets an element and attaches the event to that element (the others don't exist yet, so it's :last). What you want to do is have the blur fire no matter when the element was added if it's last, .live() will handle that. See here for a working example.

Nick Craver
FYI -- I think using `blur` with `live` requires using jQuery 1.4+
tvanfosson
This looks like it could be it. I'm not that familiar with live though, does it unbind events when the selector is no longer valid for the element?
MiffTheFox
@MiffTheFox - It listens up at the DOM root for the event bubble and executes if the selector matches, so no event actually attaches to the element itself.
Nick Craver
@tvanfosson - Good point, added a disclaimer in there.
Nick Craver
@Nick Ah, okay then. Just a concern that has just been addressed. +1
MiffTheFox
+1  A: 

The selector is only evaluated when the event's assigned. Try something like

$(function() {
    $(':text').live("blur", function() {
        if ($(this).is(':last')){
            $('<div class="line"><span>data: </span><input type="text"/></div>').appendTo('#lineStack');
        }
    }); 
});

That way, every :text gets the event (we use the live function to make sure that it's automatically assigned to new elements when they're created), but we use the is function to make sure that the one selected was really the last one.

(I also got rid of a redundant $ call in the appendTo. jQuery functions like appendTo can take a selector string as a parameter.)

MiffTheFox