Create a jQuery event after adding HTML element dynamically - javascript

I have a small script that creates new HTML form elements when a link in clicked via jQuery:
Javascript
var counterx = 2;
var counter = 2;
$(document).ready(function(){
$("#addMoreRcpt").click(function(){
if (counterx>10){
alert("Only 10 reciepients are allowed");
return false;
}
var newTextBoxTr = $(document.createElement('tr')).attr("id", 'RcptEml_' + counter);
newTextBoxTr.append("<td><input type="button" id="txtRcptID_'+ counter + '"></td><td><input type="button" value="Search" id="SearchItem_'+ counter + '">
</td>");
newTextBoxTr.appendTo("#RcptGroup");
counter++;
counterx++;
});
});
HTML
<table border=1>
<div id="RcptGroup">
<tr>
<th>1</th>
<th>2</th>
</tr>
<div id="1">
<tr>
<td><input type="text"></td>
<td><input type="button" value="Search" id="SearchItem_1"></td>
</tr>
</div>
</div>
</table>
<br /><a id="addMoreRcpt" href="#" >Add row</a>
Now for each newly created HTML form, I need to create a new jQuery event so that "Search button" will properly function. Here is the jQuery for the search button:
$("#searchItem_1").on('click', function() {
$("#bg").fadeIn(400, function() {
$("#modal").fadeIn(400);
});
});
$("#modal img").on('click', function() {
var text = $(this).siblings('.descr').text();
$("#modal").fadeOut(400, function() {
$("#bg").fadeOut(400, function() {
$("#txtRcptID_1").val(text);
});
});
});
You see, the script above refers to search_Item_1 button and textbox with id txtRcptID_ID. What I need to accomplish is to create that above script every time a the "Add Row" button is clicked.
But it also needs to have correct seatchItem_# and txtRcpt_# which corresponds to the counter number when a new element is created.
For example: when I click Add Row, and the counter currently at 3, then the script adds new element with id="txtRcptID_3" AND creates a new jQuery event starting like this $("#searchItem_3").on('click', function() {
I have tried and tried and tried but without success. Anyone can help?
EDIT **
I added the following code and got pretty close, but there is still a problem with adding the value from the modal window into the text field. I added an alert function to see the value of the counter, but it mysteriously increases by one when clicking the search button:
newTextBoxRow.appendTo("#RcptGroup");
newTextBoxRow1.appendTo("#RcptGroup");
alert("ID number:"+counter);
$("#searchItem_"+counter).on('click', function(ev){
$("#bg").fadeIn(400, function() {
$("#modal").fadeIn(400);
});
alert("ID number:"+counter);
});
$("#modal img").on('click', function(ev) {
var text = $(this).siblings('.descr').text();
$("#modal").fadeOut(400, function() {
$("#bg").fadeOut(400, function() {
$("#txtRcptID_"+counter).val(text);
});
});
});
counter++;
counterx++;
EDIT 2 **
Here is another try. I changed the id of the search text field to "txt_searchItem_'+ counter +'". And added this code. It functions, but still a problem though. When clicking on an image, it updates ALL text fields instead of just the one that triggered the modal window.
$(document).on('click', '.searchItemBtn', function(ev){
var getID = $(this).attr("id");
alert("ID number:"+getID);
$("#bg").fadeIn(400, function() {
$("#modal").fadeIn(400);
});
$(document).on('click', '#modal img', function(ev
var text = $(this).siblings('.descr').text();
$("#modal").fadeOut(400, function() {
$("#bg").fadeOut(400, function() {
$("#txt_"+getID).val(text);
});
});
});
});

If you want to make on method to attach handlers to elements dynamically created, you should use it like this:
$(parent_selector).on('click', child_selector, function(ev){
// do stuff on click
});
So, in your case, I would add a class to the buttons you are creating, besides the id:
newTextBoxTr.append('<td><input type="button" id="txtRcptID_'+ counter + '"></td><td><input type="button" value="Search" class="button_class" id="SearchItem_'+ counter + '">');
and would attach the handler like this:
$(document).on('click', '.button_class', function(ev){
// do stuff
});

Related

query click event for buttons inside a foreach loop

I am populating a data-table from a model using a foreach loop:
#foreach(var item in Model)
{
<tr>
<td style="display: none">#item.Id</td>
<td>#item.Name</td>
<td>#item.Description</td>
<td>
<div class="btn-group">
<button type="button" class="btn btn-default" data-dismiss="modal">Update</button>
<button type="button" data-id=#item.Id id="Delete" class="btn btn-danger" data-dismiss="modal">Delete</button>
</div>
</td>
</tr>
}
Each row of the table has an update and delete button.
I'm struggling to bind the buttons to a click event using jQuery.
Here is my script so far which is within the document ready function:
var table = $('#productTable').DataTable();
$('#productTable tbody').on('click', 'tr', function () {
var data = table.row(this).data();
alert(Product ID = ' + data[0] + ');
//Call delete function and pass in Id
});
This is understandably showing an alert anytime the user clicks the row. How to I get it to only fire when the delete button is clicked?
Thanks in advance for any help.
You can take doutriforce suggestion and bind the events to a class, for example:
$("#productTable tbody").on("click", ".btn-update", function() {
// Your update code here
// Use $(this) to access the button that triggered this event
}
$("#productTable tbody").on("click", ".btn-delete", function() {
// Your delete code here
// Use $(this) to access the button that triggered this event
}
I've used: $("#productTable tbody").on("click", ", function); because it also works for dynamically added elements (in this case, table rows).
Based on the documentation here, it looks like you need to edit the selector that you bind the click event too, like this:
$('#productTable button#Delete').on('click', function () {
var data = table.row(this).data();
alert(Product ID = ' + data[0] + ');
});
const medias = document.querySelectorAll('._23fpc');
for (let i=1; i<medias.length; i++) {
const media = medias[i];
const firstClickable = media.querySelectorAll('._1JX9L')[1];
if(firstClickable) {
window.setTimeout(() => firstClickable.click(), 50);
}
}
I edited the code copied from the internet, it kind of works
PS:I know nothing about coding

Multiple handlers attached to the same HTML element

I have a simple code. Everytime I click the "Start" button, 3 new buttons with unique IDs and values are created and appended to my div.
For each new button, if I click on it, it alerts the value inside the button. My problem is that if I click the "Start" button 4 times, so there are 12 new buttons created (it's OK), but whenever I click on any newly-created button, it alerts several times (not 1 time as I expect).
I guess the problem is that everytime I click button "Start", a new handler is attached to the button. How to avoid this problem. I have googled for jQuery off(), but it didnt help much. Any help is appreciated very much.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script type="text/javascript">
var count =1;
$( document ).ready(function() {
$('#start').on('click', function(e) {
var i;
for (i=0;i< 3;i++)
{
$('<button id = "Button' + count + '" value = "' + count + '">Button' + count + '</button>').appendTo('#mydiv');
count++;
}
for(i=1;i<= count;i++)
{
$(document).on("click", '#Button' + i , function(){
alert ( $(this).attr('value') );
});
}
});
});
</script>
</head>
<body>
<h1>Test dynamically created button</h1>
<div id = "mydiv">
<button id ="start">START</button>
</div>
</body>
</html>
Your guess is correct. You added handlers several times. This is fix.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script type="text/javascript">
$( document ).ready(function() {
var count = 1; //no need to make it global
$('#start').on('click', function(e) {
var i;
for (i=0;i< 3;i++)
{
$('<button id = "Button' + count + '" value = "' + count + '">Button' + count + '</button>')
.click(function(){//add handler when button created... and never more
alert (this.value);//or $(this).val()
})
.appendTo('#mydiv');
count++;
}
/* here you add handlers more and more times
for(i=1;i<= count;i++)
{
$(document).on("click", '#Button' + i , function(){
alert ( $(this).attr('value') );
});
}
*/
});
});
</script>
</head>
<body>
<h1>Test dynamically created button</h1>
<div id = "mydiv">
<button id ="start">START</button>
</div>
</body>
</html>
If your buttons stay in the DOM (like it seems at the moment), why don't you add the EventListener directly on the new added buttons like this:
$('#start').on('click', function(e) {
var i;
for (i=0;i< 3;i++) {
var myNewButton = $('<button id = "Button' + count + '" value = "' + count + '">Button' + count + '</button>');
myNewButton.appendTo('#mydiv');
myNewButton.on("click", function() {
alert ( $(this).attr('value') );
});
count++;
}
});
Otherwise, as you already guessed in your question, you adding additional Listeners to your existing buttons since you loop through all of them.
At every click on start you create event handlers also for the buttons that are already on the page, meaning they get several handlers attached to them, the more you click on the start button.
Simply add the following handler on document ready (not on click), and it will capture any future button's click if it has an id like Button*:
$(document).on('click', '[id^=Button]', function () {
alert ($(this).attr('value') );
});
Remove the creation of such click handler from the start button's handler.
So the code becomes:
$(document).ready(function() {
var count = 0;
$(document).on('click', '[id^=Button]', function () {
alert ($(this).attr('value') );
});
$('#start').on('click', function(e) {
var i;
for (i=0;i<3;i++) {
$('<button id = "Button' + count + '" value = "' + count + '">Button' + count + '</button>').appendTo('#mydiv');
count++;
}
});
});
So this way, you only have two handlers: one for the start button, and one for all other Button* buttons. No need to dynamically add new handlers.

Appending an element to a cloned element

I have a form with an HTML table that has a button (#addRows) that when clicked will clone the first table row and append it to the bottom of the table.
This table resides in a section of HTML with some other input fields that can also be cloned and appended onto the bottom of my form. When I am cloning the section I am changing all child element ID's to include a number that can be iterated dependent on how many times the user clones the section.
Example
<div id="someID"> ... </div>
<div id="someID2"> ... </div>
<div id="someID3"> ... </div>
I am doing this with JQuery like this
$(function() {
var $section = $("#facility_section_info").clone();
var $cloneID = 1;
$( ".addSection" ).click(function() {
var $sectionClone = $section.clone(true).find("*[id]").andSelf().each(function() { $(this).attr("id", $(this).attr("id") + $cloneID); });
$('#facility_section_info').append($sectionClone);
$cloneID++;
});
});
When I clone the section that holds the table I am also cloning the #addRows button which when clicked should append a table row to the table it is being clicked on. However if I clone my section and I click on my second `#addRows button it will clone my table row but it is appending to my first table and not the second.
Here is my addRows button and event handler
<input type="button" value="+" id="addRows" class="addRows"/>
$(function() {
var $componentTB = $("#component_tb"),
$firstTRCopy = $("#row0").clone();
$idVal = 1;
$(document).on('click', '.addRows', function(){
var copy = $firstTRCopy.clone(true);
var newId = 'row' +$idVal;
copy.attr('id', newId);
$idVal += 1;
copy.children('td').last().append("Remove");
$componentTB.append(copy);
});
});
My question is, when I clone my section of HTML that holds my table and #addButton how can I ensure that when the user clicks on the original button it will clone and append to that table or if I click the cloned button it will clone and append to the cloned table only?
If anything is unclear please let me know so I can try to better explain what I am trying to do, thanks.
Here is a JSFiddle demonstrating the problem I am having.
Because I truly love you BigRabbit, here is where I got to. You will see at least one useful fix here:
var $sectionClone = $section.clone(true);
$sectionClone.find("*[id]").andSelf().each(function () {
$(this).attr("id", $(this).attr("id") + $cloneID);
});
and a fix for an issue you did not report yet
$copy.children('td').last().append(' Remove');
using
$("#facility_section_info").on('click', '.remove', function (e) {
e.preventDefault();
$("#"+$(this).data("removeid")).remove();
});
FIDDLE
$(function () {
var $componentTB = $("#component_tb"),
$firstTRCopy = $("#row0").clone(),
$section = $("#facility_section_info>fieldset").clone(),
$cloneID = 0,
$idVal = 0;
$("#facility_section_info").on('click', '.remove', function (e) {
e.preventDefault();
$("#"+$(this).data("removeid")).remove();
});
$("#facility_section_info").on('click', '.addRows', function () {
$idVal++;
var $copy = $firstTRCopy.clone(true);
var newId = 'row' + $idVal;
$copy.attr('id', newId);
$copy.children('td').last().append(' Remove');
$(this).closest("fieldset").find("tbody").append($copy);
});
$("#facility_section_info").on("click", ".addSection", function () {
$cloneID++;
var $sectionClone = $section.clone(true);
$sectionClone.find("*[id]").andSelf().each(function () {
$(this).attr("id", $(this).attr("id") + $cloneID);
});
$('#facility_section_info').append($sectionClone);
});
});

Jquery click event with popup

i have following code and its not working properly,basically i am willing to add popup on my click event for confirm delete but when i click deleting the row first and then apppear popup,i am stuck and coudn't understand whats going,here is my code
$.fn.matrix.deleteCategory = function ( jqObj ) {
jqObj.find("#award").on('click', ".categoryminus", function () {
var CategoryClass = $(this).closest('tr').attr('class'); // table row Class
//split all class of current table row
var CategoryArray = CategoryClass.split(' ');
//delete all rows having class like C-1-o-1
var categoryClassLike = '[class^=' + CategoryArray[0] + '-o-]';
//for rTenderDocument,check delete c-2,c-3 and appear popup
if ( formType == 'rTenderDocument') {
if ( CategoryArray[0] == 'C-2' ){
$('#priceConfirm').bPopup();
$('.priceConfirm').click(function(){
if($(this).attr('id') == 'priceDeleteNo'){
$('#priceConfirm').bPopup().close();
return false;
} else {
$('#priceConfirm').bPopup().close();
return true;
}
});
} else if ( CategoryArray[0] == 'C-3' ){
$('#fixedAnnualConfirm').bPopup();
$('.fixedAnnualConfirm').click(function(){
if($(this).attr('id') == 'fixedAnnualDeleteNo'){
$('#fixedAnnualConfirm').bPopup().close();
return false;
} else {
$('#fixedAnnualConfirm').bPopup().close();
return true;
}
});
}
}
//remove all child of sub category
$( categoryClassLike ).each(function(){
var obj = $(this);
var subCategoryClass = obj.closest('tr').attr('class'); // table row Class
//split all class of current table row
var subCategoryArray = subCategoryClass.split(' ');
//delete all rows having class like C-1-o-3-So-1
var classLike = '[class^=' + subCategoryArray[0] + '-So-]';
//remove all child of sub category
$( classLike ).each(function(){
$(this).remove();
});
//remove sub category
obj.remove();
});
//after removing child then delete their parent
$(this).closest('tr').remove();
});
return jqObj;
};
I'm not sure what your code does - but I'll give you another
approach to do what you want (based on tables and popup confirmation)
Take a look at this fiddle: JSFiddle Demo
I have created a basic table with rows that contains a del button:
<table>
<tr><td>ID</td><td>NAME</td><td>ACTION</td></tr>
<tr>
<td><div>1</div></td>
<td><div>Booba</div></td>
<td><div><button class='del'>Delete</button></div></td>
</tr>
<tr>
<td><div>2</div></td>
<td><div>Johnas</div></td>
<td><div><button class='del'>Delete</button></div></td>
</tr>
<tr>
<td><div>3</div></td>
<td><div>Coolio</div></td>
<td><div><button class='del'>Delete</button></div></td>
</tr>
</table>
Added a popup container with the message,buttons and hide it:
<div class='popup' id='popup' style='display:none'>
<div>
<p>Please confirm the delete action</p>
<button id='confirm'>Proceed</button>
<button id='cancel'>Cancel</button>
</div>
</div>
Now for the Magic part ~ as yo can see i'm using a variable to store the
row I wish to delete before the popup is displayed and only when the "proceed" button
is clicked this element is removed (otherwise variable is reset and popup removed):
$(function(){
//element to delete:
var ele_del;
// Expose popup message when del button clicked:
$('button.del').click(function(){
event.preventDefault();
$('#popup').fadeIn('slow');
ele_del = $(this).closest('tr');
return false;
});
//delete if proceed clicked:
$('button#confirm').click(function(){
event.preventDefault();
$('#popup').fadeOut('slow',function(){
$(ele_del).find('div').each(function(){
$(this).slideUp('slow',function(){
$(ele_del).remove();
ele_del = "";
});
});
});
return false;
});
//cancel delete operation:
$('button#cancel').click(function(){
event.preventDefault();
$('#popup').fadeOut('slow',function(){
ele_del = "";
});
return false;
});
});
Notes:
I'm using a " DIV " inside the TD's to make the slideUp effect cross-browser. Some browsers won't slideUp the TR's directly.
The entire script is based on the effects callback functions - If you don't want to use effects you can remove the div's and remove the TR directly.
If you use a dynamic table (rows are being added dynamically and not all present on DOM ready) just use the " .on('click' " instead of the .click() I used.
Have fun!

Get a field with jQuery when a button is clicked

I have a table full of appointments. Every appointment has two buttons. One for canceling the event, one for accepting it.
I am struggling to get the appointmentId in the jQuery function when I click on a button. Can you please give me a hint how to do this? The appointmentId is in the table as a hidden input field.
// my html code
<tr>
<td align="left">
<input type="hidden" name="appointmentId" value="234">
John Smith - 14.03.2013 at 9 o'clock
</td>
<td align="right">
<input type="button" id="acceptEvent" class="acceptEvent" value="Accept">
<input type="button" id="cancelEvent" class="cancelEvent" value="Cancel">
</td>
</tr>
// my jQuery code
$("body").delegate('.acceptEvent', 'click', function() {
console.log('accept event clicked');
// get the appointmentId here
});
$("body").delegate('.cancelEvent', 'click', function() {
console.log('cancel event clicked');
// get the appointmentId here
});
Use closest to grab the parent tr element, then select your hidden field.
The reason that this is the correct answer is because it takes the context of the click event with $(this). Then it travels up the DOM tree to your root table row element and selects the child by name. This ensures that you are always in the correct row.
EDIT: I know you already selected an answer, but this was really bothering me that it wasn't working properly. I had to walk down twice using .children() to get it to work though you could also use .find('input[name="appointmentId"]'). Even though you've already selected your answer, I hope this will help you.
$('.acceptEvent').click(function() {
var myVal = $(this).closest('tr').children().children().val();
});
$('.cancelEvent').click(function() {
var myVal = $(this).closest('tr').children().children().val();
});
In the click function, you have access to the button that was clicked with this so you can do:
$("body").on('click', '.cancelEvent', function() {
var input = $(this).closest('tr').find('input[name="appointmentId"]').val();
});
Assuming you have no other IDs or classes to key off of, you can use jQuery's Attribute Equals Selector in reference to the clicked button's parent tr element:
$('.acceptEvent').click(function() {
// get the appointmentId here
var appointmentId = $(this).closest('tr').find('input[name="appointmentId"]').val();
});
I'll do it like that :
$("body").on('.acceptEvent', 'click', function() {
var id = $('input[name="appointmentId"]').val();
//Or search in the parent <tr>
var id = $(this).parent().find('input[name="appointmentId"]').val();
console.log('accept event clicked');
console.log('Id is ' + id);
});

Categories

Resources