jQuery .click() Not Executing for Cloned Element - javascript

I'm running into a bug with my code. I am cloning a div so that the user can add multiple customers.
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
var newElem = $('#divInput' + num).clone().attr('id', 'divInput' + newNum); // create the new element via clone(), and manipulate it's ID using newNum value
// clear input value for cloned items and do not remove text for del button.
newElem.find('input:not(.DeleteBtn),textarea').val('');
//newElem.find('input[type="submit"]
// Replace clone num with incremental num.
newElem.find(':input').each(function () {
$(this).attr('id', $(this).attr('id').replace(/\d+/, newNum));
$(this).attr('name', $(this).attr('name').replace(/\d+/, newNum));
});
// insert the new element after the last "duplicatable" input field
$('#divInput' + num).after(newElem);
I have provided a delete button to delete rows and I am using the class name for the button to execute a function on click .
$(".DeleteBtn").click(function () {
alert(".DeleteBtn Click Function - " + $(this).attr('id'));
var DelBtnNum = $(this).attr('id');
DelBtnNum = DelBtnNum[DelBtnNum.length - 1];
$('#divInput' + DelBtnNum).remove();
});
I am able to delete the first (original) input row, but any additional customer rows are not deleted.
I have a running demo of the code located here: http://jsfiddle.net/crjunk/FB4BZ/2/
Why will the cloned items not fire the .DeleteBtn.click function?

You need to use event delegation for supporting dynamic elements.
Since you have used jQuery 1.6 in the fiddle
$(document).delegate(".DeleteBtn", 'click', function () {
alert(".DeleteBtn Click Function - " + $(this).attr('id'));
var DelBtnNum = $(this).attr('id');
DelBtnNum = DelBtnNum[DelBtnNum.length - 1];
$('#divInput' + DelBtnNum).remove();
});
if jQuery >= 1.7
$(document).on('click', ".DeleteBtn", function () {
alert(".DeleteBtn Click Function - " + $(this).attr('id'));
var DelBtnNum = $(this).attr('id');
DelBtnNum = DelBtnNum[DelBtnNum.length - 1];
$('#divInput' + DelBtnNum).remove();
});
Another option is to clone the element along with the event using clone(true)

Because the default when using clone is to not clone events. Try passing true to clone():
var newElem = $('#divInput' + num).clone(true).attr('id', 'divInput' + newNum); // create the new element via clone(), and manipulate it's ID using newNum value
jsFiddle example
As the .clone() docs state:
.clone( [withDataAndEvents ] ) withDataAndEvents (default: false)

When you bound the click event, only one div existed, so it is the only one that has a click handler. You should change your code to use on instead of click.
$(document).on('click', ".DeleteBtn", function () {

try going on with .on('click',function(e){ ... }); or use live() selector (but i think live goes deprecated...)
so in your case
$(".DeleteBtn").on('click',function () { ..

Related

on click fires outside of hyperlink

I am creating a dynamic delete link that as such:
<a id=\"removeAtt__" + i + "\" class=\"remove_button\" style=\"color:#aaa;\"><i class=\"fa fa-times-circle\"></i> remove</a>
I am using the following code once the link is clicked:
$(document).on("click", $('[id*=removeAtt__]'), function () {
var id = event.target.id;
var n = id.lastIndexOf('__');
var result = id.substring(n + 2);
$('#othAtt__' + result).remove();
});
What I am finding is that even when I click outside of the hyperlink at times, it fires the delete. Is there a better way to do this so it fires on click of the hyperlink all the time.
You need to pass a selector, like
$(document).on("click", '.remove-button', function () {
var id = this.id;
var n = id.lastIndexOf('__');
var result = id.substring(n + 2);
$('#othAtt__' + result).remove();
});
And oldschool solution is to define a function to be executed when the button is clicked and call it in the onclick attribute of the tag.
You're selector is not correct so it's actually executing on $(document). This is my preference on writing jQuery selectors:
$('[id*=removeAtt__]').on("click", function () {
var id = $(this).attr('id);
var n = id.lastIndexOf('__');
var result = id.substring(n + 2);
$('#othAtt__' + result).remove();
});
The reason is if my selector is off I don't get a false sense that code is actually working.

domConstruct place button not firing

I am creating table rows dynamically using dojo domConstruct. One of the column contains a button for delete function.But i dont know how to connect onclick event for the delete button. Below is my js code for creating the row.
domConstruct.place("<tr class='test'><td>" +
" Account name"+ XXXX+" "+" Account number is is $" + data1 +
"</td><td><input type ='button' onclick='deleteFunction(this);' value='remove' id=" +
buttonId + "/></td></tr>","tradeInValue","");
So now how i connect it to
on(dom.byId("buttonId"),"click",function(){
// my code goes in here
});
I have no clue here. Basically i need to remove the row from a table on click of a button.
I am using dojo in javascript file.
Updated.
o
n(dom.byId("submitButton"), "click", function(evt){
var name=registry.byId("name").get('value');
var detail = registry.byId("manufacturer").get('value');
var id=registry.byId("model").get('value');
var make=registry.byId("shaft").get('value');
var xhrArgs={
url:"./name/getValue",
content:{name:name,detail:detail,id:id,make:make},
handleAs:"json",
load:function(data){
var data1=data/100;
var row=domConstruct.create("tr",null,"tradeInValue");
domConstruct.create("td",{innerHTML:" Name
"+ detail+" "+id+" Value is $"+data1},row);
var actions=domConstruct.create("td",null,row);
var btn=domConstruct.create("input",{
id:idRow,
type:"button",
value:"Remove"
},actions);
btn.addEventListener("click", function(evt) {
console.log("Deleting");
console.log(evt.target.parentNode.parentNode.idRow);
domConstruct.destroy(evt.target.parentNode.parentNode);
});
var test={
"name" : name,
"detail" : detail,
"id" :id,
"tradePrice" :data,
"make":make
};
tradeDetails.clubDetails.push(test);
}
}
var deferred=dojo.xhrPost(xhrArgs);
}
});
The easiest way is to create your DOM nodes individually, for example:
var row = domConstruct.create("tr", null, "myData");
domConstruct.create("td", { innerHTML: person.id }, row);
domConstruct.create("td", { innerHTML: person.name }, row);
var actions = domConstruct.create("td", null, row);
var btn = domConstruct.create("input", {
type: "button",
value: "Remove"
}, actions);
This allows you to easily attach event handlers to btn, while still preserving context and still having access to the data you're working with, for example:
btn.addEventListener("click", function() {
console.log("Deleting", person);
});
To delete the row itself you could use the Event.target property, which gives you access to the button node itself. If you use the Node.parentNode property, you can eventually access the row itself, and then you can remove it using dojo/dom-construct::destroy()
For example:
btn.addEventListener("click", function(evt) {
domConstruct.destroy(evt.target.parentNode.parentNode);
});
A full example can be found on JSFiddle.

How to create "change" event handlers dynamically?

I create dropdown dynamically.
Their ids are ddl1, ddl2, ddl3 and so on.
$('#ddl1').focus(function() {
var previous = this.value;
}).change(function() {
var index = $(this).find('selected').index();
$('#ddl1').find('option:eq(' + index + ')').hide();
$('#ddl2').find('option:eq(' + index + ')').hide();
});
$('#ddl2').focus(function() {
...
Creation of 7 dropdowns makes me to write 7 change event handlers.
How to implement dynamically create change event?
My dropdown append methods are:
var x=1;
var dropdown=('#ddl1').html();
$('#btnadd').click(function() {
$('#divname').append('<select id="ddl'+x+' > </select> <option>../option>');
x++;
});
Give a common class to every dropdown and refer to that. Also, use .on() (event delegation) to catch dynamic created elements:
$(document).on('change', '.common-class', function() {
//Your function
var currentId = $(this).attr('id');
});
UPDATE
Add the same class every time you append a select element:
//...
$('#divname').append('<select id="ddl'+ x + '" class="common-class"><option>../option></select>');
SELECTED OPTION
In order to get the selected option:
$('#current-id').find('option:selected').index();
Variant without delegated events to reduce resource usage:
var $dds = $('select');
$dds.each(function(index) {
var $this = $(this);
processDdChange($this);
});
function processDdChange($obj) {
$obj.on('change', function(e) {
var $this = $(this);
alert($this.attr('id') + ' | ' + $this.find(':selected').val());
});
}
https://jsfiddle.net/tasmanangel/2p9mbs7h/

Why is my JQuery function not triggered on a cloned element when the event becomes "true"?

I have been making this form that must enable the back-end user to create new questions for users to answer. The form is cloned and appended to a div (selector #content) successfully after the first .on(click) event, but it won't duplicate the form again if the cloned button is pressed. The .on(change) event applied to my drop-down selection does change the content of respective divs like it is supposed to, but only on the original form.
Here's the JQuery code:
$(document).ready(function () {
$('.addAnswer').on("click", function () {
var idx = $('#mp div[name^="antwoord"]:last').index() + 1;
$clone = $('#mp div[name^="antwoord"]:first').clone(true, true).attr('class', 'answer content_' + idx);
$('.removeAnswer').show;
$('#mp').append($clone);
$('.answer:last').each(function () {
$('b:last').empty();
$('b:last').prepend(String.fromCharCode(64 + idx) + ". ")
$('.addAnswer').on("click", function () {
idx++;
});
});
if (idx == 2) {
$('.removeAnswer').show();
}
});
$('.nextq').click(function () {
var newqid = $('#content form:last').index() + 1;
$('.done, .nextq, .remove').hide();
$('#content').append('<hr>');
$('#content').append($('form').html()).attr('class', 'q_' + newqid);
$('.nextq').on("click", function () {
newqid++;
});
$('.done:last, .nextq:last, .remove:last').show();
return false;
});
$('.group').hide();
$('#text:last').show();
$('.select:last').on("change", function () {
$('.group').hide();
$('#' + $(this).val() + ':last').fadeIn();
$('button.' + $(this).val() + ':last').fadeIn();
});
});
Because I thought posting the whole HTML template would be a tad bit too much, I provided a JSFiddle for you people.
One extra question for the ones that are feeling kind: In the JQuery code it is seen that the contents of the HTML are being parsed using .html() and appended with .append.(Line 33 on the JSFiddle) As the .on(change) function switches the contents of the divisions it should change, .html() sees those changes and takes those along with it. I'd like the .on(click) function to append the div's content in its original state, unchanged by the changes made beforehand by the back-end user. Any help with this would be much obliged.
In order to have jQuery trigger on new elements you would do something like
$( document ).on( "click", "<your id or class>", function() {
//Do stuff
});

jQuery Calculate Issue

I am creating an Invoicing System, using jquery.calculate.
var newIDSuffix = 2;
$(".invoice_items").delegate('#add-row', 'click', function () {
var lastRow = $("tr.lastrow");
var cloned = $("tr.default").clone().removeAttr('class');
cloned.find('td#total_item_1').each(function() {
$(this).attr('id', 'total_item_'+2);
});
cloned.find('input, select').each(function() {
var id = $(this).attr('id'),
name = $(this).attr('name');
id = id.substring(0, id.length-1) + newIDSuffix;
$(this).attr('id', id);
});
cloned.insertBefore(lastRow).find('input:text').val('');
newIDSuffix++;
});
// update the plug-in version
$("#idPluginVersion").text($.Calculation.version);
// bind the recalc function to the quantity fields
$("input").bind("keyup", recalc);
// run the calculation function now
recalc();
$("input").bind("keyup", recalc);
// run the calculation function now
recalc();
Here's what I have done so far. http://jsfiddle.net/aliharis/VXZe8/
The problem is once I add a row dynamically, and when I enter the values to it, It doesn't update the amount column and total. But If I enter values for the dynamically added row and go back to first row and enter values, It makes the calculation including the dynamically added fields.
I couldn't figure out whats going wrong.
add the line:
cloned.bind("keyup", recalc);
right after this line:
cloned.insertBefore(lastRow).find('input:text').val('');
to bind a click event to the new element.
.. or alternatively use .on() instead of bind here:
$("input").on("keyup", recalc);

Categories

Resources