jqGrid does not call the blockUI method without using window.setTimeOut when ajax request fails

Asked

Viewed 564 times

4

I’m using jqGrid 4.54 in my project and I want to put a message blocking the whole screen with the plugin blockUI when my AJAX request encounters some server error like 500 error.

I know that the blockUI 2.66.0 does not work with synchronous AJAX, so I am using my plugin jqGrid to make your AJAX requests as below:

$.extend($.jgrid.ajaxOptions, { async: true });
$.extend($.jgrid.defaults, {
    mtype: "POST",
    altRows: true,
    datatype: "json",
    loadonce: true,
    height: "auto",
    width: 1100,
    rowNum: 10,
    rowList: [10, 20, 30, 40, 50],
    viewrecords: true,
    pager: "#paginacao",
    sortorder: "asc",
    shrinkToFit: false,
    headertitles: true,
    loadui: "disable",
    rownumbers: true,
    emptyrecords: "<strong>Não houve resultado para o seu filtro.<strong>",
    autoencode: true,
    caption: "Resultados encontrados",
    deselectAfterSort: true,
    gridview: true,
    idPrefix: "id",
    rowTotal: 4000,
    sortable: true,
    toppager: true,
    loadError: function(xhr, status, error) {
        $.blockUI({
            message: '<p style=\"font-weight: bolder; color: white;\">Erro ao tentar gerar relat&oacute;rio, por favor, tente novamente.<br /><br /><a onclick=\"$.unblockUI();\">Fechar</a></p>',
            timeout: 5000,
            onOverlayClick: $.unblockUI
        });
    },
    jsonReader: {
        root: "rows",
        page: "page",
        total: "total",
        records: "records",
        repeatitems: true,
        id: 0,
        cell: ""
    }
});

But doing so the plugin does not work at all. But when I play the call to blockUI within a window.setTimeout as below works perfectly:

loadError: function(xhr, status, error) {
    window.setTimeout("$.blockUI({ message: '<p style=\"font-weight: bolder; color: white;\">Erro ao tentar gerar relat&oacute;rio, por favor, tente novamente.<br /><br /><a onclick=\"$.unblockUI();\">Fechar</a></p>', timeout: 5000, onOverlayClick: $.unblockUI});", 10);
}

Does anyone know how to make the call to blockUI be executed without having to use it within a window.setTimeout?

In time, all Javascript native functions such as parseInt, parseFloat, alert, console.log work, which leads me to believe that the problem is like the blockUI handles Ajax, the problem I use it asynchronously as it requires and it doesn’t even work without the window.setTimeout.

EDIT: According to the utluiz response, there may be some conflict with my default settings of how I handle AJAX requests, follow the configuration:

$.ajaxSetup({
    type: "POST",
    dataType : "json",
    cache : false,
    error : function(xhr, statusRequestAjax, error) { $("#msgErros").html(error); },
    beforeSend: function() { $.blockUI(); },
    complete : function() { $.unblockUI(); }
});

2 answers

3


At first I see nothing wrong with its implementation. On the other hand, the Blockiu plugin has no relation to Ajax, so your assumption about the problem seems mistaken.

This type of problem can be an action conflict problem at different events. If you have some other event like loadBeforeSend which is executed almost at the same time as the loadError, due to the error being returned very quickly, this may be undoing the display of the message.

Another problem could be some other script making changes to the DOM (HTML structure). This could affect the layers created by Blockui.

Anyway, I suggest the following steps to find the problem:

  1. Find and temporarily inhibit other events that operate during Ajax.
  2. Check whether the loadError is running and only once.
  3. Create a minimal example to reproduce the problem.

As for item 3, you can go on simplifying page code, removing elements until the problem disappears, so you isolate the cause.

Unfortunately, I don’t see how to give a direct solution to the problem, unless someone has already gone through exactly the same problem.

  • 1

    I had already thought about this part of removing parts of the system to isolate the problem, but this will simply be a hell to do, because there is no point in saving the HTML because it will not execute the ajax request I need to isolate the problem. As for blockUI having problems with AJAX is not an assumption, it is a certainty. I copied and pasted an AJAX call via jQuery that was set to be synchronous and the plugin did not work, even because synchronous AJAX already blocks the screen by itself, because nothing can run before the end of it.

  • Some links on the subject: http://stackoverflow.com/questions/6009223/blockui-vs-ajax-with-async-option-to-false and http://stackoverflow.com/questions/2875074/jquery-blockui-blocking-message-does-not-immediately-show

  • @Philippe Again: the problem is not related to Ajax. Both posts talk about the issue of the browser being locked during a synchronous Ajax. This is not about Blockui, actually, nothingness would work in that situation. The problem in such cases is that the developer does not take into account the correct sequence of events. It is possible to use a Blockui during a synchronous Ajax if Ajax is executed *after the screen is completely locked.

  • I made an example that might be seen here with Blockui both during and after Ajax. If you change the async for false works the same way, only that there is a brief visual "locking" due to browser locking.

  • @Philippe See this other example using Synchronous Ajax: http://jsfiddle.net/jL2tJ/

  • I was confused now, my solution to set up ajax to be asynchronous worked perfectly before where blockUI didn’t work and it seemed to me to be that problem, you now said and showed code that this is not the problem. The second link I sent you has an updated response that led me to the conclusion I had.

  • Follow the passage: "I don’t know if this is still Relevant, but in the end I Managed to make it work. The problem was that I was Doing a synchronous call with ajax (the "async: false" bit in the submitForm call). Blockui is thought to make an asynchronous call work as if it was synchronous, i.e. blocking the interface. If the call is already synchronous there is no need to block the ui, because that’s the normal behavior of synchronous calls!"

  • All this excerpt says is that it is not necessary to use Blockui in synchronous requests.

  • That’s what it really says. Now the funny thing is the native functions of javascript work and even other libraries, except the blockUI.

  • @Philippe Unfortunately this seems to be a particular situation. Without playing there is no help. You have tried in another browser?

  • The behavior is repeated in both Chrome and Firefox using the last two versions of them. I’ll start editing the HTML even deleting and including things. Maybe it’s something with my AJAX request settings made by us. I’ll edit to ask and put our setup here, rereading your answer I think it might have some impact.

  • 2

    you were correct, my ajax configuration was conflicting with the jqGrid plugin. We have a jQuery plugin here from the project, so I encapsulated the settings in a method. I will post as an answer, but I will mark yours as an answer, because yours led us to the correct answer.

  • @Philippe Ufa! It was nice to help.

  • Thanks, @utluiz. If possible opinion on the solution adopted.

Show 9 more comments

2

The @utluiz suggestion was correct in the first reply. My default AJAX request configuration was in conflict with the plugin jqGrid. We have a plugin jQuery here of the project, then I deleted the default AJAX settings and encapsulated them in a method.

$.fn.carregaConteudoViaAjax = function(url, dados, idElemento) {
    if (typeof idElemento === "undefined") {
        idElemento = "#" + this.attr("id");
    }

    $.ajax({
        url : url,
        data : dados,
        success : function(result, statusRequestAjax, xhr) { $(idElemento).html(result.mensagem); },
        type: "POST",
        dataType : "json",
        cache : false,
        error : function(xhr, statusRequestAjax, error) { $("#msgErros").html(error); },
        beforeSend: function() { $.blockUI(); },
        complete : function() { $.unblockUI(); }
    });
    return this;
};

Finally the calls stay $("#idElemento").carregaConteudoViaAjax(url, objetoJS);

  • Philippe, I don’t see problems with this implementation, although particularly I didn’t create a jQuery plugin for it. When I do a system, I usually create an object to represent it, with the respective methods and variables. For example: var MeuSistema = { ... }.

  • 1

    I never saw this approach, I studied a little like the plugins jQuery functionam and did similar, there are some rules that I do not follow, like create a method and play the code in it instead of already playing in your method directly, because I do not understand the right reason to do so.

  • Javascript is full of details about best practices. For example, there are several approaches to simulating Object Orientation and the form I quoted is just one example. More specifically, I use an approach equal to item #2 of this article.

  • 1

    Cool article, I’ll look better how to use your approach, I just got a little confused on how to represent DOM objects, you create your objects there, but how to reference and manipulate an input as easily as a $("#id) and extend the variable $ to give your methods to everything?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.