making a loop for click function? - javascript

I am trying to make the following functions work continually as a loop as it is to control open panels in an accordion but I can only seem to get this function to run the once to add the class to the initial clicked element (upon 1st click) and once again to remove the class (upon 2nd click) from the element upon clicking another panel in the accordion. Then it no longer adds or removes classes with the click function? Please help, I am pretty new to all this! Thanks
$(document).ready(function() {
$('dt').click(function() {
//alert( "Handler for .click() called." );
$(this).next().andSelf().addClass('.openAcc');
$('dt').click(function() {
$('dt').next().andSelf().removeClass('.openAcc');
});
});
});
basically i want to be able to click on any dt element in the accordion and either turn on or off the previous/current accordions class

You are adding new click handlers every time you click, and they will be active at the same time, one will undo the effect of the other, ...etc.
It often is a bad sign when event handlers are assigned within a handler for the same event.
In fact, jQuery has a nice function for what you want: toggleClass:
$(document).ready(function (){
$('dt').click(function() {
$(this).next().andSelf().toggleClass('.openAcc');
});
});

Instead of worrying about a loop, you can just remove all .openAcc classes, then add it to the current one.
$(document).ready(function (){
$('dt').click(function() {
//alert( "Handler for .click() called." );
$('.openAcc').removeClass('.openAcc');
$(this).next().andSelf().addClass('.openAcc');
});
});
Optimized code with help from #squint

Related

Dynamically created div behavior on button click

I went through many post from SO but not able to relate with my scenario.
I have this code on button click. by which User can create as many div on runtime as he wants to on UI.
$('#adddiv').click(function () {
debugger;
$('#main').append('<div class="ara-dynamic-div">
<div class="box box-solid bg-light-blue-gradient">
</Div></div>');
});
code to get buttonclick event from that div
$(document).on('click', '#remove', function () {
showMakeAndHold(this);
});
function showMakeAndHold(obj) {
alert(obj);
$('.ara-dynamic-div').fadeOut();
}
Now the problem is that I have to create multiple dynamic div. and each div will have button to close itself. When I call this function it will close all created div's instead of the one which button is clicked.
I am not able to find the proper div by which request for close come. I am new to DOM and JQuery. not able to relate the things
First of all, if you're using multiple divs you shouldn't give the close button an ID, but a class instead (let's say, .close)
Next you can use event delegation to find the correct element:
$(document).on('click', '.ara-dynamic-div .close', function( event ) {
$(this).closest('.ara-dynamic-div').fadeOut();
} )
The delegator handles all click events in any .ara-dynamic-div .close button, catching them all and allowing you to use $(this).closest(...) to get to the parent container.
Edit: Corrected a mistake
You can use jQuery's .closest() function.
function showMakeAndHold(obj) {
alert(obj);
$(obj).closest('.ara-dynamic-div').fadeOut();
}
JSFiddle
Replace this:
$(document).on('click', '#remove', function () {
showMakeAndHold(this);
});
by this:
$(document).on('click', '#remove', function () {
$(".ara-dynamic-div").not($(this).parents(".ara-dynamic-div")).fadeOut(function () {
$(this).remove();
});
});
Here is the JSFiddle demo
What the code does is that it remove all other .ara-dynamic-div except the one for which the button was clicked.

jQuery selectors not working with added class

I'm working on a php/jQuery store and have run into the following problem:
I have a few div boxes as articles and as soon as a box is clicked, it is moved into the shopping cart and therefore has to become inactive.
That's my code so far:
$( ".artbox" ).not( ".inactive" ).on('click', function(){
$(this).addClass("inactive");
$(this).find("#artbox").addClass("inactive")
})
It adds the class .inactive to two div objects, which are positioned inside each other. The rest of this function is left out here to keep it short. The problem is that while the according styles for .inactive are applied, I can still click on the box again and again and the function will be called again and again (although I have added the .not() selector) which results in having this specific article in the shopping cart multiple times - and this is what I would like to prevent. If I reload the page manually everything is fine and this
$( ".artbox.inactive" ).on('click', function(){
$(this).effect( "shake", {distance:1});
})
works, too (it doesn't for the items added without reloading).
But I am looking for a solution that works without reloading because I am displaying a popup window with a sucess message after the item was added to the cart.
JSFiddle
I've tried this here https://stackoverflow.com/a/12202186/2842292 but unfortunatly can't get it to work in my example.
Thanks in advance!
You can do it in two ways:
You unregister the event listener upon the click.
You can do it adding this to the event listener: $(this).unbind();,
You add an additional check at the very top of the listener:
if($(this).hasClass("inactive")) return;
Then if it even runs, it will quit and will not do the job.
The eventbinding happens on page load, so you should build the logic in the function:
$( ".artbox" ).on('click', function() {
if ($(this).hasClass("inactive")) {
$(this).effect( "shake", {distance:1});
} else {
$(this).addClass("inactive");
$(this).find("#artbox").addClass("inactive");
}
});

jquery trigger event only once on static and dynamic elements

i need to trigger only one click on specific element that can be on page load time or added dynamically in the future. Some code
This code work just fine for elements that are rendered on load time but wont bind the click event to new elements dynamically added
$(".message-actions .accept").one("click", function(e){
console.log("accept");
});
In the other hand if i do it this way, it will bind the event to new elements but don't unbind the event so if i click it again it will print the same console log
$("body").on("click", ".message-actions .accept", function(e){
console.log("decline");
$(this).unbind("click");
});
At last if i do it in this other way it will only fire the event in the first element i click even if there is more than one loaded or added after.
$("body").one("click", ".message-actions .accept", function(e){
console.log("decline");
});
How can i do this?
Thanks
You can add data to the element that remembers whether the handler has run before:
$("body").on("click", ".message-actions .accept", function() {
if (!$(this).data("run-once")) {
console.log("decline");
$(this).data("run-once", true); // Remember that we ran already on this element
}
});
I would do it this way:
var handleClick = function () {
// do your work
alert("decline");
// unbind
$("body").off("click", ".message-actions .accept", handleClick);
};
$("body").on("click", ".message-actions .accept", handleClick);
Check this fiddle
You can solve it like this, if it suits your situation : http://jsfiddle.net/hu4fp5qs/1/
$("body").on("click",".message-actions .accept",function(){
$(this).removeClass("accept").addClass("decline");
alert("Declined");
});
On click remove class accept and add class decline.
This will help you in styling both the cases differently so that you can distinguish between them.
.accept{
background-color:green;
}
.decline{
background-color:red;
}

D3 remove click events from one element out of a selection

I have a class in D3 say: selectors and I need to remove the click event from the selection
d3.selectAll('.selectors').on('click',function(){
//Remove the currently clicked element from the selection.
});
Ive got two problems:
The removed element is supposed to be moved to a different part of the page and the I need the click event on it to be removed.
Also, would it be possible to reinsert the removed element into the selection on doing something else, like clicking on the removed element again?
Edit:
Found a solution for problem 1
d3.selectAll('.selectors').on('click',function(){
//Remove the currently clicked element from the selection.
d3.select(this).on('click',null);
});
Is this the right way? Or is there a more graceful method?
A Demo Fiddle
here is the updated jquery it will work for your case
$(document).ready(function(){
$(document).on('click','.selectors',function(e){
//$(document).off( 'click','.selectors');
if(e.target.onclick==null)
{
e.target.onclick=
function(){
void(0);
};
alert('test');
console.log('Hello');
}
});
});
For problem 1, the best method(as far as I know) is to redefine the click event in D3 itself:
d3.selectAll('.selectors').on('click',function(){
//Remove the currently clicked element from the selection.
d3.select(this).on('click',null);
});
For problem 2, however, once you turn a click event callback to null, the only way is to redefine the click event again, perhaps recursively:
function clickDefine() {
d3.selectAll('.selectors').on('click', function () {
//Remove the currently clicked element from the selection.
console.log('Hello')
d3.select(this).on('click', null);
setTimeout(function(){clickDefine();},1000)
});
}
This function makes the click event inactive for 1 second on click. And reactivates this again. I'm hoping this is an effective solution.

Trying to toggle a panel whilst changing the icon to 'view more' and 'view less'

I've just started learning jQuery/javascript, so this might seem like a really basic question, but it's annoying me nevertheless.
I have a panel of 6 <li>s, 3 of which are hidden until clicking on the 'view more' link at which point the panel toggles to reveal the other 3. The icon is changing from 'more' to 'less', but then not changing back to 'more'. Can anyone see the problem in the code?
Any help would be greatly appreciated :)
Thanks,
David
$(document).ready(function() {
$('.allApps').hide();
$('.moreAppsIcon').click(function() {
$('.moreAppsIcon').removeClass("moreAppsIcon").addClass("lessAppsIcon");
$(this).toggleClass("active");
$('.allApps').slideToggle("slow");
return false;
});
$('.lessAppsIcon').click(function() {
$('.appsMore').slideToggle("slow", function () {
$('.appsMore').removeClass("appsMore").addClass("moreAppsIcon");
$(this).toggleClass("active");
return false;
});
});
});
It's easier to use .live() here, like this:
$('.moreAppsIcon').live('click', function() {
//and...
$('.lessAppsIcon').live('click', function() {
Otherwise your functions aren't being bound correctly. For example $('.lessAppsIcon') finds elements with that class at that time and binds a click handler to them...elements getting that class later don't get that click handler, whereas .live() works on the selector of the element at the time of the event, having the result you want.
So basically you're attaching n event handlers, one for each element matching initially...when you do .addClass() the other elements don't get that event handler all the sudden, it's on the DOM elements you initially found, not dynamically added to others when they change class. For the same reason .removeClass() doesn't remove the event handler. However, if you use .live() like above, it'll have the effect of changing event handlers like you're after.
I figured it out. It was pretty much what Nick was saying actually to do with the time of the event. I added an id to the <li> to handle the click event. This is what it looks like:
$(document).ready(function() {
$('.allApps').hide();
$('#moreOrLess').click(function() {
$('.allApps').slideToggle("slow", function() {
$('#moreOrLess').toggleClass("moreAppsIcon").toggleClass("lessAppsIcon");
$(this).toggleClass("active");
});
return false;
});
});
Cheers for the help though Nick :)

Categories