1

I have cases where it takes a few seconds for the dropdowns to be populated on the editPopup of jqGrid. What is the best way to showing some loading message (similar to the loading message that pops up when the regular form is being loaded)

For an example, if this is a column in my grid

 { name: "Parent", index: "Parent", width: 250, editable: true, edittype: "select", editoptions: { dataUrl: "/OrganisationalUnit/GetSelectData" }, editrules: { required: false} },

and the dataUrl (in this case: dataUrl: "/OrganisationalUnit/GetSelectData" )

takes a long time to load, right now, before the data comes back from this method, it just looks like there is an empty populated dropdown and there is no visual indicator that something is loading .

leora
  • 188,729
  • 360
  • 878
  • 1,366

1 Answers1

0

If you use dataUrl in form editing then jqGrid calls internally $.jgrid.createEl method which makes $.ajax request to dataUrl (see the code fragment). The $.ajax don't use beforeSend or complete callbacks and it uses context option with elem property which represent <select> been filled.

So my suggestion is to use ajaxSelectOptions option of jqGrid with beforeSend and complete callbacks. Inside of beforeSend callback you can create some <div> or <span> with some loading animation. The are a lot of ways how to implement the animation starting with simple gif till the usage of CSS3 animation and @keyframes like it do nprogress (see here).

I used ui-anim_basic_16x16.gif from jQuery UI 1.8.2 to define the following CSS class:

.my-select-loading {
    background: white url('ui-anim_basic_16x16.gif') right center no-repeat;
    height: 16px;
    width: 16px;
    margin-left: .5em;
    display: inline-block;
}

The option ajaxSelectOptions of jqGrid I defined as so

ajaxSelectOptions: {
    beforeSend: function () {
        var context = this;
        if (context.elem) { // if it called by $.jgrid.createEl
            context.loading = true;
            setTimeout(function () {
                if (context.loading) {
                    $("<span>").addClass("my-select-loading")
                        .insertAfter($(context.elem));
                }
            }, 50);
        }
    },
    complete: function() {
        if (this.elem) {
            this.loading = false;
            var $span = $(this.elem).next("span.ui-autocomplete-loading");
            $span.remove();
        }
    }
}

The above code append <select> with empty <span> element having the class my-select-loading. We do this only if the server don't respond on dataUrl during 50ms (see the option 50 of setTimeout). Inside of complete called both in case of failure as well as in case of success response on dataUrl. As the result the user will see something like

enter image description here

The above code is just an example of the implementation. It would be probably better to create animation element with position: absolute. To have good look in case of usage the above code the width of the form should be large enough to display the inserted <span> with the animation gif.

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • I was thinking just a single loading icon (instead of one per dropdown) but this is another option as well. The issue i have with this option is that i am using Width: auto so the form is only as wide as the largest dropdown (so the loading image doesn't show up) – leora Nov 27 '13 at 23:33