With twitters Bootstrap I've created a button group with radiobox behaviour to let the user choose between the different states. This works out of the box as supposed.
I arranged a jsFiddle with the example here: http://jsfiddle.net/jpxWj/
What I tried (and want) is that the pressed state can be removed when I click the active button second time.
I tried with jQuerys removeClass() to remove the active class from the btn classes but it won't work. (I also tried removing with .on() but this just keeps the active always hidden/removed)
Here you go, quite an unknown event phenomenon, in my opinion. You can read more about it here.
Edit:
To ellaborate, the reason why a simple .removeClass doesn't work, is because there are multiple listeners, listening to the same event. So when the click event is fired, a normal .removeClass would remove the class, but then the Twitter Bootstrap handler would add it again! To prevent any other handlers from being executed after yours, you can do e.stopPropagation. However, this does not stop the handlers attached to the same element as yours, it only stops the ones further up the tree. To completely make sure no other handlers are executed after yours, you can use event.stopImmediatePropagation().
Bootstrap 3 Update:
$('body').on('click', '.btn-group .btn.active',function(e){
e.preventDefault();
e.stopImmediatePropagation();
$(this).find('input').removeAttr('checked');
$(this).removeClass('active');
});
Related
I am using bootstrap5 carousel, and I want to fire a custom event when the previous or next indicators are clicked.
I want to prevent the default bootstrap event from firing. I have tried a bunch of different techniques, but with no success.
Does anyone know how to do this?
Mtia
Check the official documentation. It has some listeners you can add to your JavaScript.
You need to make sure you add the Bootstrap CDN or the npm module with the JavaScript for it to work, though.
Bootstrap Documentation
Example
const myCarousel = document.querySelector("#myCarousel");
const carousel = new bootstrap.Carousel(myCarousel, { interval: 2500 });
myCarousel.addEventListener("slide.bs.carousel", () => { /* Do something... */ });
Have you tried e.stopPropagation() or e.stopImmediatePropagation()
I found the solution in the end. I was programatically placing bs-slide-to on the next and previous indicators, and this was causing the event handler to fire.
So, to stop the bootstrap event handler, remove the bs-slide-to and the bs-slide attributes from the next and previous indicators, and the event won't fire.
I removed that, and used a custom event handler and it works fine (I hope).
I have two lists. I am making it so when you click the first list (instrument), you get a class list based on that instrument.
The first list is pretty clickable and everything seems to be working. But when I click the second list (li) element nothing happens. It seems so far that I can do anything with the second list except for targeting on click i have tried add class and it works but on click doesn't work.
Here's a sample.
The left list onclick works fine but the right one doesn't
Here is a link to the codepen
Link to the Code Pen
Here is the specific code that targets my li element with the class "classList"
$(".classList").on('click',function(){
$(".classList").removeClass("clicked");
$(this).addClass("clicked");
$(".studentInformationView").show();
$("#nameInput").show();
});
The code is too long to put a snippet here so please access the codepen.
Please let me know what's wrong.
Since you are adding your .classList dynamically after the page load you will after to attach your click event differently, as a delegated event.
You can read about jQuery .on() delegated events here.
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time.
Like this:
$(document).on('click', '.classList', function(){
$(".classList").removeClass("clicked");
$(this).addClass("clicked");
$(".studentInformationView").show();
$("#nameInput").show();
});
So attach the event to the document (which will always exist on page load when you are attaching the event), and it will delegate it to the .classList when it gets added at a later time.
Here is an updated CodePen
I have a series of spans (togglers) and a series of divs (toggled). I created a make_toggle function that receives the toggler and its corresponding toggled as arguments.
Everything seems to work kind of ok up to the point where I try to implement a "toggle on click out". What I've tried is to attach to the html click event a function that checks whether the target of the click is contained within the toggled element. On toggle "back", I would then detach the handler so I am only checking when I need.
var check_if_clickingout = function(e) {
if (!toggled[0].contains(e.target)) {
toggle();
}
};
See fiddle: https://jsfiddle.net/andinse/65o211nc/11/
It doesn't even seem to work anymore but when it used to, it was triggering many more times than necessary (which was the reason for me to come here ask for help).
What am I doing wrong? What is the most effective way to go about this kind of situation where I am giving functionality to a series of independent DOM elements?
Just putting this out here that this seems to do the same thing.
$("span").click(function() {
$(this).siblings("div").toggleClass("blue");
});
Maybe I am missing something more that I am not seeing in your example.
See more: http://api.jquery.com/toggleclass/
I've been making some basic mobile navigation and am using a click event to show/hide the menu.
A reduced code sample:
jQuery('.menu-button').click(function(){
jQuery('.header-nav').toggle();
console.log('clicked');
});
I've been remotely debugging on mobile and the console.log always works, but the .header-nav toggle() seems to randomly not trigger - I can't spot a pattern to it, but it always remains in the DOM (which it should), so it being somehow removed is not the reason why it is not firing.
Any ideas?
Thanks to Kevin B's comment it seems that the click event is firing multiple times. To fix this, the following was used:
$(element).off().on('click', function() {
// function body
});
Reference: jQuery click events firing multiple times
I have a fairly large javascript class that generates an complete ajax-generated application. In one version of the ajax page there are a number of dropdown menus. These menus can get created and destroyed at various points during the life cycle of the application.
This is the behaviour I see:
User opens page version 1: no dropdowns
User goes to page version 2: dropdowns added with jQuery onchange event. Work as intended.
User returns to version 1 of page, dropdowns removed.
User returns to version 2 of page, dropdowns added again (using same element IDs)
dropdowns will now have 'double' event handling, triggering the event for each onchange.
The behaviour I'm struggling with is as follows.
On the initial page load, I add an onchange event:
function myClass(){
//Initiate once for current and future elements.
jQuery(document).on('change',".mydropdowns",
function(e){
self.submitDescriptionChange(this);
}
);
}
myClass.prototype.submitDescriptionChange = function (el){
doSomeAjaxStuff();
}
This works fine, except that each time the user goes to pages version 1 and returns to page version 2, the event gets multiplied. Very quickly you can end up with the event firing 20 times per change event, which in this case creates 20 ajax calls.
Logically, by using jQuery.off() I should be able to avoid this. But what happens instead is that the event is removed from both past and future elements, which means that when I recreate page version 2, the dropdowns won't work.
Every way I have tried this (and I've tried LOADS), I either end up with no event firing, or multiple events firing. I cannot seem to find a way to add/replace the elements whereby the event is only ever fired once.
Any ideas how I can solve this?
UPDATED
Yeah, so it turns out I misdiagnosed the problem. It actually came from repeatedly rebinding a 'hashchange' event, rather than rebinding the onchange event. Apologies for misdirection. Moving to bind() function to somewhere where it only executed once fixed the issue.
Since you do not want .off() to remove your events from other pages, I would suggest using namespaces for your events. For example, something like this:
function myClass(pageno) {
var pref_ev = 'mypage' + pageno + '.' + 'change';
$(document).off(pref_ev).on(pref_ev, ".mydropdowns", function(e) {
self.submitDescriptionChange(this);
});
}
This way, each page will have its own "change" event such as "mypage1.change". The event is still registered normally as a change event; the prefix namespace "mypage1" is used to only perform the .off() call on the right events.
I am not sure what plugin you are using for your dropdown menus but there should be a "destroy" method on that plugin. If you call that when removing the dropdowns that should work. Also, if you are only hiding the second page and not actually removing it from the DOM you dont have to re-invoke the plugin as the plugin will still be saved on the element.