Самое простое и элегантное решение для мужчин:
function checkForm(form) // Submit button clicked
{
form.myButton.disabled = true;
form.myButton.value = "Please wait...";
return true;
}
Используя jQuery:
var _isDirty = false;
$("input[type='text']").change(function(){
_isDirty = true;
});
// replicate for other input types and selects
Объединение с onunload
/ onbeforeunload
методы как требуется.
Из комментариев, следующие ссылки все поля ввода, не копируя код:
$(':input').change(function () {
Используя $(":input")
относится ко всему входу, текстовой области, выберите, и элементы кнопки.
Это точно, для чего был создан плагин 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
на, разгружаются. Легкий как круг.
На .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()">
и в codebehind, добавьте триггеры к полям ввода, а также сбросу на представлении/кнопках отмены....
btnSubmit.Attributes.Add("onclick", "isDirty = 0;");
btnCancel.Attributes.Add("onclick", "isDirty = 0;");
txtName.Attributes.Add("onchange", "setDirty();");
txtAddress.Attributes.Add("onchange", "setDirty();");
//etc..
Одна часть загадки:
/**
* 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 и Защищать-данные плагин. Это позволяет мне автоматически применять контроль ко всем средствам управления на странице.
существует несколько протестов однако, особенно при контакте с приложением .NET ASP:
, Когда пользователь выберет опцию отмены, функция doPostBack бросит ошибку JavaScript. Я должен был вручную поместить выгоду попытки вокруг вызова .submit в doPostBack для подавления его.
На некоторых страницах, пользователь мог выполнить действие, которое выполняет обратную передачу к той же странице, но не является сохранением. Это приводит к любому сбросу логики JavaScript, таким образом, он думает, что ничто не изменилось после обратной передачи, когда что-то может иметь. Я должен был реализовать скрытое текстовое поле, которое получает отправленную спину со страницей и используется для содержания простого булева значения, указывающего, грязны ли данные. Это сохраняется через обратные передачи.
можно хотеть, чтобы некоторые обратные передачи на странице не инициировали диалоговое окно, такое как кнопка Save. В этом случае можно использовать JQuery для добавления функции OnClick, которая устанавливает window.onbeforeunload в NULL.
, Надо надеяться, это полезно для кого-либо еще, кто должен реализовать что-то подобное.
Один метод , с помощью массивов для содержания переменных, таким образом, изменения могут быть прослежены.
Вот очень простой метод для , обнаруживают изменения , но остальное не так изящно.
Другой метод, который является довольно простым и маленьким, от Неправдоподобный Блог :
<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>
Следующее решение работает для прототипа (протестировано в FF, IE 6 и Safari). Он использует общий наблюдатель формы (который запускает форму: изменено, когда какие-либо поля формы были изменены), который вы можете использовать и для других вещей.
/* use this function to announce changes from your own scripts/event handlers.
* Example: onClick="makeDirty($(this).up('form'));"
*/
function makeDirty(form) {
form.fire("form:changed");
}
function handleChange(form, event) {
makeDirty(form);
}
/* generic form observer, ensure that form:changed is being fired whenever
* a field is being changed in that particular for
*/
function setupFormChangeObserver(form) {
var handler = handleChange.curry(form);
form.getElements().each(function (element) {
element.observe("change", handler);
});
}
/* installs a form protector to a form marked with class 'protectForm' */
function setupProtectForm() {
var form = $$("form.protectForm").first();
/* abort if no form */
if (!form) return;
setupFormChangeObserver(form);
var dirty = false;
form.observe("form:changed", function(event) {
dirty = true;
});
/* submitting the form makes the form clean again */
form.observe("submit", function(event) {
dirty = false;
});
/* unfortunatly a propper event handler doesn't appear to work with IE and Safari */
window.onbeforeunload = function(event) {
if (dirty) {
return "There are unsaved changes, they will be lost if you leave now.";
}
};
}
document.observe("dom:loaded", setupProtectForm);
Далее для захвата любого события onchange используется функция браузера onbeforeunload и jquery. ИТ-специалисты также ищут любые кнопки отправки или сброса, чтобы сбросить флаг, указывающий, что изменения произошли.
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;