Detecting if bootstrap modal window is show don't work properly - javascript

I have to draw something in bootstrap modal window if user click on button. My code is:
$('#button').on('click', function (evt) {
doSomeCrazyStuff();
$('#myModal').modal('show');
$('#myModal').on('shown.bs.modal', function (e) {
alert('Debug');
drawStuffInModal();
});
});
For first click everything works fine. But for second click i get two alerts, for third click - three alerts etc.
User can click button only if modal is hidden, so he need to close modal before next drawing.
I found out that a problem is a detecting of modal window state - if I don't use $('#myModal').on('shown.bs.modal', function (e) {}) but just waiting:
$('#button').on('click', function (evt) {
doSomeCrazyStuff();
$('#myModal').modal('show');
setTimeout(function () {
alert('Debug');
drawStuffInModal();
}, 500);
});
... I always get alert once. It works, but it's very ugly solution.
So my question is: why first code not working properly? I don't want wait n miliseconds because in some cases modal can need more time for loading and then user got errors.

Don't bind new event in another click event handler. Click on the #button can happen many times, which means that it will bind many similar duplicated events. Just move shown.bs.modal event subscription outside:
$('#myModal').on('shown.bs.modal', function (e) {
alert('Debug');
drawStuffInModal();
});
$('#button').on('click', function (evt) {
doSomeCrazyStuff();
$('#myModal').modal('show');
});

Related

How to restart the Jquery events, to avoid the repetition of each one of them?

I have an index page that contains the following events.
<div id="sub_page"></div>
$(document).ready(function () {
$("a.menu_navegacion_abrircaja").on('click', function (ev) {
ev.preventDefault();
var href = “nombrecontrollerEJ/view_ej";
$.post(href, function (data) {
$("#sub_page").html(data);
});
});
});
In it, when you click, load the html contents of subpages in the div sub_page.
In view view view_ej, I bring html code and also, jquery code. The Jquery code of the view that is added to the index div is as follows:
$(document).ready(function () {
$('#modal_establecer_turnos').on('hidden.bs.modal', function () {
alert("hello");
});
});
By clicking on the link that contains the class "menu_navegacion_abrircaja", I get the alert ("hello");
But it turns out that there is a problem, for every time I click on the link, the alert messages are repeated (alert ("hello");). For example, the first time I click on the link that contains the class menu_navegacion_abrircaja, it works fine showing the alert once, but then I click again on the same link it shows me the alert twice, then I do it for the third time, He shows me three times the alert, and so on.
I would like to know how to solve this problem.
Will there be any way to restart the events or handler of the jquery, as are the events click, change, "hidden.bs.modal", etc., in such a way that their repetition of the events is avoided?
I have seen the methods unbind (), bind (), off (), which might be the solution, but if so, how could you apply them?
Maybe you could try something like this in the jQuery code of your subpage:
$(document).ready(function () {
$('#modal_establecer_turnos').off('hidden.bs.modal');
$('#modal_establecer_turnos').on('hidden.bs.modal', function () {
alert(“hello”);
});
});

How to stop function in event handler

I wanna just hide jsPanel window instead of remove DOM when click [X] icon.
jsPanel support jspanelbeforeclose event.
My thought
Observe jspanelbeforeclose event and stop further action.
When click [x] icon of jsPanel, it will trigger jspanelbeforeclose event.
I think if step 1 is stopped, step 2 function panel.remove() will not be executed.
My question is how to stop 1 correctly? (Or how to prevent execute panel.remove())
I already test below methods, but both not work.
e.stopPropagation();
e.preventDefault();
return false;
jsPanel code snippet
// closes a jsPanel and removes it from the DOM
close: function (panel) {
...
panel.trigger('jspanelbeforeclose', panelID);
...
// remove the jsPanel itself
panel.remove();
...
});
My code
$('body').on('jspanelbeforeclose', function(event, id) {
// HOW TO DO
});
I would suggest a far easier method. If you want the close button to hide the panel instead of closing it, why don't you just assign another handler to the close button of this panel like
var myPanel = $.jsPanel({
// your panel config ...
callback: function (panel) {
// in the callback get the close button
$('.jsPanel-btn-close', panel)
// remove the standard handler
.off()
// and assign one that hides the panel
.on('click', function(){
panel.hide();
});
}
});
Whenever you need the panel back just call
myPanel.show();

Using jQuery to control click events by adding/removing classes

I currently have something like this code running:
function blah() {
jQuery(".class1").on("click", function() {
jQuery(this).text('Validate').addClass('class2').removeClass("class1");
//more stuff here
jQuery(".class2").on("click", function() {
jQuery(this).removeClass("class1");
//More stuff here
This is bad because the click events propagate, every click that occurs adds the click event multiple times. I tried closing off the first selector (like so) and having the click events seperately but the second click event never occurred(!):
function blah() {
jQuery(".class1").on("click", function() {
jQuery(this).text('Validate').addClass('class2').removeClass("class1");
});
jQuery(".class2").on("click", function() {
jQuery(this).removeClass("class1");
//More stuff here
How do I structure code so that on the first click one thing happens, and the second click another thing happens without click events doubling
you need
jQuery(document).on("click", ".class1", function() {
jQuery(this).text('Validate').addClass('class2').removeClass("class1");
});
jQuery(document).on("click", ".class2", function() {
jQuery(this).removeClass("class1");
//More stuff here
});
Demo: Fiddle

Bootstrap modal on shown method run multiple times

I use twitter bootstrap modals's js to show and hide a modal:
$('#myModal').modal('show')//show
$('#myModal').on('shown', function () {
// do something…
})
$('#myModal').on('hidden', function () {
// do something…
})
....
$('#myModal').modal('hide')//hide
My problem is when show and hide modal multiple times, the code in //do something... run multiple times. I guess that's because every time i show a modal, it listen to shown and the function run 5 times when the modal hide and open 5 times, any way to prevent this?
Using the way fco suggested below did solve the shown problem, but unfortunately the hide does not work, i.e. still execute more than one times, one thing different, i hide the dialog using the data-dismiss="modal" markup, not through js.
Any ideas?
You should use one instead of on
The .one() method is identical to .on(), except that the handler is unbound after its first invocation. For example:
$('#myModal').modal('show')//show
$('#myModal').one('shown', function () {
// do something…
})
$('#myModal').one('hidden', function () {
// do something…
})
....
$('#myModal').modal('hide')//hide
check out .off()
if you want the event handler to run only the first time you need to do something like:
function myHandler() {
//your event handling code here
$('#myModal').off('show', myHandler);
}
$('#myModal').on('shown', myHandler);
$('#myModal').modal('show');
//...
$('#myModal').modal('hide');

How to use Zurb Foundation reveal with open, opened, close, closed callback functions?

On zurb foundation's website at http://foundation.zurb.com/docs/reveal.php they listed some Options including
open: callback function that triggers 'before' the modal opens.
opened: callback function that triggers 'after' the modal is opened.
close: callback function that triggers 'before' the modal prepares to close.
closed: callback function that triggers 'after' the modal is closed.
But I have no idea how to use them with my modal.
I tried:
$('#myModal').closed(function()
{});
$('#myModal').trigger('reveal:closed')(
{});
$('#myModal').reveal.closed(function()
{});
$('#myModal').reveal().closed(function()
{});
I have Googled but found no hits. Anyone who can explain it or give me an example or provide a related link?
The suggestion given works, however
I have yet another closely related question for reveal():
Click Me For A Modal);
I tried to add one attribute like data-closeOnBackgroundClick="false" That doesn't seem to work. What should be the correct syntax? Will it work for callback function as well?
The above answer did not work for me. Here's what worked (Foundation 4 and jQuery):
$('#myModal').bind('opened', function() {
console.log("myModal opened");
});
Event Bindings for Zurb Foundation Reveal -
There are a series of events that you can bind to for triggering callbacks:
$(document).on('open.fndtn.reveal', '[data-reveal]', function () {
// your code goes here...
});
$(document).on('opened.fndtn.reveal', '[data-reveal]', function () {
// your code goes here...
});
$(document).on('close.fndtn.reveal', '[data-reveal]', function () {
// your code goes here...
});
$(document).on('closed.fndtn.reveal', '[data-reveal]', function () {
// your code goes here...
});
If you have multiple data-reveal used in single page as follows :
<div class="content reveal-modal" id="element-1" data-reveal>
<div class="content reveal-modal" id="element-2" data-reveal>
Then in this situations you can trigger callback same as explained above but with little modification as shown below :
$(document).on('open.fndtn.reveal', '#element-1[data-reveal]', function () {
// your code goes here...
});
$(document).on('open.fndtn.reveal', '#element-2[data-reveal]', function () {
// your code goes here...
});
Call reveal like you normally would, but include the name of the option and corresponding function as an object:
//Reveal the modal and say "Good bye" when it closes
$("#myModal").reveal({ "closed": function () { alert("Good bye") } });
On Zurb Foundation v6, these events were renamed to xxx.zf.reveal:
closeme.zf.reveal Fires immediately before the modal opens. Closes any other modals that are currently open
open.zf.reveal Fires when the modal has successfully opened.
closed.zf.reveal Fires when the modal is done closing.
Source: http://foundation.zurb.com/sites/docs/reveal.html#js-events
Examples:
Generic callback that will fire for all modals:
$(document).on('open.zf.reveal', '[data-reveal]', function() {
console.log('This works');
});
Callback that will fire when a specific modal is opened:
$(document).on('open.zf.reveal', '#<ELEMENT-ID>[data-reveal]', function() {
console.log('This works');
});
Like meatrobot said, to get this working you want to bind to the modal with the action you are targetting. I got this to work:
$('#myModal').bind('closed', function() {
console.log("myModal closed!");
});
This is a little late but for the second part you add the attributes as a semi-colon separated list of values in the data-options attribute (tested with foundation 5), i.e:
<div id="myModal" data-options="close_on_background_click:false;" class="reveal-modal">
And no, you cannot pass functions this way, i tried :)
Looking at Foundation 5 and found that the reveal library triggers open, opened, close, and closed events. Just attach a handler to the event you want.
$('#myModal').on([event], handler)
You can also pass the handlers via the settings argument.
Check this out: https://github.com/zurb/foundation/blob/master/js/foundation/foundation.reveal.js#L92
The foundation 5 documentation specifies scoping of reveal events to the 'reveal' eventspace. However, the actual modal events do not seem to fire consistently within this eventspace. Removing this specification fixes the issue:
$(document).on('opened.fndtn', '[data-reveal]', function() {
console.log('This works');
});
In foundation 3.2.5 you should bind 'reveal:opened' like this:
$('#myModal').bind('reveal:opened', function() {
console.log("myModal opened");
});
Regards, MarianoC.

Categories