I am new to jQuery as well as Web development. 🙂
I want to create a questions creation page. It has a Question Text Box and a Add Button.
When users press the add button, there will be a new Question Text Box and a new Add Button appear in the next line. But the old Add Button will become a Delete Button and change its functionality.
Here is jQuery code:
$(function () {
$(".buttonMinus").hide();
$(".buttonPlus").click(function (event) {
$(this).remove(".buttonPlus");
$(".buttonMinus").show();
$("#p1").append("<p id='p2'>Question: <input type='text'><button type='button' class='buttonPlus'></button></p>"); **// Here !!!!**
alert("Welcome " + $(".ttt").val() + "!");
});
$(".buttonMinus").click(function (event) {
alert("You have pressed the DELETE button!");
});
});
And here is the html code:
<body>
<div class="demo">
<p id="p1">Your name: <input type="text" class="ttt"/>
<button class="buttonPlus" type="button"></button>
<button class="buttonMinus" type="button"></button></p>
<br />
</div>
</body>
I put all the Add Buttons and Minus Buttons into two different classes, “.buttonPlus” and “.buttonMinus”.
The .buttonPlus works well when the line is added by the main html. But it fails to work when it is added by the .append() function. It simply adds the .buttonPlus’s CSS code to its button, but the $(“.buttonPlus”).click(function (event) {…} is NOT attached to the new buttonPlus.
Could you guys tell me why and how I can solve this problem?
Thanks,
Ashley
Welcome to jQuery! This is a common issue. The problem is caused by the fact that the new
.buttonPluselement does not exist at the time when you first bind theclickevent to.buttonPlus. That first time you bind theclickevent, it will only bind to elements that already exist on the page. This is the entire reason why you wrap all your code inside$(function())— it ensures that it does not run until all the DOM elements have been created.There are a few different solutions. The simplest one is to use jQuery’s
.live()method, as Ryan suggests. This will automatically bind the specifiedclickevent to any new.buttonPluselements that get created.However, while this is the simplest solution, it’s also very computationally expensive. I won’t get into the details here, but using
.live()is pretty much never the best option. There is a similar jQuery method called.delegate()which can be used instead. However, while.delegate()is less expensive than.live(), it’s still not the best solution in your case.The best solution, as Diodeus alludes to, is to “re-bind these elements when they’re added.” You could do that in the following way:
As you can see, all we’re doing is putting the code that runs on the
clickevent into a separate function. That allows us to easily bind it to the new button. You would probably want to do a similar thing with your minus buttons as well.