Utilizo ActiveForms a menudo y lo encuentro útil, ya que incluye al cliente scripts de validación del lado yii.js y yii.activeForm.js. Normalmente se ocupa de las reglas del modelo y la validación básica por sí solo.

Hasta Yii 2.0.9:
Podríamos usar el siguiente script para evitar el envío de múltiples formularios debido a los rápidos clics en los botones:

$('form').submit(function(){
    $(this).find('button[type!="button"],input[type="submit"]').attr("disabled",true);
    setTimeout(function(){
        $('form .has-error').each(function(index, element) {
            $(this).parents("form:first").find(":submit").removeAttr("disabled");
        });
    },1000);
});

Pero
La versión actual Yii 2.0.10 trajo algunos cambios y falla por encima del script. Ahora, no enviará el formulario si se ejecuta el código anterior.
También se ha discutido anteriormente aquí y se ha identificado como error.
Desde entonces, yii.js tuvo dos cambios:

  1. Error # 10358: Se corrigió la condición de carrera en el prefiltro AJAX yii.js (silverfire)
  2. Enh # 12580: Haga que yii.js cumpla con el modo JavaScript estricto y no estricto para permitir la concatenación con código externo (mikehaertl)

Y yii.activeForm.js tuvo cuatro cambios:

  1. Error # 10681: corrección revertida del evento beforeValidate llamando a yii.activeForm.js (silverfire)
  2. Enh # 12376: parámetro agregado al método yii.activeForm.js validate () para poder forzar la validación (DrDeath72)
  3. Enh # 12499: cuando la validación AJAX está habilitada, yii.activeForm.js lo ejecutará con fuerza en el envío del formulario para mostrar todos los posibles errores (silverfire)
  4. Enh # 12744: se agregó el evento afterInit a yii.activeForm.js (werew01f)

¿Se pueden reemplazar con archivos js oder de v2.0.9?

¿Reemplazar archivos js causará fallas y comportamientos inesperados?

¿Existe alguna solución mejor para evitar envíos múltiples?

4
Kiran Shakya 13 ene. 2017 a las 18:09

4 respuestas

La mejor respuesta

Parece que ya se ha solucionado el problema.
Aquellos que hayan instalado Yii 2.0.10 nuevo a través del compositor no tendrán este problema; mientras que aquellos que descargaron un archivo archivado de la sección 'Instalar desde un archivo de archivado' aún pueden tener este problema ya que podrían no haber actualizado los archivos de archivado.

Si se enfrenta a este problema específico, todo lo que tiene que hacer es reemplazar un archivo específico framework/assets/yii.activeForm.js del fuente de github. En caso de copia local, este archivo puede ubicarse en vendor\yiisoft\yii2\assets\yii.activeForm.js.

2
Kiran Shakya 15 ene. 2017 a las 11:34

Recientemente recibí un error que mis formularios no enviamos, y el botón permanece deshabilitado, así que lo cambié a esto. Principalmente publíquelo aquí para mi referencia futura para poder encontrarlo rápidamente: D

<?php $this->registerJs("
    $(function () {
        $('body').on('submit', 'form', function() {
            $(this).find('button[type!=\"button\"],input[type=\"submit\"]').attr('disabled',true);
            setTimeout(function(){
                $(this).find('.has-error').each(function(index, element) {
                    $(this).parents('form:first').find(':submit').removeAttr('disabled');
                });
            },1000);
        });
    });
", View::POS_END, 'prevent-double-form-submit'); ?>
0
Ripper 20 ene. 2017 a las 21:48

Funciona como un encanto

Implementé y probé la siguiente extensión:

https://github.com/Faryshta/yii2-disable-submit-buttons

Requiere compositora

"faryshta/yii2-disable-submit-buttons": "*"

Registro de activos globales

class AppAsset extends yii\web\AssetBundle
{
    public $depends = [
        'faryshta\\assets\\ActiveFormDisableSubmitButtonsAsset',
        // other dependencies
    ];
}

Uso

$form = ActiveForm::begin([
    'options' => ['class' => 'disable-submit-buttons'],
    // other configurations
]);

    // inputs

    Html::submitButton('Submit', [
        // optional, will show the value of `data-disabled-text` attribute
        // while handling the validation and submit
        'data' => ['disabled-text' => 'Please Wait']
    ])

$form->end();
1
Jairus Martin 21 sep. 2017 a las 20:07

Le sugiero que use uiBlocking para evitar múltiples clics o entradas. Aquí hay una guía completa sobre cómo bloquear la interfaz de usuario mientras hay alguna tarea en progreso. http://malsup.com/jquery/block/

1
Dani 16 ene. 2017 a las 07:46