How do you think about respective callback for bootstrap modal triggers? - javascript

On bootstrap modals, we know that we can bind events for triggers like show or hide using show, shown, hide, hidden, but this event binding only works for general case. What I want is 'specific case' such as:
$("#myModal").modal("show", function(e){
alert("This pops-up after #myModal is shown properly.");
});
or maybe using dictionaries for more options.
Anyway, I want to call some functions as callback after these modal triggers are done.
I do know that there can be alternative implementations, like using setTimeout to wait until the modal is completely shown or hidden, or just unbind the event inside the callback function so the event handler works only for once. Either way, it's not very convenient and ugly.
Can this feature be feasible feature request for bootstrap?
Also, I'm not very satisfied that to change modal's property after its init, I have to change it by directly managing $("#myModal").data("bs.modal").options.
Again, I'm asking about particular situation. I don't want to make callback function called for every show, shown, hide or what ever. Just for specific situation where the modal is triggered manually via javascript.
Here is an example:
Let's say that there are #myModal, and #btn-a, #btn-b.
$(document).ready(function(){
$("#myModal").on("shown.bs.modal", function(e){
console.log("myModal shown.");
})
$("#btn-a").click(function(e){
$("#myModal").modal("show");
});
$("#btn-b").click(function(e){
// There is no such thing like below. It's just pseudo code.
$("#myModal").modal("show", function(e2){
console("myModal shown by b.");
});
});
}
Then if #btn-a is clicked,
myModal shown.
will appear while if #btn-a is clicked,
myModal shown.
myModal shown by b.
will appear.
Again and again, I'm actually not asking how to make it. I already made what I want. What I'm asking is, will this feature be feasible feature request for bootstrap.

Check out the section titled Events here:
http://getbootstrap.com/javascript/#modals
Hopefully, it will give you all the information you need

You can use shown events to detect when the modal has been made visible on the screen:
$('#myModal').on('shown.bs.modal', function (e) {
alert("This pops-up after #myModal is shown properly.");
})
You can check for more information in the events section of modal here.

Related

Checking for a class dynamically added from an iFrame

A bit of a weird situation here. I know this is far from the ideal setup, but this is what I am stuck working with, without much leniency to approach it a different way.
Basically, I have a modal window, which has an email signup form embedded via iframe.
I have a script inside of the iframe that sets a class to the main modal when the submit button is pressed. To set the class on the modal, I am using the following:
$(document).on("click", "#submit-btn", function(e) {
window.parent.$("#modal-popup").addClass("submitted");
}
I have verified that this code works fine. In inspector, whenever I press the submit button, I see the "submitted" class gets added to the modal.
However... outside of the iframe, I have another script running, that checks when the users presses the close button on the modal.
I want it so that if the modal has the class of "submitted", it does one thing - but if it doesn't have that class, it does something else.
So I have the following:
$(".close-exit-modal").on("click", function(e) {
if ($("#modal-popup").hasClass("submitted")) {
//do something
} else {
//do something else
}
});
Unfortunately, every single time I try the script, the "do something else" runs. The modal clearly shows that it has the proper class - and for the life of me, I can't figure out why this script wont recognize it.
Any ideas what's going on here?
Since you appear to have the ability to change the parent, that to me signifies that you are on the same domain. So potentially you could do some different things.
$(document).on("click", "#submit-btn", function(e) {
window.parent.$("#modal-popup").addClass("submitted");
//directly call a method in the parent to let it know the class changed
window.parent.modalPopupWasSubmitted();
});
$(document).on("click", "#submit-btn", function(e) {
window.parent.$("#modal-popup").addClass("submitted");
//trigger a custom event that your parent page can have an event listener for
$(window.parent).trigger('modalWasSubmitted');
});
Optionally, depending on the browser support you need, you could also potentially use a postMessage to let the parent know that something happened. Ref. https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

Bootbox 'loaded' callback

Does Bootbox.js have a method for invoking a function upon successfully showing a dialog?
I had originally planned to use it to switch a hidden form from elsewhere in the page into the Bootbox, but that can't be done without a callback or callback analogy. Then I devised a way of moving the hidden form in, and in a forehead-smacking cringe-worthy moment I realized that I still needed a callback (or analogy) to now reveal the form (remove the 'hide' class, add the 'in' class).
The documentation does not seem to show a built in property that will allow me to do this (bootbox.init shows promise, but I don't fully understand it, it is not documented with examples, and it seems to be global. I use many bootboxes). Is there another way I can do this? Does Bootbox publish an event of some sort?
.init() is called on a specific dialog, as I showed someone else here: https://jsfiddle.net/Lu1wp3nn/
A simplified example:
bootbox
.alert('Your message')
.init(function() {
/* do something */
});
Because bootbox.js is just a wrapper over Bootstrap's modals, you have access to the modal events that Bootstrap defines. You're after shown.bs.modal (or show.bs.modal if you want to do something just prior to the dialog being shown).
Here's an example, adapted from the Bootstrap docs:
bootbox
.alert('Your message')
.on('shown.bs.modal', function (e) {
// do something...
})
To general use:
bootbox.alert|confirm({
"title": lang['EMBED'],
"message": content
}).on("shown.bs.modal", function(e) {
alert()
});

Make one element disappear when another element disappears

Context: I am making a small jQuery library for modals (in-window popups): https://github.com/hypesystem/d_modal.js
When creating a new modal, it is possible to also fade the page. This is done by adding a div with a semi-transparent black background.
When the modal is removed I want the "fade" to disappear as well. But not just when the modal is .remove()'d - I want the fade to disappear in the same way as the modal on any action that makes the modal disappear: fadeOut(), hide(), etc.
Here is a jsFiddle to test in (if you have any ideas): http://jsfiddle.net/n5fqS/
What I'm looking for is one solution that handles all the cases.
there are many ways of hidding elements (removing content of div, changing css "display" property, fadeOut(), hide(), etc, etc) and Jquery does not have a universal event listener that would group all these events. I think you will have to manually trigger a "hide" event as a callback function in all the places where your first div is being hidden. For example:
$(".dismiss").click(function() {
$("#div-one").hide(function(){
$(this).trigger('hide');
});
});
Then you only have to have once the event handler:
$("#div-one").on('hide', function(){
//code that hides my second div
)};
Of course, you will have to manually add the trigger every place where relevant. So its not "the one solution".
you can use jquery dialog to achieve this functionality.
The short answer seems to be: jQuery does not emit events on hide.
In order to combat this, I have used the best solution I could find, and started an open project to enable sending of the required events: https://github.com/hypesystem/showandtell.js
This should cover, at the moment, the most common use-cases. Any feedback on this is appreciated.
try like this
$(".dismiss").click(function() {
$("#div-one").hide(function(){
$("#div-two").hide('slow');
});
});

JQuery if statement for .is(':visible') not working

I have a div that when the page is loaded is set to display:none;. I can open it up using this simple code:
$(".field-group-format-toggler").click(function()
{
$(".field-group-format-wrapper").css({'display':'block'});
});
Once it's opened, I'd like the user to be able to close it so I tried using the .is(':visible') function and then wrapping my original code in an if statment but this time using display:none;
if($('.field-group-format-wrapper').is(':visible')){
$(".field-group-format-toggler").click(function()
{
$(".field-group-format-wrapper").css({'display':'none'});
});
}
This does not seem to work though and I am not getting any syntax errors that I know of.
I also tried this:
if ($('.field-group-format-wrapper').is(':visible'))
$(".field-group-format-toggler").click(function () {
$(".field-group-format-wrapper").css({'display':'none'});
});
... but that did not work either.
You can just use the toggle function:
$(".field-group-format-toggler").click(function()
{
$(".field-group-format-wrapper").toggle();
});
This will show the '.field-group-format-wrapper' elements if they are currently hidden and hide them if they're currently visible.
FYI the reason your code snippet in your question wasn't working is because you're only checking the visibility of the elements on dom ready, rather than on each click - so the event handler to show the elements will never be attached.
I guess your function is only being called on page load at which time all divs are hidden.
Why not check the visibility in the click event handler?
$('.field-group-format-toggler').click(function(){
var $wrapper = $('.field-group-format-wrapper'); //Maybe $(this).parent()?
if($wrapper.is(':visible'))
$wrapper.hide();
else
$wrapper.show();
As already mentioned, you can use the toggle function to achieve what you want.
To add a bit of extra information, when attaching events like you're doing, you're actually using a subscription model.
Registering an event puts it in a queue of events subscribed to that handler. In this case, when you add the second event to change the CSS, you're adding an event, not overwriting the first one.
Whilst thing isn't actually causing your problem, it's worth being aware of.

Locating an element in a 'Facebox' box

Heres my link:
http://tinyurl.com/6j727e
If you click on the link in test.php, it opens in a modal box which is using the jquery 'facebox' script.
I'm trying to act upon a click event in this box, and if you view source of test.php you'll see where I'm trying to loacte the link within the modal box.
$('#facebox .hero-link').click(alert('click!'));
However, it doesn't detect a click and oddly enough the click event runs when the page loads.
The close button DOES however have a click event built in that closes the box, and I suspect my home-grown click event is being prevented somehow, but I can't figure it out.
Can anyone help? Typically its the very last part of a project and its holding me up, as is always the way ;)
First, the reason you're getting the alert on document load is because the #click method takes a function as an argument. Instead, you passed it the return value of alert, which immediately shows the alert dialog and returns null.
The reason the event binding isn't working is because at the time of document load, #facebox .hero-link does not yet exist. I think you have two options that will help you fix this.
Option 1) Bind the click event only after the facebox is revealed. Something like:
$(document).bind('reveal.facebox', function() {
$('#facebox .hero-link').click(function() { alert('click!'); });
});
Option 2) Look into using the jQuery Live Query Plugin
Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the DOM updated.
jQuery Live Query will automatically bind the click event when it recognizes that Facebox modified the DOM. You should then only need to write this:
$('#facebox .hero-link').click(function() { alert('click!'); });
Alternatively use event delegation
This basically hooks events to containers rather than every element and queries the event.target in the container event.
It has multiple benefits in that you reduce the code noise (no need to rebind) it also is easier on browser memory (less events bound in the dom)
Quick example here
jQuery plugin for easy event delegation
P.S event delegation is pencilled to be in the next release (1.3) coming very soon.

Categories

Resources