检测未保存的更改

IT技术 javascript asp.net prompt
2021-01-30 23:05:57

我需要在 ASP .Net 应用程序中实现“未保存的更改”提示。如果用户修改了 Web 表单上的控件,并在保存之前尝试离开,则应出现提示,警告他们有未保存的更改,并为他们提供取消并留在当前页面的选项。如果用户未触摸任何控件,则不应显示提示。

理想情况下,我想在 JavaScript 中实现它,但在我开始滚动我自己的代码之前,是否有任何现有的框架或推荐的设计模式来实现这一目标?理想情况下,我希望能够以最少的更改轻松地在多个页面中重复使用。

6个回答

使用jQuery:

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

根据需要结合onunload/onbeforeunload方法。

从注释中,以下引用了所有输入字段,没有重复代码:

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

使用$(":input")指的是所有输入、文本区域、选择和按钮元素。

请记住,change对于文本输入,在离开/失去焦点时触发一次,而input在每次击键时触发。(我通常将它与changeJQuery 的一起使用one(),以防止多个事件。)
2021-03-15 23:05:57
Upvote 因为我使用了这个解决方案,但有一个稍微简单的方法。如果您使用: $(':input').change(function () { 那么这适用于所有输入字段,您不需要为其他输入类型复制。 $(":input") 选择所有输入,textarea 、选择和按钮元素。
2021-03-19 23:05:57
只是一个提示。如果表单是脏的,它仍然并不意味着它包含真正改变的数据。为了获得更好的可用性,您必须实际将旧数据与新数据进行比较;)
2021-03-25 23:05:57
我认为这在 Firefox 中可能有问题。如果用户修改表单,然后单击浏览器的刷新按钮,页面将重新加载,Firefox 将使用用户以前的条目填充表单 - 不会触发更改事件。现在表单将变脏,但除非用户进行另一次编辑,否则不会设置标志。
2021-03-26 23:05:57

一块拼图:

/**
 * 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的事件注册。

谢谢,这很棒。你能告诉我们如何注册jquery吗?除非我在同一个 html 页面上有这个脚本,否则它不会触发。如果我将它放在外部 .js 文件中,则它不起作用。
2021-03-14 23:05:57
这个脚本很棒,但对我来说,它在提交表单时也显示了警告消息。我通过在 onClick ( onclick="window.onbeforeunload=null") 中解除绑定事件来解决这个问题
2021-03-23 23:05:57
在 Firefox 9.0.1 中,我没有收到任何消息。我有一条默认消息说“您确定要离开该页面吗?某些数据可能会丢失”(这或多或少是我的非英语浏览器向我显示的消息的翻译)
2021-04-02 23:05:57
我喜欢比较 defaultValue 等属性而不是设置脏位的方法。这意味着如果有人更改了一个字段,然后又将其改回,那么表单将不会报告为脏。
2021-04-06 23:05:57

在 .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;
嗨,当我放置一个复选框时,colin reset 不起作用,最初我选中它并再次取消选中但警报被触发,当用户取消选中该复选框时我如何重置
2021-03-14 23:05:57

谢谢大家的回复。我最终使用 JQuery 和Protect-Data插件实现了一个解决方案这允许我自动将监控应用到页面上的所有控件。

但是,有一些警告,尤其是在处理 ASP .Net 应用程序时:

  • 当用户选择取消选项时,doPostBack 函数将抛出一个 JavaScript 错误。我不得不手动在 doPostBack 中的 .submit 调用周围放置一个 try-catch 来抑制它。

  • 在某些页面上,用户可以执行回发到同一页面但不是保存的操作。这会导致任何 JavaScript 逻辑重置,因此它认为在回发后没有任何变化,当某些事情可能发生时。我必须实现一个与页面一起回发的隐藏文本框,并用于保存一个简单的布尔值,指示数据是否脏。这在回发中持续存在。

  • 您可能希望页面上的某些回发不触发对话框,例如保存按钮。在这种情况下,您可以使用 JQuery 添加一个 OnClick 函数,该函数将 window.onbeforeunload 设置为 null。

希望这对必须实现类似功能的其他人有所帮助。