我需要在 ASP .Net 应用程序中实现“未保存的更改”提示。如果用户修改了 Web 表单上的控件,并在保存之前尝试离开,则应出现提示,警告他们有未保存的更改,并为他们提供取消并留在当前页面的选项。如果用户未触摸任何控件,则不应显示提示。
理想情况下,我想在 JavaScript 中实现它,但在我开始滚动我自己的代码之前,是否有任何现有的框架或推荐的设计模式来实现这一目标?理想情况下,我希望能够以最少的更改轻松地在多个页面中重复使用。
我需要在 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")
指的是所有输入、文本区域、选择和按钮元素。
一块拼图:
/**
* 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;
}
另一个:
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 函数来判断表单信息是否“脏”
<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()">
并在代码隐藏中,将触发器添加到输入字段以及重置提交/取消按钮....
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 事件。IT 还会查找任何提交或重置按钮以重置指示已发生更改的标志。
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。
希望这对必须实现类似功能的其他人有所帮助。