BlockUI не работает до проверки формы

У меня есть форма, которая отправляется с использованием тега sj:submit из плагина struts2-jquery. Кнопка отправки настроена с помощью функции validateFunction и onAfterValidationTopic. Я пытаюсь заблокировать форму с помощью jquery BlockUI, когда пользователь сохраняет эту форму через sj:submit. Проблема в том, что BlockUI не включается до завершения проверки. Так как эта форма довольно объемная, а проверка занимает секунду, этот разрыв во времени крайне заметен для пользователя.

BlockUI вызывается с помощью метода javascript, добавленного к параметру кнопки onClick. Я установил для fadeIn значение 0, поэтому он должен выполняться синхронно.

С помощью точек останова я определил, что BlockUI вызывается перед любым из методов проверки struts2-jquery, но блок по-прежнему не появляется до тех пор, пока форма не будет проверена, и она либо отправлена, либо предупреждения проверки помечены.

Мой порядок операций должен заключаться в том, чтобы заблокировать пользовательский интерфейс с помощью параметра onClick, заставить плагин struts2-jquery отправить форму для проверки, а затем запустить мой AfterValidationTopic, который разблокирует пользовательский интерфейс, если проверка не удалась. Все эти шаги выполняются в правильном порядке, за исключением того, что я не вижу блокировки пользовательского интерфейса. Я в недоумении, почему это так. Я дошел до того, что попытался добавить вызов $.blockUI из файла jquery.struts2.js в функцию $.elem.click с теми же результатами. BlockUI вызывается, но я его не вижу.

Вот мой JSP:

<sj:submit 
    button="true"
    type="button"
    id="save_button"
    cssClass="btn bg-cobalt-300"
    buttonIcon="icon-floppy-disk"
    label="Save"
    validate="true"
    formIds="my_form"
    onAfterValidationTopics="postValidation"
    validateFunction="bootstrapValidation"
    value="%{getText('global.save')}"
    onClick="loadingMaskSave();"
    />

и JS-код:

function loadingMaskSave() {
    $.blockUI({
        fadeIn: 0
    });
}

$.subscribe('postValidation', function (event,data) {
    if(event.originalEvent.formvalidate == false) {
        $.unblockUI();
    }
});

person Curtis Snowden    schedule 15.04.2017    source источник
comment
Что произойдет, если просто позвонить blockUI? Например. в готовом блоке.   -  person Aleksandr M    schedule 17.04.2017
comment
Готовый блок?   -  person Curtis Snowden    schedule 17.04.2017
comment
Готово.   -  person Aleksandr M    schedule 17.04.2017
comment
Верно, извини. Он отлично работает. Я вызываю $.blockUI() без параметров в области $(window).ready(), и оверлей отображается, как и ожидалось, с сообщением по умолчанию «Пожалуйста, подождите...». BlockUI работает и в других областях. Например, в той же форме я запустил BlockUI в момент загрузки страницы для учета элементов sj:select, заполняемых с сервера. $.unblockUI вызывается после завершения загрузки всех моих элементов sj:select через метод onSuccessTopics. Это прекрасно работает.   -  person Curtis Snowden    schedule 17.04.2017
comment
Попробуйте с некоторыми перед темой вместо onClick.   -  person Aleksandr M    schedule 17.04.2017
comment
Боюсь, это совсем не работает. Я добавляю onBeforeTopics=beforeValidation к элементу sj:submit и подписываю его как функцию, которая выполняет $.blockUI(). Подписанная функция beforeValidation даже не выполняется.   -  person Curtis Snowden    schedule 17.04.2017
comment
Если блокировка работает должным образом, почему вы ждете?   -  person Roman C    schedule 18.04.2017
comment
Блокировка не сработала, как ожидалось. Наложение нельзя было увидеть до завершения проверки.   -  person Curtis Snowden    schedule 18.04.2017


Ответы (1)


Мне удалось выяснить, в чем проблема. В методе validateForm файла jquery.struts2.js форма синхронно отправляется на проверку через ajax. Асинхронный параметр ajaxSubmit имеет значение false. Это приводит к полной блокировке браузера до завершения проверки, поэтому оверлей BlockUI не отображался. Чтобы решить эту проблему, я обновил код $elem.click() в методе formsubmit. AjaxSubmit теперь срабатывает асинхронно (с параметром async, установленным в true), а обработка тем после проверки и фактическая отправка формы теперь обрабатываются полным методом AjaxSubmit. Это предотвращает блокировку браузера, и теперь я могу видеть оверлей BlockUI до начала проверки.

$elem.click( function(e) {
    var form = $(self.escId(o.formids)),
        orginal = {};
    orginal.formvalidate = true; 
    e.preventDefault();

    if (o.validate) {
        var submit = true,
            ajaxSubmitParams = {};

        if (!self.loadAtOnce) {
            self.require("js/plugins/jquery.form" + self.minSuffix + ".js");
        }

        ajaxSubmitParams.type = "POST";
        ajaxSubmitParams.data = {
                "struts.enableJSONValidation": true,
                "struts.validateOnly": true
        };
        if (o.href && o.href !== '#') {
            ajaxSubmitParams.url = o.href;
        }
        else {
            ajaxSubmitParams.url = form[0].action;
        }

        if (o.hrefparameter) {
            ajaxSubmitParams.url = ajaxSubmitParams.url + '?' + o.hrefparameter;
        }

        ajaxSubmitParams.cache = false;
        //ajaxSubmitParams.forceSync = true;
        ajaxSubmitParams.async = true;

        ajaxSubmitParams.complete = function(request, status) {
            var f = $(form[0]),
                et = request.responseText,
                errors;
            if ($.isFunction(o.validateFunction)) {
                if (et && et.length > 10) {
                    submit = false;
                    if(et.substring(0,2) === "/*") {
                        // Handle Validation Errors for all Struts2 versions until 2.2.3.1
                        errors = $.parseJSON(et.substring(2, et.length - 2));
                    }
                    else {
                        errors = $.parseJSON(et);
                    }
                    o.validateFunction(f, errors);
                }
            }
            else if (StrutsUtils !== undefined) {
                StrutsUtils.clearValidationErrors(form[0]);

                // get errors from response
                if(et.substring(0,2) === "/*") {
                    errors = StrutsUtils.getValidationErrors(et);
                }
                else {
                    errors = StrutsUtils.getValidationErrors($.parseJSON(et));
                }

                // show errors, if any
                if (errors.fieldErrors || errors.errors) {
                    StrutsUtils.showValidationErrors(form[0], errors);
                    submit = false;
                }
            }
            self.log('form validation : ' + submit);
            orginal.formvalidate = submit;

            if (o.onaftervalidation) {
                $.each(o.onaftervalidation.split(','), function(i, topic) { 
                    $elem.publish(topic, $elem, orginal);
                });
            }  

            if(orginal.formvalidate) {
                if ( o.href && o.href != "#") {
                    form[0].action = o.href;
                }
                form.submit();
            }
        };

        form.ajaxSubmit(ajaxSubmitParams);
    }

    return false;
});
person Curtis Snowden    schedule 17.04.2017