validar validacion formularios formulario enviar ejemplos ejemplo con antes javascript jquery html-form double-submit-prevention html-form-post

validacion - validar formulario javascript onclick



Evite la doble presentaciĆ³n de formularios en jQuery (19)

Tengo un formulario que tarda un poco en procesarse para el servidor. Necesito asegurarme de que el usuario espera y no intenta volver a enviar el formulario haciendo clic en el botón nuevamente. Intenté usar el siguiente código jQuery:

<script type="text/javascript"> $(document).ready(function() { $("form#my_form").submit(function() { $(''input'').attr(''disabled'', ''disabled''); $(''a'').attr(''disabled'', ''disabled''); return true; }); }); </script>

Cuando pruebo esto en Firefox todo se deshabilita, pero el formulario no se envía con ninguno de los datos POST que se supone que debe incluir. No puedo usar jQuery para enviar el formulario porque necesito que se envíe el botón con el formulario, ya que hay varios botones de envío y determino cuál fue el valor utilizado por el valor que se incluye en el mensaje POST. Necesito que el formulario se envíe como suele ser y tengo que desactivar todo justo después de que eso ocurra.

¡Gracias!


... pero el formulario no se envía con ninguno de los datos POST que se supone que debe incluir.

Correcto. Los nombres / valores de elementos de formularios desactivados no se enviarán al servidor. Debe establecerlos como elementos de solo lectura .

Además, los anclajes no se pueden desactivar así. Tendrá que eliminar sus HREF (no recomendado) o evitar su comportamiento predeterminado (mejor forma), por ejemplo:

<script type="text/javascript"> $(document).ready(function(){ $("form#my_form").submit(function(){ $(''input'').attr(''readonly'', true); $(''input[type=submit]'').attr("disabled", "disabled"); $(''a'').unbind("click").click(function(e) { e.preventDefault(); // or return false; }); }); </script>


El código de Nathan, pero para jQuery Validate plugin

Si usa el complemento jQuery Validate, ya tienen implementado el controlador de envío, y en ese caso no hay motivo para implementar más de uno. El código:

jQuery.validator.setDefaults({ submitHandler: function(form){ // Prevent double submit if($(form).data(''submitted'')===true){ // Previously submitted - don''t submit again return false; } else { // Mark form as ''submitted'' so that the next submit can be ignored $(form).data(''submitted'', true); return true; } } });

Puede expandirlo fácilmente dentro del bloque } else { -block para deshabilitar las entradas y / o enviar.

Aclamaciones


Cambiar el botón de enviar:

<input id="submitButtonId" type="submit" value="Delete" />

Con el botón normal:

<input id="submitButtonId" type="button" value="Delete" />

Luego use la función de clic:

$("#submitButtonId").click(function () { $(''#submitButtonId'').prop(''disabled'', true); $(''#myForm'').submit(); });

Y recuerda volver a habilitar el botón cuando sea necesario:

$(''#submitButtonId'').prop(''disabled'', false);


Creo que la respuesta de Nathan Long es el camino a seguir. Para mí, estoy usando la validación del lado del cliente, por lo que acabo de agregar una condición para que el formulario sea válido.

EDITAR : si no se agrega, el usuario nunca podrá enviar el formulario si la validación del lado del cliente encuentra un error.

// jQuery plugin to prevent double submission of forms jQuery.fn.preventDoubleSubmission = function () { $(this).on(''submit'', function (e) { var $form = $(this); if ($form.data(''submitted'') === true) { // Previously submitted - don''t submit again alert(''Form already submitted. Please wait.''); e.preventDefault(); } else { // Mark it so that the next submit can be ignored // ADDED requirement that form be valid if($form.valid()) { $form.data(''submitted'', true); } } }); // Keep chainability return this; };


Creo que tu problema es esta línea:

$(''input'').attr(''disabled'',''disabled'');

Estás deshabilitando TODAS las entradas, incluidas, supongo, aquellas cuya información se supone que debe enviar el formulario.

Para deshabilitar solo el botón (s) de envío, puede hacer esto:

$(''button[type=submit], input[type=submit]'').prop(''disabled'',true);

Sin embargo, no creo que IE envíe el formulario si incluso esos botones están desactivados. Sugeriría un enfoque diferente.

Un plugin jQuery para resolverlo

Acabamos de resolver este problema con el siguiente código. El truco aquí es usar data() de jQuery data() para marcar el formulario como ya enviado o no. De esa forma, no tenemos que meternos con los botones de envío, lo que asusta a los IE.

// jQuery plugin to prevent double submission of forms jQuery.fn.preventDoubleSubmission = function() { $(this).on(''submit'',function(e){ var $form = $(this); if ($form.data(''submitted'') === true) { // Previously submitted - don''t submit again e.preventDefault(); } else { // Mark it so that the next submit can be ignored $form.data(''submitted'', true); } }); // Keep chainability return this; };

Úselo así:

$(''form'').preventDoubleSubmission();

Si hay formularios AJAX que se deben permitir enviar múltiples veces por carga de página, puede darles una clase que los indique y luego excluirlos de su selector de esta manera:

$(''form:not(.js-allow-double-submission)'').preventDoubleSubmission();


El enfoque del tiempo es incorrecto: ¿cómo sabes cuánto tiempo llevará la acción en el navegador del cliente?

Cómo hacerlo

$(''form'').submit(function(){ $(this).find('':submit'').attr(''disabled'',''disabled''); });

Cuando se envía el formulario, deshabilitará todos los botones de envío dentro.

Recuerde, en Firefox cuando deshabilita un botón, este estado será recordado cuando regrese a la historia. Para evitar eso, debe habilitar botones en la carga de la página, por ejemplo.


En mi caso, el formulario onsubmit tenía algún código de validación, por lo que incrementé respuesta de incluido un punto de control de envío

$.fn.preventDoubleSubmission = function() { $(this).on(''submit'',function(e){ var $form = $(this); //if the form has something in onsubmit var submitCode = $form.attr(''onsubmit''); if(submitCode != undefined && submitCode != ''''){ var submitFunction = new Function (submitCode); if(!submitFunction()){ event.preventDefault(); return false; } } if ($form.data(''submitted'') === true) { /*Previously submitted - don''t submit again */ e.preventDefault(); } else { /*Mark it so that the next submit can be ignored*/ $form.data(''submitted'', true); } }); /*Keep chainability*/ return this; };


Existe la posibilidad de mejorar el approach Nathan Long. Puede reemplazar la lógica para la detección del formulario ya enviado con este:

var lastTime = $(this).data("lastSubmitTime"); if (lastTime && typeof lastTime === "object") { var now = new Date(); if ((now - lastTime) > 2000) // 2000ms return true; else return false; } $(this).data("lastSubmitTime", new Date()); return true; // or do an ajax call or smth else


He estado teniendo problemas similares y mi (s) solución (es) son las siguientes.

Si no tiene ninguna validación del lado del cliente, puede simplemente usar el método jquery one () como se documenta aquí.

http://api.jquery.com/one/

Esto deshabilita el controlador después de haber sido invocado.

$("#mysavebuttonid").on("click", function () { $(''form'').submit(); });

Si estás haciendo una validación del lado del cliente como lo estaba haciendo, entonces es un poco más complicado. El ejemplo anterior no le permitirá enviar nuevamente después de la validación fallida. Pruebe este enfoque en su lugar

$("#mysavebuttonid").on("click", function (event) { $(''form'').submit(); if (boolFormPassedClientSideValidation) { //form has passed client side validation and is going to be saved //now disable this button from future presses $(this).off(event); } });


Mi solución:

// jQuery plugin to prevent double submission of forms $.fn.preventDoubleSubmission = function () { var $form = $(this); $form.find(''[type="submit"]'').click(function () { $(this).prop(''disabled'', true); $form.submit(); }); // Keep chainability return this; };


Por favor, revisa el plugin jquery-safeform .

Ejemplo de uso:

$(''.safeform'').safeform({ timeout: 5000, // disable next submission for 5 sec submit: function() { // You can put validation and ajax stuff here... // When done no need to wait for timeout, re-enable the form ASAP $(this).safeform(''complete''); return false; } });


Resolví un problema muy similar usando:

$("#my_form").submit(function(){ $(''input[type=submit]'').click(function(event){ event.preventDefault(); }); });


Se modificó la solución de Nathan un poco para Bootstrap 3. Esto configurará un texto de carga para el botón de enviar. Además, caducará después de 30 segundos y permitirá que se reenvíe el formulario.

jQuery.fn.preventDoubleSubmission = function() { $(''input[type="submit"]'').data(''loading-text'', ''Loading...''); $(this).on(''submit'',function(e){ var $form = $(this); $(''input[type="submit"]'', $form).button(''loading''); if ($form.data(''submitted'') === true) { // Previously submitted - don''t submit again e.preventDefault(); } else { // Mark it so that the next submit can be ignored $form.data(''submitted'', true); $form.setFormTimeout(); } }); // Keep chainability return this; }; jQuery.fn.setFormTimeout = function() { var $form = $(this); setTimeout(function() { $(''input[type="submit"]'', $form).button(''reset''); alert(''Form failed to submit within 30 seconds''); }, 30000); };


Si utiliza AJAX para publicar un formulario, establezca async: false debe evitar presentaciones adicionales antes de que se borre el formulario:

$("#form").submit(function(){ var one = $("#one").val(); var two = $("#two").val(); $.ajax({ type: "POST", async: false, // <------ Will complete submit before allowing further action url: "process.php", data: "one="+one+"&two="+two+"&add=true", success: function(result){ console.log(result); // do something with result }, error: function(){alert(''Error!'')} }); return false; } });


Terminé usando ideas de esta publicación para llegar a una solución que es bastante similar a la versión de AtZako.

jQuery.fn.preventDoubleSubmission = function() { var last_clicked, time_since_clicked; $(this).bind(''submit'', function(event){ if(last_clicked) time_since_clicked = event.timeStamp - last_clicked; last_clicked = event.timeStamp; if(time_since_clicked < 2000) return false; return true; }); };

Usando así:

$(''#my-form'').preventDoubleSubmission();

Descubrí que las soluciones que no incluían algún tipo de tiempo de espera, pero que solo presentaban elementos de formularios deshabilitados o desactivados, causaban problemas porque, una vez que se desencadena el bloqueo, no puede volver a enviarlos hasta que actualice la página. Eso causa algunos problemas para mí al hacer ajax.

Esto probablemente puede ser preciado un poco ya que no es tan elegante.


Use dos botones de enviar.

<input id="sub" name="sub" type="submit" value="OK, Save"> <input id="sub2" name="sub2" type="submit" value="Hidden Submit" style="display:none">

Y jQuery:

$("#sub").click(function(){ $(this).val("Please wait.."); $(this).attr("disabled","disabled"); $("#sub2").click(); });


así es como lo hago:

$(document).ready(function () { $(''.class_name'').click(function () { $(this).parent().append(''<img src="data:image/gif;base64,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" />''); $(this).hide(); }); });

Créditos: https://github.com/phpawy/jquery-submit-once


este código mostrará la carga en la etiqueta del botón y establecerá el botón para

deshabilitar el estado, luego después del procesamiento, volver a habilitar y devolver el texto del botón original **

$(function () { $(".btn-Loading").each(function (idx, elm) { $(elm).click(function () { //do processing if ($(".input-validation-error").length > 0) return; $(this).attr("label", $(this).text()).text("loading ...."); $(this).delay(1000).animate({ disabled: true }, 1000, function () { //original event call $.when($(elm).delay(1000).one("click")).done(function () { $(this).animate({ disabled: false }, 1000, function () { $(this).text($(this).attr("label")); }) }); //processing finalized }); }); }); // and fire it after definition }

);


event.timeStamp no funciona en Firefox. Devolver falso no es estándar, debe llamar a event.preventDefault() . Y mientras estamos en eso, siempre use llaves con una construcción de control .

Para resumir todas las respuestas anteriores, aquí hay un complemento que hace el trabajo y funciona en todos los navegadores.

jQuery.fn.preventDoubleSubmission = function() { var last_clicked, time_since_clicked; jQuery(this).bind(''submit'', function(event) { if(last_clicked) { time_since_clicked = jQuery.now() - last_clicked; } last_clicked = jQuery.now(); if(time_since_clicked < 2000) { // Blocking form submit because it was too soon after the last submit. event.preventDefault(); } return true; }); };

Para abordar Kern3l, el método de sincronización me funciona simplemente porque estamos tratando de detener un doble clic en el botón Enviar. Si tiene un tiempo de respuesta muy largo a un envío, le recomiendo que reemplace el botón o el formulario de envío por un giro.

Bloquear por completo las presentaciones posteriores del formulario, como lo hacen la mayoría de los ejemplos anteriores, tiene un efecto secundario negativo: si hay un error en la red y quieren intentar volver a enviarlo, no podrían hacerlo y perderían los cambios que hecho. Esto definitivamente convertiría a un usuario enojado.