I’m working on a bit of code for a project at work, and am kind of stumped on a nuance of jQuery. In the following code, It should look down my list and iterate each text input element with the same general name as the last one, but with one number higher in the name. Instead what it’s doing is iterating the name of each text input element with one number higher than the last number that existed when the link was created. So, it should look like a more complicated version of this this:
<input name="industry1" /> <a href="#" class="addField"></a> <!-- Clicked twice -->
<input name="industry2" /> <a href="#" class="addField"></a>
<input name="industry3" /> <a href="#" class="addField"></a>
…And instead, it looks like this:
<input name="industry1" /> <a href="#" class="addField"></a> <!-- Clicked twice -->
<input name="industry2" /> <a href="#" class="addField"></a>
<input name="industry2" /> <a href="#" class="addField"></a>
I think the problem is that the line which selects the value to iterate is set when .live binds to the new add link. So, if the link by the first field creates the button by the second field, and the one by the third field, it acts as if there was still only one field because that’s how it was when .live bound a function to the “click” event. Is there any way to force the selector to figure out what the real $(“form.wizard ul li.industry:last input[type=text]”) in the state of the DOM when the element is clicked is, rather than when it is bound to the element?
<script type="text/javascript">
$(function() {
$("a.addField").live("click", function(event) {
$(this).parents("li").clone().appendTo($("form.wizard > ul"))
.children("input[type=text]").val("").attr("name", function() {
return "industry" + (parseFloat($("form.wizard ul li.industry:last input[type=text]").attr("name").replace("industry", "")) + 1);
})
.after(function() {
if($(this).siblings(".removeField").length == 0) {
return "<a href='#' class='removeField'>Remove</a>"
}
})
.siblings("label").text("");
event.preventDefault();
});
$("a.removeField").live("click", function(event) {
$(this).parents("li").remove();
event.preventDefault();
});
});
</script>
<form action="#" method="post" class="wizard">
<ul>
<li>
<label>Your company name</label>
<input type="text" />
<div class="clear"></div>
</li>
<li class="industry">
<label>Your Industry</label>
<input type="text" name="industry1" />
<a href="#" class="addField left">Add</a>
<div class="clear"></div>
</li>
</ul>
</form>
After rearranging parts of the script, it now seems to work.
The main problem that I identified was, that the fields were appended and immediately selected with
$("form.wizard ul li.industry:last input[type=text]"). That’s why the number was always the clicked element + 1.