2010-12-30 12 views
5

Tengo un formulario generado por <% Ajax.BeginForm() {} %> que contiene una gran cantidad de entradas y texareas.¿Cómo sé que ha cambiado una entrada de formulario?

Cuando un valor de entrada cambia, necesito saberlo y marcar la entrada y el formulario como "sucio". Si el usuario intenta abandonar la página sin guardarla, le pediré que confirme el abandono de los cambios.

¿Alguna sugerencia sobre cómo se debe hacer esto?

Respuesta

17

Los controles HTML incluyen una propiedad que tiene el valor original. Puede comparar este valor con el valor actual para ver si ha habido algún cambio.

function getHasChanges() { 
    var hasChanges = false; 

    $(":input:not(:button):not([type=hidden])").each(function() { 
     if ((this.type == "text" || this.type == "textarea" || this.type == "hidden") && this.defaultValue != this.value) { 
      hasChanges = true; 
      return false;    } 
     else { 
      if ((this.type == "radio" || this.type == "checkbox") && this.defaultChecked != this.checked) { 
       hasChanges = true; 
       return false;     } 
      else { 
       if ((this.type == "select-one" || this.type == "select-multiple")) { 
        for (var x = 0; x < this.length; x++) { 
         if (this.options[x].selected != this.options[x].defaultSelected) { 
          hasChanges = true; 
          return false; 
         } 
        } 
       } 
      } 
     } 
    }); 

    return hasChanges; 
} 

function acceptChanges() { 
    $(":input:not(:button):not([type=hidden])").each(function() { 
     if (this.type == "text" || this.type == "textarea" || this.type == "hidden") { 
      this.defaultValue = this.value; 
     } 
     if (this.type == "radio" || this.type == "checkbox") { 
      this.defaultChecked = this.checked; 
     } 
     if (this.type == "select-one" || this.type == "select-multiple") { 
      for (var x = 0; x < this.length; x++) { 
       this.options[x].defaultSelected = this.options[x].selected 
      } 
     } 
    }); 
} 
+0

Me gusta mucho esta forma de comprobar si el valor es igual al valor predeterminado, y supongo que esto funcionaría bien en una "forma tradicional". Sin embargo, enviaré los cambios a través de XMLHttpRequest y necesito "reiniciar" el formulario cuando el envío sea exitoso. ¿Hay alguna buena manera de configurar _set_ defaultValue/defaultChecked etc. en el valor actual? – tkalve

+1

se agregó acceptChanges método –

+0

Gracias. Hice algunos cambios más agregando el campo numérico. :) –

10

De jQuery Docs:

//This applies to whole form 
$('#formID').change(function() { 
    alert('Form changed!'); 
}); 

Y se podría hacer como esto sólo para comprobar las entradas de usuario y tienen notificada, si tratan de salir sin guardar los cambios.

var inputsChanged = false; 
$('#formID input').change(function() { 
    inputsChanged = true; 
}); 

$(window).unload(function() { 
    if (inputsChanged === true) { 
    alert('Would you like to save your edits before exiting?'); 
    }  
}); 

jQuery API .change()

5

Me gustaría hacer esto con jQuery. Sería algo como esto (sólo un proyecto, puede ser necesario añadir/cambiar algo de código):

$(document).ready(function() { 
    $('#formId:input').each(function(key) { 
     $(this).change(function() { 
      $(this).addClass('dirty'); 
     }); 
    } 
}); 

Entonces, antes de la publicación, compruebe si hay una entrada sucia. Incluso puedes agregar un poco de color usando la clase css sucia.

EDIT: typo fijo 'cambiado' a 'cambio'

8

Resucitando esta vieja pregunta porque pensé en una manera más simple/mejor. En lugar de escuchar a los eventos en las distintas entradas, puede serializar los datos de forma inicial, almacenarlo, y luego serializarlo de nuevo más tarde y comprobar si se ha cambiado, así:

var originalFormData = $('form#formId').serialize(); 
function checkFormChanged() { 
    if(originalFormData !== $('form#formId').serialize()) { 
     //it's dirty! 
    } 
} 

Una ventaja adicional es que si el usuario hace un cambio y luego revierte, este cheque informará el formulario como limpio.

Cuestiones relacionadas