set event function trigger in looping with jquery - javascript

I would like to ask something about set event trigger with jquery.
First of all, i have a form with many buttons ( btnadd1 , btnadd2, btnadd3 , ... )
I have this code:
for(i=1;i=<3;i++){
$('.btnAdd'+i).click(function(){
alert(i);
});
}
The code should be alert(1) when i click btnadd1 , alert(2) when i click btnadd2,
but the problem is when i click btnadd1, btnadd2, or btnadd3 it alerts "3"
My assumption is that the function overwrites the previous function. Does anyone have a solution for this problem?

This is a common closure issue. You can work around it like this:
$('.btnAdd'+i).click(function(idx){
return function(){alert(idx);};
}(i));
JSFIDDLE

The issue deals with closure inside loop.
Better you could use a user defined attribute in your button and use a single classs for binding the event. see #bipen's answer.
<button class= "someclass" data-value="1"> click</button>
<button class= "someclass" data-value="2">click </button>
$('.someclass').click(function(){
alert($(this).attr('data-value'));
});
Check Fiddle
http://jsfiddle.net/hoja/3jt5furd/5/

Avoid using closure inside a loop...better is to assign a single class to all the buttons and register single event for that..make use of data attributes.
$('.someclass').click(function() {
alert($(this).data('value')); //using jquery's data function
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="someclass" data-value="1">
button1
</button>
<button class="someclass" data-value="2">
button2
</button>
there are other solution to achieve what you want, using attribute selector [class^="btnadd"] and so on but i think this solution is better and readable.

Related

Clicking on image does nothing

I am trying to create a click event for an image using jQuery but I fail every time I try.
First I have a div:
<div id="price-holder"></div>
then I am using jQuery to insert this HTML by using the following:
$("#price-menu li:nth-child(2)").click(function() {
var pregHTML = $("#cakesmash-price").html();
$("#price-holder").html(pregHTML);
});
However, using this HTML doesn't work
<div id="cakesmash-price" style="display:none">
<img id="cake" src="images/order.png" height="32px" onclick="pregbasic(this);">
</div>
I tried to use the attribute onclick for the image and also tried using jQuery's selector with the ID like so
$("#cake").click(function(){
})
but both didn't work.
Can anyone help me?
Thanks
This assumes that the element is actually being added to the page.
I am betting you are adding the click event before you add the element to the page meaning the selector did not find anything so it did not add the event.
Either add the event after you add the element or use event delegation.
$("#price-holder").html(pregHTML);
$("#cake").click(function(){
});
or
$("#price-holder").on("click", "#cake", function () {
});
Your error could be due to your choice of selectors "#price-menu li:nth-child(2)". Try using the JS .children and .eq selectors. Also if your code was added dynamically consider using the .on() event handler rather than the .click().
Just start with the DOM you actually want, without using jQuery to do this:
<div id="price-holder">
<div id="cakesmash-price" style="display:none">
<img id="cake" src="images/order.png" height="32px">
</div>
</div>
Then you can just add you click handler on #cake:
$('#cake').on('click', function (event) {
// your logic goes here
});

Using .each on dynamic objects in jQuery?

There are lots of questions that seem to be asking this, but in the end all they want is to attach .click events and not .each and so the generally accepted answer in all of them include $("body").on("click", ".selector", function(){}); and this is definitely not what I want.
I have some generated inputs and I need to change the value of each one at the same time. Normally I would $(".inputs").each(function(){$(this).val("new-value")}; or something along those lines, however, I can't because of the dynamic aspect.
So how would you do a $("body").on("each", ".inputs", function(){});?
Actually, it's as simple as running the .each inside setTimout.
setTimeout(function(){
$(".inputs").each(function(){$(this).val("new-value")});
}, 5000);
$.each works with any new elements added.
http://jsfiddle.net/4SV7n/
Doing something different each time:
http://jsfiddle.net/4SV7n/1/
Here is much better script that does exactly what the OP asked.
function doWithInput(i, e){
$(e).val("done with each");
}
$(document).ready(function(){
$("#button").click(function(){
$("#inputs").append("<input class='inputs_new' type='text' /><br />");
});
$(".inputs").each(doWithInput);
});
$(document).on("DOMNodeInserted", ".inputs_new", function(e) {
$(e.target).removeClass('inputs_new').addClass('inputs');
doWithInput(0, e.target);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="inputs">
<input class="inputs" type="text" placeholder='type in me' /><br />
</div>
<button type="button" id="button">Add</button>
You can use $(".inputs").each(function(){$(this).val("new-value")}; perfectly fine on dynamic elements. You just need to rerun the script after you added an element dynamically.
From the comments I figured that some misunderstanding exists about 'each'. 'Each' is not an event and so no event is fired if 'each' is called. If you want to keep track of added elements because you have no control over when they are added you'd need a timer:
setInterval(function(){ $(".inputs").each(function(){$(this).val("new-value")}; },500);
What about this:
http://jsfiddle.net/cudts0f2/
I want the dynamically generated text to take effect on each

Linked event listeners using jQuery

I have this HTML structure
<div class="buttons">
<button data-icon="ui-icon-disk" class="save">Save1</button>
<button data-icon="ui-icon-check" class="ok">OK1</button>
<button data-icon="ui-icon-trash" class="delete">Delete1</button>
<button data-icon="ui-icon-close" class="close">Close1</button>
</div>
There are many blocks in the page like this one.
Some buttons come with click handlers functions (save and delete buttons).
What I want to do is: if someone click on an ok button, the corresponding save button click bound function should run.
My code:
$('.save').click(function(){
alert('save');
});
$('.ok').click(function(){
$('.save').click();
});
This is wrong, when I click on a ok button all save buttons fires... not only the one within the same buttons group.
Demo illustrating my problem.
Use $(this).siblings('.save').click() to select only siblings of the clicked button instead of all matching buttons in the whole document.
Demo: http://jsfiddle.net/ThiefMaster/nMnm7/2/
Docs: http://api.jquery.com/siblings/
use siblings
$('.ok').click(function(){
$(this).siblings('.save').click();
});
DEMO
http://api.jquery.com/siblings/
$('.ok').click(function(){
$(this).siblings(".save").click();
});

How to get element by javascript function

Can I select the element by its function?
for example
HTML
<button id="saveButton" onClick="javascript:fnSave(this)>
Save
</button>
then javascript
function fnSave(element){
console.log($(element).attr('id'));
}
clicking the button will result : saveButton
You can do that with using the currentTarget - like this:
save = function(object){
console.log($(object).attr('id'));
}
And, you would call this from your HTML like you mentioned - just including the quote:
<button id="saveButton" onClick="save(this)">Save</button>
To get the element you can do what you just did, add onClick='fnSave(this)' to the button, and on the function:
function fnSave(element){
//the element is in 'element'
}
But I see you are using jQuery, so you can remove the onClick and use this:
$("#saveButton").click(function(event){
var element = $(this);//the element is in 'element'
});
Note: if you are going to use this for multiple different buttons, it would be wise to select them by a clasName instead, or use the first function.
edited

Jquery Click to hide/show div not working

Need to use one single button to toggle the show and hide for div
my code looks something like this
function showTable(number){
$('#div_'+number).show('slow');
$('#button_'+number).html("Hide Table").click(function(){
hideTable(number);
return false;
});
}
function hideTable(number){
$('#div_'+number).hide('slow');
$('#button_'+number).html("Show Table").click(function(){
showTable(number);
return false;
});
}
<div id="div_1" style="display:none"></div>
<button id="button_1" onClick="javascript:showTable(1)">Show Table</button>
<div id="div_2" style="display:none"></div>
<button id="button_2" onClick="javascript:showTable(2)">Show Table</button>
<div id="div_1" style="display:none"></div>
<button id="button_3" onClick="javascript:showTable(3)">Show Table</button>
The function is working fine at first. But after i show and hide it once, whenever I tried to show it again, it starts chaining show/hide/show/hide by itself without any clicks. And the more I do it, the longer it does the chaining. It seems it's just a loop that everytime it doubles the amount of looping(like show/hide for 2/4/8/16/32 times ....) the more I do the longer it loops. Anyone have a clue what's going on?
I tried to remove the click part in the hideTable function, the loop stops but still whenever I try to hit showTable, it will show then hide it self automatically like it's auto executing the stuff in the click function without any clicks...
Also is there anyway to use the jquery tagging style to call the function instead of using onclick? i know I can do like
$("#button_1").click(function(){......................});
$("#button_2").click(function(){......................});
$("#button_3").click(function(){......................});
but is there anyway I can group all of them together into a single function and still able to tell which button is clicked? Because I need a way to track which div to show and hide, and change the the text in corresponding button. Thank you very much in advance. m(_ _)m
You're piling on more and more redundant event handlers with each "click". That's what those calls to ".click()" in the handlers do — add another event handler.
You only need to add an event handler once. And adding an event handler does not remove the prior handler. Since you're using jQuery, use it to add the handlers, not old-fashioned "onclick" attributes.
Give all those <div> elements a class value, like "toggled".
<div id="div_1" style="display:none" class='toggled'>
You can do the same with the buttons. Then you can set up event handlers by using the class to refer to them in a jQuery selector.
A better way to do this is with toggle. Refer to JQuery toggle showhide
you should gove all your divs the same class eg class="toggleable" on the ones you want to toggle.
Then try:
jQuery(".toggleable input[type='button']").click(function()
{
jQuery(this).closest("div.toggleable").toggle();
});
This will put an onlick on your buttons inside your div which will find the closest parent div with class toggleable and will either hide/show your div.
To read about toggle():
http://api.jquery.com/toggle/
to read about selectors:
http://api.jquery.com/category/selectors/
I agree with Pointy but since I can't seem to add onto the answer, I must make another.
$('[data-show-table]').click(function() {
var $this_button = $(this);
$('#div_' + $(this).attr('data-show-table')).toggle(function() {
var msg = $(this).css('display') == 'none' ? 'Show table' : 'Hide table';
$this_button.html(msg);
});
});
<div id="div_1" style="display:none">Table 1</div>
<button id="button_1" data-show-table="1">Show Table</button>
<div id="div_2" style="display:none">Table 2</div>
<button id="button_2" data-show-table="2">Show Table</button>
<div id="div_3" style="display:none">Table 3</div>
<button id="button_3" data-show-table="3">Show Table</button>

Categories