Почему в Yii2 событие submit у формы происходит дважды?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
jekahm
Сообщения: 30
Зарегистрирован: 2016.01.04, 10:22

Почему в Yii2 событие submit у формы происходит дважды?

Сообщение jekahm »

Доброго времени суток!
Для перехвата события сабмита формы использую след. код (в качестве теста):

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

$(document).on("beforeSubmit", "#pm-form", function (event, messages) {
    var formdata = $(this).serialize();
    console.log(formdata);
    $(this).find(':submit').attr('disabled', true);
    return false;
  });
Но, несмотря на то, что при этом делаю кнопку сабмита неактивной, в консоли можно увидеть, что форма отправляется как минимум дважды при быстром клике на кнопку. То есть по сути вызов события beforeSubmit происходит с задержкой.
С чем это может быть связано? И можно ли это как-то пофиксить?
Заранее благодарен!
Аватара пользователя
futbolim
Сообщения: 2051
Зарегистрирован: 2012.07.08, 19:28

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение futbolim »

Ищите в своём js коде.
Если pjax - может timeout-a не хватать.
В ином случае такого поведения не встречал.
jekahm
Сообщения: 30
Зарегистрирован: 2016.01.04, 10:22

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение jekahm »

futbolim писал(а):Ищите в своём js коде.
Если pjax - может timeout-a не хватать.
В ином случае такого поведения не встречал.
Pjax не использую
Goog1e
Сообщения: 97
Зарегистрирован: 2016.01.18, 20:02

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение Goog1e »

Мне кажется, что у вас сперва срабатывает ajax валидация.
Покажите код формирования формы.
jekahm
Сообщения: 30
Зарегистрирован: 2016.01.04, 10:22

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение jekahm »

Goog1e писал(а):Мне кажется, что у вас сперва срабатывает ajax валидация.
Покажите код формирования формы.

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

<?php
    $form = ActiveForm::begin([
            'id' => 'pm-form',
            'action' => ['/messages/send'],
            //'enableClientValidation' => true,
            //'enableAjaxValidation' => true,
        ]);
?>
    <?php if (empty($dialog)): ?>
        <?= $form->field($model, 'subject',[
            'template' => "<div class='field'>{label}\n{input}\n{error}</div>",
        ])->textInput(['maxlength' => 255]) ?>
    <?php endif; ?>

    <?=
        $form->field($model, 'content')->widget(Widget::className(), [
            'settings' => [
                'buttons' => ['bold', 'italic', 'underline', 'deleted', 'link', 'image'],
                'lang' => app\components\helpers\LanguageHelper::getCurrent(),
                'minHeight' => 200,
                'plugins' => []
            ]
        ])->label('');

    ?>

    <?= Html::activeHiddenInput($model, 'sendfrom') ?>

    <?= Html::activeHiddenInput($model, 'sendto', ['id' => 'YBoardMessage_send_to']) ?>

    <?= Html::hiddenInput('dialog', $dialog) ?>

    <div class="field">
        <?= Html::submitButton(Yii::t('comments/send_message', 'send'))?>
    </div>

<?php ActiveForm::end(); ?>
Аватара пользователя
futbolim
Сообщения: 2051
Зарегистрирован: 2012.07.08, 19:28

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение futbolim »

В коде у себя ищите.
jekahm
Сообщения: 30
Зарегистрирован: 2016.01.04, 10:22

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение jekahm »

Решил данную проблему след. образом:

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

$(document).on("beforeValidate", "form", function(event, messages, deferreds) {
		$(this).find(':submit').attr('disabled', true);
	}).on("afterValidate", "form", function(event, messages, errorAttributes) {
		if (errorAttributes.length > 0) {
			$(this).find(':submit').attr('disabled', false);
		}
	});
Onotole
Сообщения: 1808
Зарегистрирован: 2012.12.24, 12:49

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение Onotole »

Написать костыль вместо того, чтобы найти проблему и решить ее...
jekahm
Сообщения: 30
Зарегистрирован: 2016.01.04, 10:22

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение jekahm »

Onotole писал(а):Написать костыль вместо того, чтобы найти проблему и решить ее...
Ну так особо никто и не проявляет активность в теме, что помочь решить возникшую проблему.
Если есть другие варианты - предлагайте. Буду рад любому дельному совету.
jekahm
Сообщения: 30
Зарегистрирован: 2016.01.04, 10:22

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение jekahm »

Затестил ради интереса на голом сайте. Как минимум сабмит формы происходит дважды. С помощью Enter и 3 раза удаётся отправить.

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

   $(document).on("beforeSubmit", "#test-form", function (event, messages) {
		$(this).find(':submit').attr('disabled', true);
		console.log('Test new form');
		return false;
	});
То есть проблема явно не в моём коде.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение zelenin »

jekahm писал(а):Затестил ради интереса на голом сайте. Как минимум сабмит формы происходит дважды. С помощью Enter и 3 раза удаётся отправить.

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

   $(document).on("beforeSubmit", "#test-form", function (event, messages) {
		$(this).find(':submit').attr('disabled', true);
		console.log('Test new form');
		return false;
	});
То есть проблема явно не в моём коде.
https://github.com/yiisoft/yii2/blob/ma ... orm.js#L81
If the handler returns a boolean false, it will stop form submission.
jekahm
Сообщения: 30
Зарегистрирован: 2016.01.04, 10:22

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение jekahm »

zelenin писал(а): https://github.com/yiisoft/yii2/blob/ma ... orm.js#L81
If the handler returns a boolean false, it will stop form submission.
Не могли бы разъяснить немного подробнее? Заранее благодарен
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение Loveorigami »

Вы сами останавливаете submit формы, т.к. возвращаете false.
jekahm
Сообщения: 30
Зарегистрирован: 2016.01.04, 10:22

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение jekahm »

Loveorigami писал(а):Вы сами останавливаете submit формы, т.к. возвращаете false.
Этот код я привёл в качестве теста, чтобы показать, что в моём случае блокирование кнопки не срабатывает моментально и в консоль лог выводится несколько раз. А Вообще возвращаю false, так как у себя в реальном проекте использую ajax для отправки формы.
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение rugabarbo »

А почему должно быть "моментально"? (:
jekahm
Сообщения: 30
Зарегистрирован: 2016.01.04, 10:22

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение jekahm »

rugabarbo писал(а):А почему должно быть "моментально"? (:
Потому как логично, что в ином случае форма будет отправлена несколько раз, если кнопка не будет заблокирована мгновенно.
В идеале после прохождения валидации должно быть, как здесь https://jsfiddle.net/m146a9b2/
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение zelenin »

jekahm писал(а):
rugabarbo писал(а):А почему должно быть "моментально"? (:
Потому как логично, что в ином случае форма будет отправлена несколько раз, если кнопка не будет заблокирована мгновенно.
вас спрашивают о логике в контексте работы браузера, а не о логике ваших ожиданий.
если js навешанный на форуму отрабатывает 100 мс, то в эти 100 мс вы можете много раз успеть на кнопку сабмита и она еще не будет заблокирована.
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение rugabarbo »

jekahm писал(а):
rugabarbo писал(а):А почему должно быть "моментально"? (:
Потому как логично, что в ином случае форма будет отправлена несколько раз, если кнопка не будет заблокирована мгновенно.
В идеале после прохождения валидации должно быть, как здесь https://jsfiddle.net/m146a9b2/
В идеале да, но включите JS-профайлер и посмотрите, сколько там всего происходит и может происходить до вызова beforeSubmit. Не удивительно, что при зажатом Enter успевает проскочить 2-3 клика - это всё-таки асинхронная среда.

Вот здесь идёт обсуждение защиты от double-сабмитов на серверной стороне: https://github.com/yiisoft/yii2/issues/10498

Если вам нужно 100% защититься от двойных кликов, то это не решить с помощью JavaScript. Я тоже делаю для всех важных кнопок:

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

$('.btn').prop('disabled', true); 
- и в 99.9% случаев это позволяет защититься. Но практика показывает, что в 0.1% случаев всё-таки находятся кретины, успевающие нажать сабмит очень-очень быстро два раза подряд :mrgreen:

Хотите гарантий - это не про JavaScript.
JavaScript - про удобство клиента.
jekahm
Сообщения: 30
Зарегистрирован: 2016.01.04, 10:22

Re: Почему в Yii2 событие submit у формы происходит дважды?

Сообщение jekahm »

rugabarbo писал(а):
jekahm писал(а):
rugabarbo писал(а):А почему должно быть "моментально"? (:
Потому как логично, что в ином случае форма будет отправлена несколько раз, если кнопка не будет заблокирована мгновенно.
В идеале после прохождения валидации должно быть, как здесь https://jsfiddle.net/m146a9b2/
В идеале да, но включите JS-профайлер и посмотрите, сколько там всего происходит и может происходить до вызова beforeSubmit. Не удивительно, что при зажатом Enter успевает проскочить 2-3 клика - это всё-таки асинхронная среда.

Вот здесь идёт обсуждение защиты от double-сабмитов на серверной стороне: https://github.com/yiisoft/yii2/issues/10498

Если вам нужно 100% защититься от двойных кликов, то это не решить с помощью JavaScript. Я тоже делаю для всех важных кнопок:

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

$('.btn').prop('disabled', true); 
- и в 99.9% случаев это позволяет защититься. Но практика показывает, что в 0.1% случаев всё-таки находятся кретины, успевающие нажать сабмит очень-очень быстро два раза подряд :mrgreen:

Хотите гарантий - это не про JavaScript.
JavaScript - про удобство клиента.
Благодарю вас, а так же участников данной темы ;) Теперь пришло четкое осознание того, что многие вещи не могут быть реализованы и достигнуты только за счет client-side технологий. И спасибо за ссылку о server-side решении.
Последний раз редактировалось jekahm 2016.09.05, 14:36, всего редактировалось 1 раз.
Ответить