I have a checklist, where I get a list when I click on a Checkbox. I can check more than one Checkbox - so I get more lists. I add at then end of each list a button, through JQuery. My Code for the button looks like this:
//Add a button to the previous list:
function add() {
$(".list:last").append("<div id='button'><input type='button' class='click' id='feld' name='feld' value='+'/>Add new listfield</div>");
}
When I click on the button, I get a new Checkbox with empty Textfield:
$(document).ready(function() {
// Variables for counting
var utxtname = 0;
var ucheckname = 0;
var utxtid = 1;
var ucheckid = 1;
var uctxtname = 1;
var uccheckname= 1;
//Function for the buttons with the same class ".click"
$(document).on('click', '.click', function() {
var utxtname ='utxtfield'+uctxtname;
var ucheckname ='uchecklist'+uccheckname;
$(this).closest(".list").append("<br><input type='checkbox' name=' "+ucheckname+"' id='"+ucheckid+"' checked><input type='textfield' name ='"+utxtname+"' id='"+utxtid+"'/>");
uctxtname += 1;
uccheckname += 1;
utxtid += 1;
ucheckid += 1;
});
});
My Problem:
When I generate more than one Button, the function triggers multiple times. If I have 3 lists with 3 generated buttons, my function generates 3 buttons if I click on a button. I knew the reason for my mistake. It's because I have 3 buttons with the same class, so it triggers the function multiple times. I just can't figure out how I can solve this problem. I tried so many methods to prevent this. For example unbind the function and bind it again. I also tried to dynamically add button with unique functions, but I couldnt get this.
Any Ideas how can I solve this problem easier?
Use inner function is the simplest solution, but may lead to a memory leak. This is just a more choice.
function add() {
var $button = $("<div id='button'><input type='button' class='click' id='feld' name='feld' value='+'/>Add new listfield</div>");
$(".list:last").append($button);
$button.click(function(){
/*process here*/
});
}
Just for remind, the button may not release , since click function is bound. If you remove in your own code, please add $("button").unbind("click");
Just use Off() in jquery before the on() statement
You can use
e.PreventDefault();
statement to prevent multiple trigger.
Related
I'd like to create a button using HTML. If user click the button, then use javascript to create some elements (like checkboxes). After these, if any of the elements changes, do something, like printing out some text.
Following is my code.
HTML:
<button id="try" type="button">TRY</button>
<div id="boxes"></div>
<p id="demo"></p>
Javascript:
doit = function(){
var checkboxes = "";
for(var i = 0;i<5;i++){
checkboxes += "<input type='checkbox' name='a'/>Option" + i+"<br>";
}
$("#boxes").html(checkboxes);
}
$('#try').click(function(){
doit();
})
$("input[name='a']").on("change",function(){
$("#demo").text("success!")
})
I really can't figure out where I am wrong. Demo:https://jsfiddle.net/slfan/cu7tn64o/12/.
Since you are dynamically adding new elements, you need to use a delegate event handler:
$(document).on("change", "input[name='a']", function() {
$("#demo").text("success!")
})
Updated JSFiddle: https://jsfiddle.net/cu7tn64o/14/
I am making a website that displays profiles of people. Each person is designated a svg button and when that button is clicked, a pop up displays that persons information.
I have this jquery function:
$('.button1').click(function() {
$('.person1-profile').fadeIn();
});
$('.button1-exit').click(function() {
$('.person1-profile').fadeOut();
});
$('.button2').click(function() {
$('.person2-profile').fadeIn();
});
$('.button2-exit').click(function() {
$('.person2-profile').fadeOut();
});
$('.button3').click(function() {
$('.person3-profile').fadeIn();
});
$('.button3-exit').click(function() {
$('.person3-profile').fadeOut();
});
I'm wondering if it is possible to do this with Javascript so that it significantly shortens the coding, and rather than copy & pasting that code every time for each person, if variables can be made for people/profile and so it would be something like:
$('var person + button').click(function() {
$('var person + profile').fadeIn();
});
$('var button + exit').click(function() {
$('var person + profile').fadeOut();
});
Thank you I really appreciate it! Sorry if it is unclear.
You could use data-attributes for this one:
Define your buttons like that:
<button class="openButton" data-person="3">Open</button>
<button class="closeButton" data-person="3">Close</button>
And your open/close-code like that:
$('.openButton').click(function() {
var personNumber = $(this).attr("data-person");
$('.person'+personNumber+"-profile").fadeIn();
});
$('.closeButton').click(function() {
var personNumber = $(this).attr("data-person");
$('.person'+personNumber+"-profile").fadeOut();
});
In action: http://jsfiddle.net/ndx4fn9n/
I can think of few ways of doing it.
You could read only 7th character of the class name. This limits you to having only 10 fields. Or you could put id on very end like this person-profile1 and read 16th and up character.
You could also set up additional tag to your container. But this will cause your web page to not HTML validate.
<div class="person" personid="1">// content</div>
You can do this in your selector:
var buttons = document.getElementsByTagName(svgButtonSelector);
for (i = 0; i > buttons.length; i++) {
$(".button" + index).click(function() {
$(".person" + index + "-profile").fadeIn();
});
}
This will attach the event to every svg button you've got on your page. You just gotta make sure the scope of selection for the buttons is declared right (I'm using document as an example).
I have a row of custom styled radio buttons. On hover, I want a sort icon (two arrows made with css) to appear. I've gotten this to work successfully with jQuery's .hover function. However, when I try to add some logic to only allow the sort arrow to appear when a radio button is NOT checked, the hover event does not work. There's obviously a problem with the if statement; I suspect it's the syntax, but I'm just not sure how to fix it.
JS
// COLUMN HEADING ROLLOVER SORT BUTTONS //
var wrap = "<div class='sortWrap'>";
var sortUp = "<div class='sortIcon arrow-up'></div>";
var sortDown = "<div class='sortIcon arrow-down'></div>";
var combine = wrap + sortUp + sortDown + "</div>";
$('input[type=radio]+label').hover(function() {
var checked = $(this).attr('checked');
if (checked == false) {
$(this).append(combine);
};
}, function() {
$(this).children('.sortWrap').remove();
});
Use $(this).is(':checked') or this.checked.
.prop() vs .attr()
The other problem is that this in your handler is the label element, not the checkbox. You need %(this).prev().is(':checked').
DEMO
So I have EDIT and REMOVE buttons that are dynamically added for each data node (a "poll") in a Firebase database. I have a function which assigns onclick listeners to these with jQuery, but oddly, the event only fires when there just happens to be a single node, and hence a single pair of EDIT/REMOVE buttons. When there are multiple nodes and multiple pairs of buttons, none will fire. Here's the javascript where the events are added to the buttons...
function displayCurrentPollsForEditing(pollsRef)
{
var tbl = createTable();
var th = ('<th>Polls</th>');
$(th).attr('colspan', '3');
$(th).appendTo($(tbl).children('thead'));
pollsRef.once('value', function(pollsSnapshot) {
pollsSnapshot.forEach(function(pollsChild) {
var type = pollsChild.name();
// If this is true if means we have a poll node
if ($.trim(type) !== "NumPolls")
{
// Create variables
var pollRef = pollsRef.child(type);
var pollName = pollsChild.val().Name;
var btnEditPoll = $('<button>EDIT</button>');
var btnRemovePoll = $('<button>REMOVE</button>');
var tr = $('<tr></tr>');
var voterColumn = $('<td></td>');
var editColumn = $('<td></td>');
var rmvColumn = $('<td></td>');
// Append text and set attributes and listeners
$(voterColumn).text(pollName);
$(voterColumn).attr('width', '300px');
$(btnEditPoll).attr({
'class': 'formee-table-button',
'font-size': '1.0em'
});
$(btnRemovePoll).attr({
'class': 'formee-table-remove-button',
'font-size': '1.0em'
});
$(btnEditPoll).appendTo($(editColumn));
$(btnRemovePoll).appendTo($(rmvColumn));
// Append to row and row to table body
$(tr).append(voterColumn).append(editColumn).append(rmvColumn);
$(tr).appendTo($(tbl).children('tbody'));
// Append table to div to be displayed
$('div#divEditPoll fieldset#selectPoll div#appendPolls').empty();
$(tbl).appendTo('div#divEditPoll fieldset#selectPoll div#appendPolls');
$(btnEditPoll).click(function() {
displayPollEditOptions(pollRef);
return false;
});
$(btnRemovePoll).click(function() {
deletePoll($(this), pollsRef);
return false;
});
}
});
});
}
The markup would be something like the following...
<div id="divEditPoll">
<form class="formee" action="">
<fieldset id="selectPoll">
<legend>SELECT A POLL</legend>
<div class="formee-msg-success">
</div>
<div class="grid-12-12" id="appendPolls">
</div>
</fieldset>
</div>
EDIT - So I've switched some lines around and now I don't set the click() events until the buttons are appended to the document, so the button elements are definitely in the DOM when the click events are attached. So could this issue result from not setting id's for these buttons? That seems strange to me, since I'm using variable references rather than ids to attach the events.
There are two things I would check for.
First, make sure you don't have two elements with the same id. If you do, jquery may only bind to the first, or not bind at all.
Second, make sure the element is added to the dom before jquery attempts to bind the click event. If the code is running asynchronously, which can easily happen if you're using ajax, then you may be trying to bind the event before creating the element. Jquery would fail to find the element then give up silently.
you should use .on() for dynamically added button
I am using Select2 which works great. However I am using below code to create new dynamic select2 drop down but they do not react/open when clicking on them.
var relationshipcounter = 0;
$('#AddMoreRelationships').click(function () {
var $relationship = $('.relationship'); // div containing select2 dropdown
var $clone = $relationship.eq(0).clone();
$clone[0].id = 'id_' + ++relationshipcounter;
$relationship.eq(-1).after($clone);
$relationship.find('select').trigger('change'); // not working
});
Screenshot:
JSFIDDLE:
http://jsfiddle.net/pHSdP/133/
I had this exact problem and, of course, the first thing I tried was a deep copy with data:
el.clone(true,true);
Which did not work. Instead the best method I found was:
el=other_el.clone()_etc; // cloning the old row
el.find('.select2-container').remove();
el.find('select').select2({width: 268});
el in both of these snippets is the div row that contains the select and so the Select2 element.
Essentially what I do in the second snippet is remove the "old" select2 which will always have the class of .select2-container and then recreate it on all found select elements within my new row.
You need to call clone with the true argument to copy over events and data as well. Otherwise only the element gets cloned, not the events that are bound to it.
$relationship.eq(0).clone(true);
Docs:http://api.jquery.com/clone/
Ok so issue is resolved, fiddle:
http://jsfiddle.net/WrSxV/1/
// add another select2
var counter = 0;
$('#addmore').click(function(){
var $relationship = $('.relationship');
var $clone = $("#RelationshipType").clone();
$clone[0].id = 'id_' + ++counter;
$clone.show();
$relationship.eq(-1).after($clone);
$clone.select2({ "width" : "200px" });// convert normal select to select2
//$('body').select2().on('change', 'select', function(){
// alert(this.id);
//}).trigger('change');
return false;
});
After cloning your object you have to reassign event for em:
var $clone = $relationship.eq(0).clone();
$clone.on("click", function_name);
Use .on to bind dynamically inserted elements to events like
$('body').on('click','#AddMoreRelationships',function () {
});