【发布时间】:2011-06-01 13:12:44
【问题描述】:
我有一个由<% Ajax.BeginForm() {} %> 生成的表单,其中包含很多输入和 texareas。
当输入值发生变化时,我需要了解它并将输入和表单标记为“脏”。如果用户试图离开页面而不保存,我会要求他或她确认放弃更改。
有什么建议吗?
【问题讨论】:
标签: jquery asp.net-mvc-2 asp.net-ajax
我有一个由<% Ajax.BeginForm() {} %> 生成的表单,其中包含很多输入和 texareas。
当输入值发生变化时,我需要了解它并将输入和表单标记为“脏”。如果用户试图离开页面而不保存,我会要求他或她确认放弃更改。
有什么建议吗?
【问题讨论】:
标签: jquery asp.net-mvc-2 asp.net-ajax
您可以使用 jquery 插件dirrty 来识别表单脏。
https://github.com/rubentd/dirrty
在 on("dirty") 事件中将一些全局变量设置为 true 以识别表单已更改。
处理 window.onbeforeunload 或 $(window).unload() 事件并根据该变量值获得用户的确认。
这个插件的优点是你可以使用'on("clean") 事件再次将表单更改为原始值进行追踪
【讨论】:
我会用 jQuery 来做这件事。大概是这样的(只是一个草稿,您可能需要添加/更改一些代码):
$(document).ready(function() {
$('#formId:input').each(function(key) {
$(this).change(function() {
$(this).addClass('dirty');
});
});
});
然后,在 POST 之前,检查是否有脏输入。您甚至可以使用脏 css 类添加一些颜色。
编辑:错字将“更改”固定为“更改”
【讨论】:
来自 jQuery 文档:
//This applies to whole form
$('#formID').change(function() {
alert('Form changed!');
});
如果用户尝试退出而不保存更改,您可以这样做以仅检查输入并通知用户。
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?');
}
});
【讨论】:
复活这个老问题,因为我想到了一种更简单/更好的方法。您可以序列化初始表单数据,存储它,然后稍后再次序列化它并检查它是否已更改,而不是监听各种输入上的事件,如下所示:
var originalFormData = $('form#formId').serialize();
function checkFormChanged() {
if(originalFormData !== $('form#formId').serialize()) {
//it's dirty!
}
}
这里的另一个好处是,如果用户进行了更改然后还原它,此检查将报告表单是干净的。
【讨论】:
html 控件包含一个保存原始值的属性。您可以将此值与当前值进行比较,看看是否有任何变化。
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
}
}
});
}
【讨论】: