我需要在 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。
希望这对必须实现类似功能的其他人有所帮助。