Menu icon Foundation
Reveal Modal, Loading State

Is there an easy way to programmatically add a loading state when using the Reveal Modal? If not, is there a wide-spread pattern being used by people?

The issue I'm facing is when a reveal modal is shown say, after a button click. I'm filling the modal window with data from an Ajax call.

I find that the screen greys out, and if the data from the ajax call takes a while to load, it feels and seems as if the app is broken, and there's no way to get out of this state - the screen stays grayed out, without any way to access any of widgets in the screen below.

I've been replacing Colorbox (http://www.jacklmoore.com/colorbox/) modals with Foundation's Reveal Modal, but this is a pretty large sticking point, and would be a source of many support requests about this, from impatient users. Colorbox will show the modal window almost immediately, but at least have a spinning icon, showing that things are loading. Any clicks outside of this modal window will call off the modal, which will disappear.

I feel I'll almost need to recreate this behavior, using something similar to the "Modal in a modal" example in the docs.

revealmodalreal modalAJAXloading

Is there an easy way to programmatically add a loading state when using the Reveal Modal? If not, is there a wide-spread pattern being used by people?

The issue I'm facing is when a reveal modal is shown say, after a button click. I'm filling the modal window with data from an Ajax call.

I find that the screen greys out, and if the data from the ajax call takes a while to load, it feels and seems as if the app is broken, and there's no way to get out of this state - the screen stays grayed out, without any way to access any of widgets in the screen below.

I've been replacing Colorbox (http://www.jacklmoore.com/colorbox/) modals with Foundation's Reveal Modal, but this is a pretty large sticking point, and would be a source of many support requests about this, from impatient users. Colorbox will show the modal window almost immediately, but at least have a spinning icon, showing that things are loading. Any clicks outside of this modal window will call off the modal, which will disappear.

I feel I'll almost need to recreate this behavior, using something similar to the "Modal in a modal" example in the docs.

Chris Oyler almost 4 years ago

I have not tested this, but I think something like what's on
http://www.dave-bond.com/blog/2010/01/JQuery-ajax-progress-HMTL5/
would help. I don't think it would be too difficult to drop this in, with some modification, to the js options on programmatic open.

$('#modal-button').click(function(){
$('#myModal').foundation('reveal', 'open', {
url: 'someURL',
beforeSend: function(XMLHttpRequest){
//Download progress
XMLHttpRequest.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete)
//Do something with download progress
}
}, false);
},
success: function(data) {
alert('modal data loaded');
}
});

As for what other people have been doing for this, I haven't seen any other requests for this specific feature.

Justin J almost 4 years ago

I was hoping for something even simpler than that. For example, if there was a data attribute, you could just set on a preceding reveal:

 $('#myModal').foundation('reveal', 'open', {
   data: 'string showing my loading widget'
});
// And then, 
$('#myModal').foundation('reveal', 'open', {
    url: 'http://some-url-with-the-slow-loading-return-value',
    data: {param1: 'value1', param2: 'value2'}
});

Or setup as a callback, or whatever.

The whole, "freezing" of the entire interface" is a way less than ideal. Other than revealing hidden divs with data already present, the reveal modal is pretty restricted.

Chris Oyler almost 4 years ago

I hear you, unfortunately, I don't think that's a feature we'll be implementing in Foundation 5 as we're working feverishly on 6 currently. If you wanted to work on this functionality and submit a pull request, I would love to have a look at it.

Justin J almost 4 years ago

OK, Chris thanks. I'm looking forward to Foundation 6, which should be ready once I'm done converting this enormous project over to Foundation 5! (just my luck, eh?) Hopefully, the migration from 5->6 will be nice and smooth.

I may just look into a way to communicate that things are happening, before the ajax call is complete, in a slightly different way (or go back to Colorbox - hoping to get away from it to Keep Things Simple). I can already see how freezing the entire app is going to cause my users headaches.

Stephen Tuttlebee over 3 years ago

I cobbled together a fairly straightforward solution that I thought I'd share for anyone else who stumbles by this.

In the HTML, I added a div to hold the loading spinner image that sits at the top level under the body tag:
HTML
<div id="loadingDiv" style="position: absolute; top: 50%; left: 50%; z-index: 9999; display: none;">
<img src="img/loading.gif" />
</div>

I've centred it horizontally and vertically using top and left, and raised it above everything using z-index. By default it's not displayed.

Then inside tags on my page, I add the following JQuery (found at http://stackoverflow.com/questions/68485/how-to-show-loading-spinner-in-jquery):

 $(document)
        .ajaxStart(function () {
            $('#loadingDiv').show();
        })
        .ajaxStop(function () {
            $('#loadingDiv').hide();
        });

Ensure that the above is not inside $(document).ready().

The drawback of this approach is that it applies to all Ajax that takes place, which may not always be what you want. The following StackOverflow Q&A might help here: http://stackoverflow.com/questions/1191485/how-to-call-ajaxstart-on-specific-ajax-calls. Hopefully this provides a start for someone out there.

Justin J over 3 years ago

Stephen, I would just look at spin.js, (http://spin.js.org/) which does what you are trying to also do, but allows you to set a target and allows you to manually start/stop.

I'll have to look if F6 has made inroads on some of the problems I'm facing - notably that there's no way to call off a modal, once you've called it, by clicking outside of the modal window itself.

I ended up shipping with colorbox support, and just adding some code to make the colorbox window responsive. First, I set up some paramaters - these are also passed to colorbox when invoked,

var responsive_options = {
    width: '95%',
    height: '95%',
    maxWidth: '640px',
    maxHeight: '480px'  
};

Then made the following onresize callback, after the colorbox is loaded:

  $(window).resize(function(){
      $.colorbox.resize({
        width: window.innerWidth > parseInt(responsive_options.maxWidth) ? responsive_options.maxWidth : responsive_options.width,
        height: window.innerHeight > parseInt(responsive_options.maxHeight) ? responsive_options.maxHeight : responsive_options.height
      });    
  });

Chris Oyler over 3 years ago

@Justin J do you mean closeOnClick? Clicking outside the modal window will close the modal itself, as will hitting the esc key, by default.

Justin J over 3 years ago

@Chris Oyler , if you look at the differences in the docs between v5:

http://foundation.zurb.com/sites/docs/v/5.5.3/components/reveal.html

and v6:

http://foundation.zurb.com/sites/docs/reveal.html

You'll see there's no closeOnClick plugin option in v5

So, I'll have to revisit this when I move this project to v6 of Foundation.

I don't think F6 has really fixed this bug, they've just made it outdated, as modal doesn't load content via a call to Ajax anymore (so the modal will never be there in the way, unable to be removed, as content is being fetched)- you gotta do it yourself, and also initialize the loading graphic/visual cue - whatever you want that to be.