server-side может быть?jekahm писал(а):Благодарю Теперь пришло четкое осознание того, что многие вещи не могут быть реализованы и достигнуты только за счет client-side технологий.
Почему в Yii2 событие submit у формы происходит дважды?
Re: Почему в Yii2 событие submit у формы происходит дважды?
Re: Почему в Yii2 событие submit у формы происходит дважды?
Написал, что "НЕ могут быть достигнуты"zelenin писал(а):server-side может быть?jekahm писал(а):Благодарю Теперь пришло четкое осознание того, что многие вещи не могут быть реализованы и достигнуты только за счет client-side технологий.
Re: Почему в Yii2 событие submit у формы происходит дважды?
а, ок.jekahm писал(а):Написал, что "НЕ могут быть достигнуты"zelenin писал(а):server-side может быть?jekahm писал(а):Благодарю Теперь пришло четкое осознание того, что многие вещи не могут быть реализованы и достигнуты только за счет client-side технологий.
Re: Почему в Yii2 событие submit у формы происходит дважды?
Сейчас делаю отправку данных из "Active Form" с помощью Ajax-запроса и столкнулся с такой же проблемой, но не понял как её решить.
Есть совершенно стандартная форма:
На которую я повесил обработчик:
При первом нажатии на "Submit" происходит два одинаковых post-запроса, за исключением того, что во втором запросе к передаваемым данным добавляется "update-button". При последующих нажатиях отправляется один запрос.
Посмотрев в отладчике работу внутреннего скрипта "yii.activeForm.js", понял почему так происходит:
1. В "submitForm: function() {}" не срабатывает условие "if (data.validated) {}".
2. Отправляется первый запрос.
3. Условие "if (data.validated) {}" срабатывает, в форму добавляется <input type="hidden" name="update-button">.
4. Отправляется второй запрос.
Проблема в том, что в первый раз в БД создастся две одинаковых записи, но этого делать не нужно. Я понимаю, что это связано с валидацией данных, но, то ли я не до конца понимаю работу Active Form, то ли у меня неправильно работает js-скрипт. Подскажите, пожалуйста, как сделать правильно, чтобы добавление/редактирование происходило один раз.
Есть совершенно стандартная форма:
Код: Выделить всё
<?php $form = ActiveForm::begin(['id' => 'user-form']); ?>
<?= $form->field($model, 'name') ?>
//...
<div class="form-group">
<?= Html::submitButton('Сохранить', ['class' => 'button', 'name' => 'update-button']) ?>
</div>
<?php ActiveForm::end(); ?>
Код: Выделить всё
var form = $('#user-form');
form.on('submit', function(event) {
event.preventDefault();
var url = '/main/controller/action';
var data = form.serialize();
$.ajax({
//...
});
});
Посмотрев в отладчике работу внутреннего скрипта "yii.activeForm.js", понял почему так происходит:
1. В "submitForm: function() {}" не срабатывает условие "if (data.validated) {}".
2. Отправляется первый запрос.
3. Условие "if (data.validated) {}" срабатывает, в форму добавляется <input type="hidden" name="update-button">.
4. Отправляется второй запрос.
Проблема в том, что в первый раз в БД создастся две одинаковых записи, но этого делать не нужно. Я понимаю, что это связано с валидацией данных, но, то ли я не до конца понимаю работу Active Form, то ли у меня неправильно работает js-скрипт. Подскажите, пожалуйста, как сделать правильно, чтобы добавление/редактирование происходило один раз.
Re: Почему в Yii2 событие submit у формы происходит дважды?
Мне помог данный способ:Haku писал(а): ↑2018.08.31, 15:47 Сейчас делаю отправку данных из "Active Form" с помощью Ajax-запроса и столкнулся с такой же проблемой, но не понял как её решить.
Есть совершенно стандартная форма:На которую я повесил обработчик:Код: Выделить всё
<?php $form = ActiveForm::begin(['id' => 'user-form']); ?> <?= $form->field($model, 'name') ?> //... <div class="form-group"> <?= Html::submitButton('Сохранить', ['class' => 'button', 'name' => 'update-button']) ?> </div> <?php ActiveForm::end(); ?>
При первом нажатии на "Submit" происходит два одинаковых post-запроса, за исключением того, что во втором запросе к передаваемым данным добавляется "update-button". При последующих нажатиях отправляется один запрос.Код: Выделить всё
var form = $('#user-form'); form.on('submit', function(event) { event.preventDefault(); var url = '/main/controller/action'; var data = form.serialize(); $.ajax({ //... }); });
Посмотрев в отладчике работу внутреннего скрипта "yii.activeForm.js", понял почему так происходит:
1. В "submitForm: function() {}" не срабатывает условие "if (data.validated) {}".
2. Отправляется первый запрос.
3. Условие "if (data.validated) {}" срабатывает, в форму добавляется <input type="hidden" name="update-button">.
4. Отправляется второй запрос.
Проблема в том, что в первый раз в БД создастся две одинаковых записи, но этого делать не нужно. Я понимаю, что это связано с валидацией данных, но, то ли я не до конца понимаю работу Active Form, то ли у меня неправильно работает js-скрипт. Подскажите, пожалуйста, как сделать правильно, чтобы добавление/редактирование происходило один раз.
вместо
Код: Выделить всё
form.on('submit', function(e){})
Код: Выделить всё
form.on('beforeValidate', function(){
return false; // Если вернуть false, то форма не будет отправлена
})
Re: Почему в Yii2 событие submit у формы происходит дважды?
Столкнулся с такой же проблемой и нашел ее решение. Как верно подметил товарищ выше, при включенной ajax валидации в ActiveForm отправляется насколько запросов (валидация/отправка формы). Валидацию нужно вынести в отдельный экшен. Вот пример кода:
Код: Выделить всё
<?php $form = \yii\widgets\ActiveForm::begin([
'id' => 'my-form-id',
'action' => 'save-url',
'enableAjaxValidation' => true,
'validationUrl' => 'validate',
]); ?>
public function actionValidate()
{
$model = new MyModel();
$request = \Yii::$app->getRequest();
if ($request->isPost && $model->load($request->post())) {
\Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
}
Re: Почему в Yii2 событие submit у формы происходит дважды?
Проверил такая проблема действительно есть. Кликать дважды не обязательно, форма отправляется клавишей Enter.jekahm писал(а): ↑2016.09.05, 14:27Благодарю вас, а так же участников данной темы Теперь пришло четкое осознание того, что многие вещи не могут быть реализованы и достигнуты только за счет client-side технологий. И спасибо за ссылку о server-side решении.rugabarbo писал(а):В идеале да, но включите JS-профайлер и посмотрите, сколько там всего происходит и может происходить до вызова beforeSubmit. Не удивительно, что при зажатом Enter успевает проскочить 2-3 клика - это всё-таки асинхронная среда.jekahm писал(а): Потому как логично, что в ином случае форма будет отправлена несколько раз, если кнопка не будет заблокирована мгновенно.
В идеале после прохождения валидации должно быть, как здесь https://jsfiddle.net/m146a9b2/
Вот здесь идёт обсуждение защиты от double-сабмитов на серверной стороне: https://github.com/yiisoft/yii2/issues/10498
Если вам нужно 100% защититься от двойных кликов, то это не решить с помощью JavaScript. Я тоже делаю для всех важных кнопок:
- и в 99.9% случаев это позволяет защититься. Но практика показывает, что в 0.1% случаев всё-таки находятся кретины, успевающие нажать сабмит очень-очень быстро два раза подрядКод: Выделить всё
$('.btn').prop('disabled', true);
Хотите гарантий - это не про JavaScript.
JavaScript - про удобство клиента.
1. Зажать Enter
2. Сработал beforeSubmit, Submit = false, return false
3. Ждем выполнения Ajax, Submit = true
4. И вот тут начинается вакханалия, форма отправляется столько раз сколько успеет за 200мс, а это от 4 до 6 раз. Клавиша Enter все еще зажата.
Не очень понимаю почему все положили хер, мол юзер так никогда не сделает.
Долго по коду не лазил, но нашел вот такой вызов. Отсюда идет данная ошибка:
yii.activeForm.js
Код: Выделить всё
if (data.submitting) {
// delay callback so that the form can be submitted without problem
window.setTimeout(function () {
updateInputs($form, messages, submitting);
}, 200);
} else {