yes example javascript asp.net prompt

javascript - example - Detectando cambios no guardados



jquery confirm dialog (15)

A continuación, se usa la función onbeforeunload del navegador y jquery para capturar cualquier evento onchange. También busca cualquier botón de envío o reinicio para restablecer el indicador que indica que se han producido cambios.

dataChanged = 0; // global variable flags unsaved changes function bindForChange(){ $(''input,checkbox,textarea,radio,select'').bind(''change'',function(event) { dataChanged = 1}) $('':reset,:submit'').bind(''click'',function(event) { dataChanged = 0 }) } function askConfirm(){ if (dataChanged){ return "You have some unsaved changes. Press OK to continue without saving." } } window.onbeforeunload = askConfirm; window.onload = bindForChange;

Tengo un requerimiento para implementar un indicador de "Cambios no guardados" en una aplicación ASP .Net. Si un usuario modifica los controles en un formulario web e intenta salir de él antes de guardarlo, debería aparecer un aviso que le advierta que tiene cambios no guardados, y le dará la opción de cancelar y permanecer en la página actual. El aviso no debería mostrarse si el usuario no ha tocado ninguno de los controles.

Idealmente, me gustaría implementar esto en JavaScript, pero antes de ir por el camino de rodar mi propio código, ¿hay marcos existentes o patrones de diseño recomendados para lograr esto? Idealmente, me gustaría algo que pueda reutilizarse fácilmente en varias páginas con cambios mínimos.


Aquí hay una solución javascript / jquery que es simple. Representa "undos" por parte del usuario, está encapsulado dentro de una función para facilitar la aplicación y no falla al enviar. Simplemente llame a la función y pase la identificación de su formulario.

Esta función serializa el formulario una vez cuando se carga la página, y nuevamente antes de que el usuario abandone la página. Si los dos estados de formulario son diferentes, se muestra el mensaje.

Pruébelo: http://jsfiddle.net/skibulk/Ydt7Y/

function formUnloadPrompt(formSelector) { var formA = $(formSelector).serialize(), formB, formSubmit = false; // Detect Form Submit $(formSelector).submit( function(){ formSubmit = true; }); // Handle Form Unload window.onbeforeunload = function(){ if (formSubmit) return; formB = $(formSelector).serialize(); if (formA != formB) return "Your changes have not been saved."; }; } $(function(){ formUnloadPrompt(''form''); });


Detectar cambios en el formulario con jQuery es muy simple:

var formInitVal = $(''#formId'').serialize(); // detect form init value after form is displayed // check for form changes if ($(''#formId'').serialize() != formInitVal) { // show confirmation alert }


En IE document.ready no funcionará correctamente, actualizará los valores de entrada.

así que tenemos que vincular el evento de carga dentro de la función document.ready que también se manejará para el navegador IE.

a continuación está el código que debe poner dentro de la función document.ready.

$(document).ready(function () { $(window).bind("load", function () { $("input, select").change(function () {}); }); });


En la página .aspx, necesita una función de Javascript para saber si la información del formulario está "sucia" o no.

<script language="javascript"> var isDirty = false; function setDirty() { isDirty = true; } function checkSave() { var sSave; if (isDirty == true) { sSave = window.confirm("You have some changes that have not been saved. Click OK to save now or CANCEL to continue without saving."); if (sSave == true) { document.getElementById(''__EVENTTARGET'').value = ''btnSubmit''; document.getElementById(''__EVENTARGUMENT'').value = ''Click''; window.document.formName.submit(); } else { return true; } } } </script> <body class="StandardBody" onunload="checkSave()">

y en el código subyacente, agregue los desencadenantes a los campos de entrada, así como los reinicios en los botones de envío / cancelación ...

btnSubmit.Attributes.Add("onclick", "isDirty = 0;"); btnCancel.Attributes.Add("onclick", "isDirty = 0;"); txtName.Attributes.Add("onchange", "setDirty();"); txtAddress.Attributes.Add("onchange", "setDirty();"); //etc..


Esto es exactamente lo que se creó para el plugin fleegix.form.diff ( ). Serialice el estado inicial del formulario en carga utilizando fleegix.form.toObject ( ) y guárdelo en una variable, luego compare el estado actual con fleegix.form.diff en la descarga. Muy fácil.


Expandí la sugerencia de Slace anterior, para incluir la mayoría de los elementos editables y también excluir ciertos elementos (con un estilo CSS llamado "srSearch" aquí) de causar que se establezca la bandera sucia.

<script type="text/javascript"> var _isDirty = false; $(document).ready(function () { // Set exclude CSS class on radio-button list elements $(''table.srSearch input:radio'').addClass("srSearch"); $("input[type=''text''],input[type=''radio''],select,textarea").not(".srSearch").change(function () { _isDirty = true; }); }); $(window).bind(''beforeunload'', function () { if (_isDirty) { return ''You have unsaved changes.''; } });


Gracias por las respuestas a todos. Terminé implementando una solución usando JQuery y el complemento Protect-Data . Esto me permite aplicar automáticamente la supervisión a todos los controles en una página.

Sin embargo, hay algunas advertencias, especialmente cuando se trata de una aplicación ASP .Net:

  • Cuando un usuario elige la opción cancelar, la función doPostBack generará un error de JavaScript. Tuve que poner manualmente un try-catch alrededor de la llamada .submit dentro de doPostBack para suprimirlo.

  • En algunas páginas, un usuario puede realizar una acción que realiza una devolución de datos a la misma página, pero no es un guardado. Esto da como resultado cualquier reinicio de la lógica de JavaScript, por lo que cree que nada ha cambiado después de la devolución de datos cuando algo puede tener. Tuve que implementar un cuadro de texto oculto que se publica con la página, y se usa para mantener un valor booleano simple que indica si los datos están sucios. Esto se mantiene en las devoluciones.

  • Es posible que desee algunas devoluciones en la página para no activar el cuadro de diálogo, como un botón Guardar. En este caso, puede usar JQuery para agregar una función OnClick que establece window.onbeforeunload en null.

Espero que esto sea útil para cualquier otra persona que tenga que implementar algo similar.


Hace poco contribuí con un plugin jQuery de código abierto llamado dirtyForms .

El complemento está diseñado para trabajar con HTML añadido dinámicamente, admite múltiples formularios, puede admitir prácticamente cualquier marco de diálogo, vuelve al navegador antes del diálogo de descarga, tiene un marco de ayuda enchufable para soportar el estado sucio de los editores personalizados (se incluye un complemento tinyMCE) , funciona dentro de iFrames, y el estado sucio se puede configurar o restablecer a voluntad.

dirtyForms


La siguiente solución funciona para prototipos (probados en FF, IE 6 y Safari). Utiliza un observador de formulario genérico (que activa la forma: cambia cuando se han modificado los campos de la forma), que también puede usar para otras cosas.

/* use this function to announce changes from your own scripts/event handlers. * Example: onClick="makeDirty($(this).up(''form''));" */ function makeDirty(form) { form.fire("form:changed"); } function handleChange(form, event) { makeDirty(form); } /* generic form observer, ensure that form:changed is being fired whenever * a field is being changed in that particular for */ function setupFormChangeObserver(form) { var handler = handleChange.curry(form); form.getElements().each(function (element) { element.observe("change", handler); }); } /* installs a form protector to a form marked with class ''protectForm'' */ function setupProtectForm() { var form = $$("form.protectForm").first(); /* abort if no form */ if (!form) return; setupFormChangeObserver(form); var dirty = false; form.observe("form:changed", function(event) { dirty = true; }); /* submitting the form makes the form clean again */ form.observe("submit", function(event) { dirty = false; }); /* unfortunatly a propper event handler doesn''t appear to work with IE and Safari */ window.onbeforeunload = function(event) { if (dirty) { return "There are unsaved changes, they will be lost if you leave now."; } }; } document.observe("dom:loaded", setupProtectForm);


Solución general Compatible con múltiples formularios en una página determinada ( solo copie y pegue en su proyecto )

$(document).ready(function() { $(''form :input'').change(function() { $(this).closest(''form'').addClass(''form-dirty''); }); $(window).bind(''beforeunload'', function() { if($(''form:not(.ignore-changes).form-dirty'').length > 0) { return ''You have unsaved changes, are you sure you want to discard them?''; } }); $(''form'').bind(''submit'',function() { $(this).closest(''form'').removeClass(''form-dirty''); return true; }); });

Nota: Esta solución se combina con las soluciones de otros para crear una solución integrada general.

caracteristicas:

  • Solo copia y pega en tu aplicación.
  • Admite múltiples formularios.
  • Puede aplicar estilos o acciones a los formularios sucios, ya que tienen la clase "form-dirty".
  • Puede excluir algunos formularios agregando la clase ''ignorar cambios''.

Una pieza del rompecabezas:

/** * Determines if a form is dirty by comparing the current value of each element * with its default value. * * @param {Form} form the form to be checked. * @return {Boolean} <code>true</code> if the form is dirty, <code>false</code> * otherwise. */ function formIsDirty(form) { for (var i = 0; i < form.elements.length; i++) { var element = form.elements[i]; var type = element.type; if (type == "checkbox" || type == "radio") { if (element.checked != element.defaultChecked) { return true; } } else if (type == "hidden" || type == "password" || type == "text" || type == "textarea") { if (element.value != element.defaultValue) { return true; } } else if (type == "select-one" || type == "select-multiple") { for (var j = 0; j < element.options.length; j++) { if (element.options[j].selected != element.options[j].defaultSelected) { return true; } } } } return false; }

Y otro :

window.onbeforeunload = function(e) { e = e || window.event; if (formIsDirty(document.forms["someForm"])) { // For IE and Firefox if (e) { e.returnValue = "You have unsaved changes."; } // For Safari return "You have unsaved changes."; } };

Envuélvelo todo, y ¿qué obtienes?

var confirmExitIfModified = (function() { function formIsDirty(form) { // ...as above } return function(form, message) { window.onbeforeunload = function(e) { e = e || window.event; if (formIsDirty(document.forms[form])) { // For IE and Firefox if (e) { e.returnValue = message; } // For Safari return message; } }; }; })(); confirmExitIfModified("someForm", "You have unsaved changes.");

Probablemente también desee cambiar el registro del controlador de eventos beforeunload para usar el registro de eventos de LIBRARY_OF_CHOICE .


Usando jQuery:

var _isDirty = false; $("input[type=''text'']").change(function(){ _isDirty = true; }); // replicate for other input types and selects

Combine con onunload / onbeforeunload métodos según sea necesario.

De los comentarios, la siguiente referencia hace referencia a todos los campos de entrada, sin duplicar el código:

$('':input'').change(function () {

Usar $(":input") refiere a todos los elementos de entrada, área de texto, selección y botón.


Un método , usando matrices para contener las variables para que los cambios puedan ser rastreados.

Aquí hay un método muy simple para detectar cambios , pero el resto no es tan elegante.

Otro método que es bastante simple y pequeño, del blog Farfetched :

<body onLoad="lookForChanges()" onBeforeUnload="return warnOfUnsavedChanges()"> <form> <select name=a multiple> <option value=1>1 <option value=2>2 <option value=3>3 </select> <input name=b value=123> <input type=submit> </form> <script> var changed = 0; function recordChange() { changed = 1; } function recordChangeIfChangeKey(myevent) { if (myevent.which && !myevent.ctrlKey && !myevent.ctrlKey) recordChange(myevent); } function ignoreChange() { changed = 0; } function lookForChanges() { var origfunc; for (i = 0; i < document.forms.length; i++) { for (j = 0; j < document.forms[i].elements.length; j++) { var formField=document.forms[i].elements[j]; var formFieldType=formField.type.toLowerCase(); if (formFieldType == ''checkbox'' || formFieldType == ''radio'') { addHandler(formField, ''click'', recordChange); } else if (formFieldType == ''text'' || formFieldType == ''textarea'') { if (formField.attachEvent) { addHandler(formField, ''keypress'', recordChange); } else { addHandler(formField, ''keypress'', recordChangeIfChangeKey); } } else if (formFieldType == ''select-multiple'' || formFieldType == ''select-one'') { addHandler(formField, ''change'', recordChange); } } addHandler(document.forms[i], ''submit'', ignoreChange); } } function warnOfUnsavedChanges() { if (changed) { if ("event" in window) //ie event.returnValue = ''You have unsaved changes on this page, which will be discarded if you leave now. Click "Cancel" in order to save them first.''; else //netscape return false; } } function addHandler(target, eventName, handler) { if (target.attachEvent) { target.attachEvent(''on''+eventName, handler); } else { target.addEventListener(eventName, handler, false); } } </script>


var unsaved = false; $(":input").change(function () { unsaved = true; }); function unloadPage() { if (unsaved) { alert("You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?"); } }

window.onbeforeunload = descargar la página;