Linked event listeners using jQuery - javascript

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();
});

Related

How to add event listeners using a for loop to dynamically generated buttons

I have a page w/ dynamically generated buttons and i'm trying to add event listeneners to them using a for loop.
I'm not sure why my code is not working as it refers the each button via it's ID and uses dot notation to add the event listener. There is some commenting in the code to help clarify.
Here is abbreviated markup showing the buttons only
<button class="btnRollDice" id="btnRollDiceP1">Roll Dice!</button>
<button class="btnRollDice" id="btnRollDiceP2">Roll Dice!</button>
<button class="btnRollDice" id="btnRollDiceP3">Roll Dice!</button>
Here is the js
rollDiceBtns = document.getElementsByClassName('btnRollDice');//returns a HTML collection
function addEventListeners(){
console.log(rollDiceBtns);
for(i=0;i<rollDiceBtns.length;i++){
console.log(rollDiceBtns[i].id); //THIS WORKS,
rollDiceBtns[i].id.addEventListener('click', rollDice, false); //THIS DOES NOT
}
}
How would this be done using a for loop? to dynamically generated buttons?
addEventListener is a method you find on elements.
rollDiceBtns[i] is an element.
rollDiceBtns[i].id is a string.
Remove .id.

Hide / Show multiple items with Jquery

I have searched around and seem to be getting the same answer to all the people who have asked a similar question so please forgive me if it seems simplistic. I am trying to hide/show multiple items at the same time with the pressing of just one button, and it seems the only way I have come about doing so it by handling it with the class, such as below:
$(document).ready(function(){
$(".btn1").click(function(){
$("p").hide();
});
$(".btn2").click(function(){
$("p").show();
});
});
and the html as follows
<p class="test">If you click on the "Hide" button, I will disappear.</p>
<p class="test">If you click on the "Hide" button, this also disappears.</p>
I dont want to do so using an html selector like
<p>
as in my example because I want to use it for different types of items.
what about using a css class?
$(".btn1").click(function(){
$(".class-to-hide").hide();
});
html
<div class="class-to-hide">
<p>will hide</p>
</div>
<div>
<p class="class-to-hide">will also hide</p>
</div>
there are countless options you could use, just get familiar with your jQuery selectors and take your pick..
you could use class, which is $('.something')
data-target="something", which is $('*[data-target="something"]')
input type="number", which is $('input[type="number"]')
The other option (in addition the answer already presented) is you can use toggle to hide / show (allows you to use 1 button instead of 2):
<p class="test">If you click on the "Hide" button, I will disappear.</p>
<p class="test">If you click on the "Hide" button, this also disappears.</p>
will do both hide and show.
$(document).ready(function(){
$(".btn1").click(function(){
$("p.test").toggle();
});
});
You can use Class Selector (".class")
Selects all elements with the given class.
//It will select all paragraph with the given class
$("p.test").hide();
You should go through all the selectors
Try using the class instead:
$(document).ready(function(){
$(".test").click(function(){
$("p").hide();
});
$(".test").click(function(){
$("p").show();
});
});

set event function trigger in looping with jquery

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.

Is there a general way to specify elements in jquery

Is there a general way to specify elements in jQuery. For example using the $(this).find or next function.
I am trying to create a button that when copied will only activate one at a time.
At the moment when the button is duplicated output is copied.
See example.
http://jsfiddle.net/X8AYd/12/
button
<p class="vote-number">+ 70,101</p> button
<p class="vote-number">+ 70,101</p> button
<p class="vote-number">+ 70,101</p>
$(".vote-number").hide();
$(".vote-btn").click(function () {
$(".vote-number").finish().show().fadeOut(5000);
});
$(".vote-number").finish() will target all the elements with the class vote-number. Instead, you want to target only the element next to the button. So, use $(this).next(".vote-number") to target specifically.
JSFIDDLE DEMO
$(".vote-btn").click(function(){
$(this).next(".vote-number").finish().show().fadeOut(5000);
});
You can do with .next() as using .vote-btn will only target the first occurrance of the same, so better use $(this).next(".vote-number') which targets to the next <p> with class vote-number
$(".vote-btn").click(function(){
$(this).next(".vote-number").finish().show().fadeOut(5000);
});
Fiddle Example
Try This:
$(".vote-btn").click(function(){
$(this).next('.vote-number').finish().show().fadeOut(5000);
});
Working Fiddle
$(".vote-number").hide();
$(document).on("click", ".vote-btn", function (e) {
$(this).prev(".vote-number").show().fadeOut(5000);
});
Working Fiddle

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