Обнаружение несохраненных изменений - PullRequest
87 голосов
/ 01 октября 2008

У меня есть требование для реализации приглашения «Несохраненные изменения» в приложении ASP .Net. Если пользователь изменяет элементы управления в веб-форме и пытается уйти перед сохранением, должен появиться запрос, предупреждающий их об несохраненных изменениях, и предоставляющий им возможность отменить и остаться на текущей странице. Подсказка не должна отображаться, если пользователь не коснулся ни одного из элементов управления.

В идеале я хотел бы реализовать это в JavaScript, но прежде чем идти по пути развертывания собственного кода, существуют ли какие-либо платформы или рекомендуемые шаблоны проектирования для достижения этой цели? В идеале я хотел бы, чтобы что-то можно было легко использовать на нескольких страницах с минимальными изменениями.

Ответы [ 15 ]

2 голосов
/ 08 июля 2014
      var unsaved = false;
    $(":input").change(function () {         
        unsaved = true;
    });

    function unloadPage() {         
        if (unsaved) {             
          alert("You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?");
        }
    } 

window.onbeforeunload = unloadPage;

2 голосов
/ 14 февраля 2012

Я расширил предложение Slace, приведенное выше, чтобы включить большинство редактируемых элементов, а также исключить определенные элементы (с CSS-стилем, называемым здесь "srSearch"), от установки флага грязного состояния.

<script type="text/javascript">
        var _isDirty = false;
        $(document).ready(function () {            

            // Set exclude CSS class on radio-button list elements
            $('table.srSearch input:radio').addClass("srSearch");

            $("input[type='text'],input[type='radio'],select,textarea").not(".srSearch").change(function () {
                _isDirty = true;
            });
        });

        $(window).bind('beforeunload', function () {
            if (_isDirty) {
                return 'You have unsaved changes.';
            }
        });        

1 голос
/ 02 октября 2008

Это именно то, для чего был создан плагин Fleegix.js fleegix.form.diff (http://js.fleegix.org/plugins/form/diff). Сериализация исходного состояния формы при загрузке с использованием fleegix.form.toObject (http://js.fleegix.org/ref#fleegix.form.toObject) и сохраните его в переменной, затем сравните с текущим состоянием, используя fleegix.form.diff при выгрузке. Easy as pie.

0 голосов
/ 06 июля 2015

В IE document.ready не будет работать должным образом, он обновит значения ввода.

, поэтому нам нужно связать событие загрузки внутри функции document.ready, которая также будет обрабатывать браузер IE.

ниже - код, который вы должны поместить в функцию document.ready.

 $(document).ready(function () {
   $(window).bind("load", function () { 
    $("input, select").change(function () {});
   });
});
0 голосов
/ 01 октября 2008

Один метод , использующий массивы для хранения переменных, чтобы можно было отслеживать изменения.

Вот очень простой метод обнаружения изменений , но все остальное не так элегантно.

Еще один довольно простой и маленький метод из Farfetched Blog :

<body onLoad="lookForChanges()" onBeforeUnload="return warnOfUnsavedChanges()">
<form>
<select name=a multiple>
 <option value=1>1
 <option value=2>2
 <option value=3>3
</select>
<input name=b value=123>
<input type=submit>
</form>

<script>
var changed = 0;
function recordChange() {
 changed = 1;
}
function recordChangeIfChangeKey(myevent) {
 if (myevent.which && !myevent.ctrlKey && !myevent.ctrlKey)
  recordChange(myevent);
}
function ignoreChange() {
 changed = 0;
}
function lookForChanges() {
 var origfunc;
 for (i = 0; i < document.forms.length; i++) {
  for (j = 0; j < document.forms[i].elements.length; j++) {
   var formField=document.forms[i].elements[j];
   var formFieldType=formField.type.toLowerCase();
   if (formFieldType == 'checkbox' || formFieldType == 'radio') {
    addHandler(formField, 'click', recordChange);
   } else if (formFieldType == 'text' || formFieldType == 'textarea') {
    if (formField.attachEvent) {
     addHandler(formField, 'keypress', recordChange);
    } else {
     addHandler(formField, 'keypress', recordChangeIfChangeKey);
    }
   } else if (formFieldType == 'select-multiple' || formFieldType == 'select-one') {
    addHandler(formField, 'change', recordChange);
   }
  }
  addHandler(document.forms[i], 'submit', ignoreChange);
 }
}
function warnOfUnsavedChanges() {
 if (changed) {
  if ("event" in window) //ie
   event.returnValue = 'You have unsaved changes on this page, which will be discarded if you leave now. Click "Cancel" in order to save them first.';
  else //netscape
   return false;
 }
}
function addHandler(target, eventName, handler) {
 if (target.attachEvent) {
  target.attachEvent('on'+eventName, handler);
 } else {
  target.addEventListener(eventName, handler, false);
 }
}
</script>
...