我需要在ASP .Net应用程序中实现"未保存的更改"提示.如果用户修改了Web表单上的控件,并尝试在保存之前导航,则会出现一个提示,提示他们有未保存的更改,并为他们提供取消和保留在当前页面的选项.如果用户未触及任何控件,则不应显示提示.
理想情况下,我想在JavaScript中实现它,但在我开始编写自己的代码之前,是否有任何现有的框架或推荐的设计模式来实现这一目标?理想情况下,我希望能够轻松地在多个页面上重复使用,而且变化很小.
使用jQuery:
var _isDirty = false; $("input[type='text']").change(function(){ _isDirty = true; }); // replicate for other input types and selects
与onunload
/ 结合onbeforeunload
根据需要方法.
从注释中,以下引用所有输入字段,而不重复代码:
$(':input').change(function () {
使用$(":input")
是指所有输入,textarea,select和按钮元素.
一块拼图:
/** * 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}true
if the form is dirty,false
* 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; }
而另一个:
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."; } };
总结一下,你得到了什么?
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.");
您可能还想更改beforeunload
事件处理程序的注册以使用LIBRARY_OF_CHOICE
事件注册.
在.aspx页面中,您需要一个Javascript函数来判断表单信息是否"脏"
并在代码隐藏中,将触发器添加到输入字段以及重置提交/取消按钮....
btnSubmit.Attributes.Add("onclick", "isDirty = 0;"); btnCancel.Attributes.Add("onclick", "isDirty = 0;"); txtName.Attributes.Add("onchange", "setDirty();"); txtAddress.Attributes.Add("onchange", "setDirty();"); //etc..
以下使用浏览器的onbeforeunload函数和jquery来捕获任何onchange事件.它还会查找任何提交或重置按钮以重置指示已发生更改的标志.
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;
感谢大家的回复.我最终使用JQuery和Protect-Data插件实现了一个解决方案.这允许我自动将监控应用于页面上的所有控件.
但是有一些注意事项,特别是在处理ASP .Net应用程序时:
当用户选择取消选项时,doPostBack函数将抛出JavaScript错误.我不得不手动在doPostBack中的.submit调用周围放置一个try-catch来抑制它.
在某些页面上,用户可以执行执行回发到同一页面的操作,但不是保存.这会导致任何JavaScript逻辑重置,因此它认为在回发之后没有任何内容发生变化.我必须实现一个隐藏的文本框,该文本框与页面一起回发,并用于保存一个简单的布尔值,指示数据是否脏.这会在回发中持续存在.
您可能希望页面上的一些回发不触发对话框,例如"保存"按钮.在这种情况下,您可以使用JQuery添加一个OnClick函数,该函数将window.onbeforeunload设置为null.
希望这对任何必须实现类似功能的人都有帮助.
以下解决方案适用于原型(在FF,IE 6和Safari中测试).它使用通用表单观察器(触发表单:在修改表单的任何字段时更改),您也可以将其用于其他内容.
/* 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);
这是一个简单的javascript/jquery解决方案.它由用户解释"undos",它被封装在一个函数中以便于应用,并且它在提交时不会失败.只需调用该函数并传递表单的ID即可.
此功能在加载页面时将表单序列化一次,并在用户离开页面之前再次序列化表单.如果两个表单状态不同,则会显示提示.
尝试一下: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'); });
常规解决方案支持给定页面中的多个表单(只需复制并粘贴到项目中)
$(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; }); });
注意:此解决方案与其他解决方案相结合,可创建通用集成解决方案.
特征:
只需复制并粘贴到您的应用中即可.
支持多种形式.
你可以设置样式或使动作变脏,因为它们是"形式脏"的类.
您可以通过添加"忽略更改"类来排除某些表单.