How can I prevent an event from finish firing on jquery? - javascript

I'm trying to capture when someone tries to close "edit mode" on a page and tell them to save changes.
What triggers edit mode is a collapse element, first child is "View", second child is "Edit". I also have an event listener attached to the "hide" event of the edit child, so when they click to collapse the edit mode, they will receive a message asking them if they want to continue without saving. Problem is, I ask them, and if they hit continue, everything is fine, but if they hit cancel, I want the edit mode to STOP collapsing, and remain as it is.
I've tried with e.preventDefault, stopImmediatePropagation, return false, nothing works.
HTML:
<div class="accordion" id="my-accordion">
<div class="accordion-group">
<div class="accordion-heading">
<ul class="nav nav-tabs tab-items">
<li id="firstTab" class="active">First</li>
<li id="secondTab">Second</li>
</ul>
</div>
<div id="collapseOne" class="accordion-body collapse in">
</div>
</div>
<div class="accordion-group" id="edit" style="display:none;">
<div class="accordion-heading center">
<a id="edit-toggler" class="accordion-toggle" data-toggle="collapse" data-parent="#my-accordion" href="#collapseTwo">
<i class='icon-arrow-up'></i> Open Edit <i class='icon-arrow-up'></i>
</a>
</div>
<div id="collapseTwo" class="accordion-body collapse">
</div>
</div>
</div>
JavaScript:
$('#batch-edit').on('hide', function () { // THIS IS FOR THE BATCH EDIT BUTTON FUNCTIONALITY
$('#collapseOne').collapse('toggle');
$('#edit-toggler').html("<i class='icon-arrow-up'></i> Open Edit <i class='icon-arrow-up'></i>");
isEdit = false;
if(UserEditing){
if(!confirm('Leave without saving?')) {
return false;
}
}
// DO SOME STUFF
});
Any help would be greatly appreciated.

Unfortunately, there is no native hide/show event you can bind to. This just means we need to trigger these custom events ourselves.
Take a look at this SO answer. Here is the link to the fiddle.
I did something similar to the solution in the answer linked above in order to get beforeHide, afterHide, beforeShow and afterShow events.
The snippet below can demo the events mentioned above.
var $show = $('#show'),
$hide = $('#hide'),
$batchEdit = $('#batch-edit');
$show.hide();
$show.on('click', function()
{
$show.hide();
$hide.show();
$batchEdit.show();
});
$hide.on('click', function()
{
$show.show();
$hide.hide();
$batchEdit.hide();
});
$batchEdit.on('beforeHide', function ()
{
alert('triggered beforeHide');
$show.show();
$hide.hide();
})
.on('afterHide', function ()
{
alert('triggered afterHide');
})
.on('beforeShow', function ()
{
alert('triggered beforeShow');
$show.hide();
$hide.show();
})
.on('afterShow', function ()
{
alert('triggered afterShow');
});
(function($){
$.override ={'show': $.fn.show, 'hide': $.fn.hide};
$.each($.override,function(M,F){
var m=M.replace( /^\w/, function(r){ return r.toUpperCase(); });
$.fn[M] = function(speed, easing, callback) {
var args=[speed||0,easing||'',callback||function(){}];
if( $.isFunction(speed)){
args[2]=speed;
args[0]=0;
}
if( $.isFunction(easing)){
args[2]=easing;
args[1]='';
}
if(!this.selector){
F.apply(this, arguments);
return this;
}
return this.each(function () {
var obj = $(this),
oldCallback = args[args.length-1],
newCallback = function () {
if ($.isFunction(oldCallback)){
oldCallback.apply(obj);
}
obj.trigger('after'+m);
};
obj.trigger('before'+m);
args[args.length-1]=newCallback;
//alert(args);
F.apply(obj,args);
});
}
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="batch-edit">Batch Edit</div>
<input type='button' id="show" value='Show'>
<input type='button' id="hide" value = 'Hide'>

Related

Disable close dropdown after click href

I would like to keep my dropdown opened after a page load. For example if I click on an item(href) into an dropdown, I would like to keep the dropdown opened after the redirection.
I've seen that there is a method jquery named stopPropagation, but it seems that this does not work for me
HTML
<div class="sidenav">
<div class="item_sn">
Groups
</div>
<div class="item_list_body">
<div class="link_sidenav">
<a href="#" class="sub_item">
group 1
</a>
</div>
<div class="link_sidenav">
<a href="#" class="sub_item">
group 2
</a>
</div>
</div>
<div class="item_sn">
Users
</div>
<div class="item_list_body">
<div class="link_sidenav">
<a href="#" class="sub_item">
user 1
</a>
</div>
<div class="link_sidenav">
<a href="#" class="sub_item">
user 2
</a>
</div>
</div>
</div>
JQuery
<script>
$(document).ready(function () {
$('.item_list_body').hide();
$('.item_sn').on('click', function (event) {
var content = $(this).next('.item_list_body')
content.slideToggle();
$('.item_list_body').not(content).slideUp();
});
});
</script>
Solution 1 (not working) :
$(document).on('click', '.sub_item', function (e) {
$(this).parent('.link_sidenav').parent('.item_list_body').toggle();
});
you can use sessionStorage to store the state of the menu and then open the menu on page load by checking the state see below
EDIT
rather than using state of the menu we should save the index of the clicked menu as discussed in the comment so updated my answer
$(document).ready(function () {
//sessionStorage.removeItem('opened');
$('.item_list_body').hide();
if (sessionStorage.getItem('opened') !== null) {
$('.sidenav>div:eq(' + sessionStorage.getItem('opened') + ')').next('.item_list_body').show();
}
$('.item_sn').on('click', function (event) {
var content = $(this).next('.item_list_body');
var elem = $(this);
content.slideDown(0, function () {
sessionStorage.setItem('opened', elem.index());
});
$('.item_list_body').not(content).slideUp();
});
});
Hope it helps

Expand/Collapse several blocks at the same time?

I have several blocks in my page. I use bootstrap 4 alpha 6 version. I want expand/collapse these blocks by clicking one button. Right know I use next js code and it only open all blocks but how to close them?! How to fix this problem?
HTML:
<div class="card">
<div class="card-header">
<button id='expand-collapse' type="button" data-parent="#blocks" data-toggle="collapse" data-target=".block" aria-expanded="false" aria-controls=".block">
</button>
</div>
<div class="card-block">
<div id="blocks">
<div class="list-group">
<div class="list-group-item">
<a data-toggle="collapse" href="#block-1" aria-expanded="false" aria-controls="block-1"OPEN FIRST</a>
<div class="collapse block" id="block-1">
<!--FIRST BLOCK BLOCK-->
</div>
</div>
<div class="list-group-item">
<a data-toggle="collapse" href="#block-2" aria-expanded="false" aria-controls="block-2">OPEN SECOND</a>
<div class="collapse block" id="block-2">
<!--SECOND BLOCK-->
</div>
</div>
<div class="list-group-item">
<a data-toggle="collapse" href="#block-3" aria-expanded="false" aria-controls="block-3">OPEN THIRD</a>
<div class="collapse block" id="block-3">
<!--THIRD BLOCK-->
</div>
</div>
</div>
</div>
</div>
</div>
JAVASCRIPT:
$(function() {
$('#expand-collapse').on('click', function() { // We capture the click event
var target = $(this).attr('data-target'); // We get teh target element selector
$(target).each(function() { // Loop through each element
if ($(this).hasClass('show')) { // Check if it's already visible or not
$(this).collapse('hide'); // Show and hide accordingly
} else {
$(this).collapse('show');
}
});
});
});
$(document).ready(function () {
$('.collapse')
.on('shown.bs.collapse', function(event) {
event.stopPropagation();
$(this)
.parent().parent()
.find(".fa-commenting-o")
.removeClass("fa-commenting-o")
.addClass("fa-commenting");
}).on('hidden.bs.collapse', function(event) {
event.stopPropagation();
$(this)
.parent().parent()
.find(".fa-commenting")
.removeClass("fa-commenting")
.addClass("fa-commenting-o");
});
});
The code that youve used will work as expected in bootstrap3 due to the way collapse was handled then (You can verify it by using JS & CSS of bootstrap V3)
Comming to solving your problem the following snippet would work as expected:
$(function() {
$('#expand-collapse').on('click', function() { // We capture the click event
var target = $(this).attr('data-target'); // We get teh target element selector
$(target).each(function() { // Loop through each element
if ($(this).hasClass('show')) { // Check if it's already visible or not
$(this).collapse('hide'); // Show and hide accordingly
} else {
$(this).collapse('show');
}
});
});
});
TIP:
We can also pass toggle argument to the collapse function and get rid of the if-else condition
$(this).collapse('toggle'); can be used to replace the if-else
But I did not use this in my example to show that you can add additional computation in it
Working Fiddle
UPDATE:
The updated question asks for individual control for the block
To acheive that, we can use the default method of triggering the action with a button element.
<div class="list-group-item">
<div class="collapse block" id="block-1">
FIRST BLOCK
</div>
</div>
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#block-1">
Block 1
</button>
You can find the updated jsFidde here
Add an else statement to handle all other cases that don't match the criteria to show. Try this:
$(function () {
$('#expand-collapse').on('click',function(){
$('[data-toggle="collapse"]').each(function(){
var objectID=$(this).attr('data-target');
if($(objectID).hasClass('.collapse')===false)
{
$(objectID).collapse('show');
} else {
$(objectID).collapse('hide');
}
});
});
});
There is an error with the Bootstrap v4.0.0-alpha.6 version with the transitioning that will be solved on the next release.
See the issue 22256 and pull 21743 links for more information.

Toggle the glyphicon with bootstrap collapse

I have glyphicon-chevron-down when div is in collapsed state,i want to replace it with glyphicon-chevron-up when the div is in collapse in state.I have many of these collapsible divs in my project.So i need to toggle the glyphicon on press of particular collapsibe content(or div).
HTML
<div class="divcontainer">
<span>Click -----></span>
<span class="glyphicon glyphicon-chevron-down" data-toggle="collapse" href="#collapsecontent"></span>
</div>
<div class="collapse" id="collapsecontent">
content
</div>
JavaScript
$(document).ready(function () {
$('.glyphicon-chevron-down').click(function () {
$(this).parent("div").find(".glyphicon-chevron-down")
.toggleClass("glyphicon-chevron-up");
});
});
Fiddle here
Your JS is putting an emphasis on the wrong thing. Find is very slow and best avoided if possible -- and it's very possible here. Just change it to this:
$(document).ready(function () {
$('.glyphicon').click(function () {
$(this).toggleClass("glyphicon-chevron-down").toggleClass("glyphicon-chevron-up");
});
});
JS Fiddle: http://jsfiddle.net/ft4mnynh/
Try the FIDDLE,
I have changed the selectors and events like below
$(document).ready(function () {
$('.divcontainer').click(function () {
$(this).find("span:eq(1)")
.toggleClass('glyphicon-chevron-down')
.toggleClass("glyphicon-chevron-up");
});
});
Hope this helps
Use this below jquery code and just change glyphicon name as you wish
<script>
$('.collapse').on('shown.bs.collapse', function(){
$(this).parent().find(".glyphicon-menu-right").removeClass("glyphicon-menu-right").addClass("glyphicon-menu-down");
}).on('hidden.bs.collapse', function(){
$(this).parent().find(".glyphicon-menu-down").removeClass("glyphicon-menu-down").addClass("glyphicon-menu-right");
});
</script>
You need to toggle both classes chevron-up and chevron-down.
You can find the correct div using the more general glyphicon class.
I also added id to the div, so you don't need to find it by the down class
See: http://jsfiddle.net/amwLaojj/1/
$(document).ready(function () {
$('#myglyph').click(function () {
$(this).parent("div").find(".glyphicon")
.toggleClass("glyphicon-chevron-up")
.toggleClass("glyphicon-chevron-down");
});
});
Update:
Instead of ID, you can use:
$('.glyphicon[data-toggle=collapse]').click(function () {
Updated in: http://jsfiddle.net/amwLaojj/3/
The following code worked for me. As far as I can tell the bootstrap js events only fire on the "div.collapse" element, i.e., the hidden and shown block(s). Even the jquery "click" event on "div.panel-heading" or any child was unresponsive.
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
Getting Started
<span class="glyphicon glyphicon-menu-right" aria-hidden="true"></span></a></h4>
</div>
<div id="collapseOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<a id="choosing">Choosing a topic</a>
<a id="exploring">Exploring a topic</a>
</div></div>
JQuery
$(document).ready(function () {
$('div.collapse').on("show.bs.collapse || hide.bs.collapse", function () {
let glyph = $(this).siblings("div.panel-heading").find('span.glyphicon');
glyph.hasClass("glyphicon-menu-right") ? glyph.toggleClass("glyphicon-menu-down") : glyph.toggleClass("glyphicon-menu-right");
});
});

Quicksand.js interfering with Bootstrap Modals

I've been trying to make a lightbox portfolio using the Bootstrap Modal functions, with the quicksand sorting plug-in. I originally followed this tutorial which I had to work with a little to get to work in Bootstrap 3.0.0 (the version I'm using), but it was working. I decided I needed more control over the modal boxes so I took out the bootbox plug-in and just used the modal js that comes in bootstrap. Now when I press the thumbnail the modal box pops up fine, but if I press one of the sorting nav buttons, the box will pop up with either the last image that was in the modal (not the correct one) or if the first thing you do is sort then click, the modal box pops up but it is empty. The tutorial mentioned the problem and a work-around:
"Inherently, Quicksand will nullify Bootstrap’s modal feature as soon
as you interact with any of the categories. That is, the modal works
before firing Quicksand, but not after. However, we’ve easily avoided
this issue by defining our Bootbox function earlier. As shown above,
we then used “gallery” as an attribute inside the quicksand() function
and setup $(document).ready(gallery);. Now modal will work as expected
both before and after selecting a filter/category."
but it doesn't seem to work with the normal bootstrap modal. The only similar question I could find is this one, the answer was to add a call-back, since the objects sorted by quicksand are actually new objects that have not been affected by the modal script, but when I added the callback it didn't work.
here is my code (I left out all the other thumbnails)
<div class="container well well-lg">
<ul class="filter nav nav-pills">
<li data-value="all"><h6>All</h6></li>
<li data-value="Historical"><h6>Historical</h6></li>
...
</ul>
<hr>
<ul class="thumbnails">
<li class="col-lg-2 col-md-2 col-sm-3 col-xs-4" data-id="id-1" data-type="Historical">
<a class="thumbnail" data-toggle="modal" data-target="#myModal" id="joan1" href="#" data-image-id="" data-title="Joan of Arc" data-caption="Digital, Junior Thesis subject Crime and Punishment, 2015" data-image="/images/joan1.png">
<img alt="" src="/images/thumb_joan1.png"></a>
</li>
...
</ul>
</div>
<!-- Modal -->
<div class="modal modal-wide fade" id="myModal" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3 class="modal-title" id="myModal-title"></h3>
</div>
<div class="modal-body">
<img id="myModal-image" class="img-responsive" src="">
</div>
<div class="modal-footer">
<div class="col-md-2">
<button type="button" class="btn btn-primary" id="show-previous-image">Previous</button>
</div>
<div class="col-md-8 text-justify" id="myModal-caption">
</div>
<div class="col-md-2">
<button type="button" id="show-next-image" class="btn btn-default">Next</button>
</div>
</div>
</div>
</div>
</div>
and here is my javascript
<script src="/Scripts/jquery.quicksand.js" type="text/javascript"></script>
<script>
$(document).ready(function () {
loadGallery(true, 'a.thumbnail');
$(".modal-wide").on("show.bs.modal", function () {
var height = $(window).height() - 200;
$(this).find(".modal-body").css("max-height", height);
});
function disableButtons(counter_max, counter_current) {
$('#show-previous-image, #show-next-image').show();
if (counter_max == counter_current) {
$('#show-next-image').hide();
} else if (counter_current == 1) {
$('#show-previous-image').hide();
}
}
function loadGallery(setIDs, setClickAttr) {
var current_image,
selector,
counter = 0;
$('#show-next-image, #show-previous-image').click(function () {
if ($(this).attr('id') == 'show-previous-image') {
current_image--;
} else {
current_image++;
}
selector = $('[data-image-id="' + current_image + '"]');
updateGallery(selector);
});
function updateGallery(selector) {
var $sel = selector;
current_image = $sel.data('image-id');
$('#myModal-caption').text($sel.data('caption'));
$('#myModal-title').text($sel.data('title'));
$('#myModal-image').attr('src', $sel.data('image'));
disableButtons(counter, $sel.data('image-id'));
}
if (setIDs == true) {
$('[data-image-id]').each(function () {
counter++;
$(this).attr('data-image-id', counter);
});
}
$(setClickAttr).on('click', function () {
updateGallery($(this));
});
};
function gallery() {
}
var $itemsHolder = $('ul.thumbnails');
var $itemsClone = $itemsHolder.clone();
var $filterClass = "";
$('ul.filter li').click(function (e) {
e.preventDefault();
$filterClass = $(this).attr('data-value');
if ($filterClass == 'all') { var $filters = $itemsClone.find('li'); }
else { var $filters = $itemsClone.find('li[data-type=' + $filterClass + ']'); }
$itemsHolder.quicksand(
$filters,
{ duration: 1000 },
loadGallery
);
});
});
$holder.quicksand($filteredData, {
duration: 800,
easing: 'easeInOutQuad'
}, gallery);
$(document).ready(gallery);
</script>
and here is the live page where you can see the problem. I'm pretty new to this so hopefully I just messed up something basic and fixable. Thanks in advance for any help!
Hi your thumbnail click event does not trigger after filtering, when filtering you are creating a clone of the elements and adding them to back to the DOM, Therefore your trying to bind a click event to elements that are not on the page yet, to fix bind to an element that's is always on the page, then use your variable 'setClickAttr' for the Selector filter
i.e change
$(setClickAttr).on('click', function () {
....
});
to
$(document).on('click', setClickAttr, function() {
....
});
This Turning live() into on() in jQuery talks more about binding to elements that must exist first

How to hide my collapse bootstrap 3 navbar with click on body when, collapse is visible?

I'm making a WordPress website for agency where I will go work.
I used Bootstrap 3.0, and I created a responsive menu.
How to hide menu when is collapsed and visible (2nd pic) with click on body, and menu button change it color only collapse is visible?
bootstrap.js and jquery is connected in my footer.
This is a functional solution:
$(document).on('click touchstart', function (e) {
if ($(e.target).closest(".navbar-collapse").length === 0 && $(e.target).closest('[data-target=".navbar-collapse"]').length === 0) {
$(".navbar-toggle").collapse('hide');
}
});
Try This Example
<script type='text/javascript'>
$(document).ready(function () {
function CloseNav() {
$(".navbar-collapse").stop().css({ 'height': '1px' }).removeClass('in').addClass("collapse");
$(".navbar-toggle").stop().removeClass('collapsed');
}
$('html').click(function (event) {
var clickover = $(event.target);
var _opened = $(".navbar-collapse").hasClass("navbar-collapse in");
if (_opened === true && !clickover.hasClass("navbar-toggle")) {
CloseNav();
}
});
});
</script>
Update
you can change the html selector to whatever selector you want, body (if you have enough height), wrapper or whatever. A clean fiddle example here
This works. It will close the collapsed navbar when touched anywhere on the mobile touchscreen.
$(document).on('touchend', function (event) {
var clickover = $(event.target);
var $navbar = $(".navbar-collapse");
var _opened = $navbar.hasClass("in");
if (_opened === true && !clickover.hasClass("navbar-toggle")) {
$navbar.collapse('hide');
}
});
Here is another approach which is working for me.
My scenario: I want to hide the collapsible when I click anywhere outside of a form which contains a dropdownlist.
$(document).ready(function(){
//check if collapsible is shown
$(".collapse").on('shown.bs.collapse', function(){
//then check if there was a click
$(document).click(function(event) {
//exclude the click was on the form
if (!$(event.target).hasClass("input-default")) {
//then hide it
$(".collapse").collapse('hide');
}
});
});
});
I think your best approach would be to do something in a mediaquery, or pherhaphs with js instead, check in bootstrap page which are the break points and use the one you are interested in.
You don't want to listen for the click all the time that is so wrong. you have to bind and unbind based on the navbar status. here is my navbar-colapse and it's id is 'z', and when it is open i will listen for clicks and when it's closed i don't listen anymore. i will put comment on the code:
//CALLBACK AFTER NAVBAR-COLLAPSE OPEN
$('#z').on('shown.bs.collapse', function () {
// HERE WE BIND THE CLICK TO THE HANDLER FUNCTION
$(document).bind( "click", handler );
})
//CALLBACK AFTER NAVBAR-COLLAPSE CLOSE
$('#z').on('hidden.bs.collapse', function () {
// SINCE THE NAVBAR IS CLOSED WE DONT NEED TO LISTEN FOR CLICKS ANYMORE
$(document).unbind( "click", handler );
})
//THIS IS THE FUNCTION THAT GET FIRED
var handler = function() {
//LISTEN FOR CLICKS
$(document).click(function(event) {
//HERE FORM-CONTROL IS MY SEARCH BOX IN THE NAV SO I DONT WANT TO CLOSE
//THE NAVBAAR IF THEY CLICK ON FONT-CONTROL, BUT ANYTHING BESIDE THAT WE CLOSE THE NAVBAR
if (!$(event.target).hasClass("form-control")) {
$('#z').collapse('hide');
}
});
};
Also here is my nav-bar code :)
<nav class="navbar navbar-default my-nav" data-spy="affix" id="nav" style="margin-bottom: 0">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#z" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">-</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="z">
<div class="navbar-form navbar-left my-navbar-left" role="search">
<div class="form-group">
<input id="searchbar" type="text" class="form-control" placeholder="Search for ads">
</div>
</div>
<ul class="nav navbar-nav navbar-right my-navbar-right">
<li><a class="tab-c tab-home"> <span class="text-to-icon">Posts</span> </a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
$('.collapse').collapse('hide');

Categories