Страница 1 из 1

Ошибка TypeError: data is undefined при перегрузки submit

Добавлено: 2019.06.13, 01:45
Dark Gard
Добрый день.
Есть необходимость отказаться от стандартной логики submit и реализовать ее через ajax
Для этого реализуем обработчик beforeSubmit

Код: Выделить всё

(document).on('beforeSubmit', 'form', function (event) {
event.preventDefault();
event.stopImmediatePropagation();
 $.ajax({
        url: .....,
        type: 'POST',
        data:  new FormData(this),
        processData: false,
        contentType: false,
        beforeSend: function() {
            ...
        },
        success: function(context) {
            ....
        },
        error:  function(xhr, str) {
            if (xhr.responseText ) {
              ...
            }
        }
    });

return false;
});
Все отрабатывает, но в консоле пишется ошибка:
TypeError: data is undefined на js код ядра yii:

Код: Выделить всё

/**
     * Restores original form options
     * @param $form the form jQuery object
     */
    var restoreButtonOptions = function ($form) {
        var data = $form.data('yiiActiveForm');

        for (var i = 0; i < buttonOptions.length; i++) {
           $form.attr(buttonOptions[i], data.options[buttonOptions[i]] || null); // Вот эта строка
        }
    };
Эта ошибка ни на что не влияет, но хочется разобраться в чем проблема и убрать ее.

Версия ядра 2.0.17. И кстати это последняя сборка совместимая с php5.6, все более старшие требуют php7.0 поскольку в них включены пакеты работающие только на php7.0, что не соответствует завяленному описанию сборок....

Re: Ошибка TypeError: data is undefined при перегрузки submit

Добавлено: 2019.06.13, 07:32
proctoleha
А в чем профит использования события beforeSubmit? Почему не используете стандартное событие submit?
Но, если так принципиально beforeSubmit, то предполагаю, что возвращать надо не false, а form.submit();

Вы должны понимать, что в js события beforeSubmit нет. Это искусственное поведение. И вообще у вас все в куче, и
event.preventDefault();
event.stopImmediatePropagation();
и
return false;

Re: Ошибка TypeError: data is undefined при перегрузки submit

Добавлено: 2019.06.13, 10:29
Dark Gard
События beforeValidate и beforeSubmit заявлены разработчиками для решения как раз указанной задачи. Собственно эта логика не менялась с 2014 года... https://habr.com/ru/post/238447/

Использование event.preventDefault(), event.stopImmediatePropagation() и return false связанно с тем, что устаешь каждый раз дебажить выясняя какая именно механика остановит дальнейшую обработку события. Проще указать все гарантировано работающие - на результат это ни как не влияет.

Например, если необходимо изменить логику перехода по ссылке:

Код: Выделить всё

<a class="btn btn-success ajax-action" href="/managers/users/create" data-pjax="0" data-title="Добавить нового пользователя" data-toggle="modal" data-target="#modal-ajax" data-method="get">Добавить</a>
И в место стандартного перехода на страницу /managers/users/create реализовать свою логику получения контента с отображением в модальном окне.

Логично перегрузить событие on click

Код: Выделить всё

$(document).on('click', 'a.ajax-action, button.ajax-action', function (event) {.....});
Но дело в том что вызов event.preventDefault(), event.returnValue = false, return false или .off('click') не позволяют отключить обработку клика js-ядром yii, поскольку на уровне js-ядра yii есть "отдельный обработчик on click" с фильтром на присутствие "data-confirm", и если у ссылки указано поле "data-confirm" то у ваша корректировка не работает, и спасает только event.stopImmediatePropagation(). Но таких не неожиданностей при плохо задокументированном js-ядре yii довольно много. Проще использовать все "набитые шишки".

Re: Ошибка TypeError: data is undefined при перегрузки submit

Добавлено: 2019.06.13, 10:40
Dark Gard
Залез в ядро:
yiisoft\yii2\assets\yii.activeForm.js судя по коду:

Код: Выделить всё

var event = $.Event(events.beforeSubmit);
$form.trigger(event);
if (event.result === false) {
    data.validated = false;
    submitFinalize($form);
    return false;
} 
Надо использовать event.result = false, но это тоже проблемы не решает.