Предупреждение о несохраненных изменениях формы
Я хочу написать код JQuery в главном файле, так что если там, если пользователь меняет страницу и есть какие-либо несохраненные изменения, пользователь должен получить предупреждение.
Я получил один ответ от этого: ссылка
Однако в большинстве решений мне придется писать код на всех страницах. Я хочу, чтобы он писал только в одном месте, так что всем не нужно беспокоиться, чтобы написать его в своих модулях. Мой код похож:
<script type="text/javascript">
var isChange;
$(document).ready(function () {
$("input[type='text']").change(function () {
isChange = true;
})
});
$(window).unload(function () {
if (isChange) {
alert('Handler for .unload() called.');
}
});
</script>
Но каждый раз, когда я вношу изменения в текстовые поля, событие change() не запускается.
Что может быть неправильным в коде?
EDIT:
Я изменил .change() на .click и уволен. Я использую jquery 1.4.1.. это из-за версии jquery, которая меняет() не работает?
Ответы
Ответ 1
Это то, что я использую, поместите весь этот код в отдельный файл JS и загрузите его в свой заголовочный файл, чтобы вам не нужно было копировать это снова и снова:
var unsaved = false;
$(":input").change(function(){ //triggers change in all input fields including text type
unsaved = true;
});
function unloadPage(){
if(unsaved){
return "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;
РЕДАКТИРОВАТЬ за $ не найдено:
Эта ошибка может быть вызвана только одной из трех причин:
- Ваш файл JavaScript неправильно загружается на вашу страницу
- У вас испорченная версия jQuery. Это может произойти из-за того, что кто-то отредактировал основной файл, или плагин мог перезаписать переменную $.
- У вас работает JavaScript до полной загрузки страницы и до полной загрузки jQuery.
Убедитесь, что весь код JS находится в этом:
$(document).ready(function () {
//place above code here
});
Изменить исключение кнопки Сохранить/Отправить/Отправить
$('#save').click(function() {
unsaved = false;
});
Изменить для работы с динамическими входами
// Another way to bind the event
$(window).bind('beforeunload', function() {
if(unsaved){
return "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?";
}
});
// Monitor dynamic inputs
$(document).on('change', ':input', function(){ //triggers change in all input fields including text type
unsaved = true;
});
Добавьте приведенный выше код в свой файл alert_unsaved_changes.js.
Надеюсь это поможет.
Ответ 2
Версия, использующая сериализацию формы:
Выполните этот код, когда Дом готов:
// Store form state at page load
var initial_form_state = $('#myform').serialize();
// Store form state after form submit
$('#myform').submit(function(){
initial_form_state = $('#myform').serialize();
});
// Check form changes before leaving the page and warn user if needed
$(window).bind('beforeunload', function(e) {
var form_state = $('#myform').serialize();
if(initial_form_state != form_state){
var message = "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?";
e.returnValue = message; // Cross-browser compatibility (src: MDN)
return message;
}
});
Если пользователь изменил поле, а затем откат вручную, предупреждение не отображается
Ответ 3
событие изменения запускается после того, как пользователь размывается от ввода не на каждый введенный символ.
Если вам нужно, чтобы он вызывался каждый раз, когда что-то менялось (даже если фокус все еще находится в этом поле ввода), вам придется полагаться на комбинацию клавиш и кучу событий, чтобы отслеживать вставки/вырезания только с помощью мыши.
P.S.
Надеюсь, вы знаете, что ваш подход к обнаружению изменений не самый лучший? Если пользователь вводит какой-либо текст, покидает поле, а затем возвращает изменения, то script будет предупреждать его об измененном тексте.
Ответ 4
вы должны регистрировать события не только для ввода, но и для текстовых полей, если вы имеете в виду textarea с текстовым полем. Вы можете использовать keyup для isChange, чтобы вы не дождались размытия пользователя из этой области.
$("input[type='text'], textarea").keyup(function () {
isChange = true;
})
Ответ 5
Почему бы просто не связать событие с обратным вызовом change
?
$(":input").change(function()
{
$(window).unbind('unload').bind('unload',function()
{
alert('unsaved changes on the page');
});
});
В качестве дополнительного бонуса вы можете использовать confirm
и выбрать последний элемент, который вызвал событие изменения:
$(":input").change(function()
{
$(window).unbind('unload').bind('unload',(function(elem)
{//elem holds reference to changed element
return function(e)
{//get the event object:
e = e || window.event;
if (confirm('unsaved changes on the page\nDo you wish to save them first?'))
{
elem.focus();//select element
return false;//in jQuery this stops the event from completeing
}
}
}($(this)));//passed elem here, I passed it as a jQ object, so elem.focus() works
//pass it as <this>, then you'll have to do $(elem).focus(); or write pure JS
});
Если у вас есть кнопка сохранения, убедитесь, что это отвязывает событие разгрузки:
$('#save').click(function()
{
$(window).unbind('unload');
//rest of your code here
});
Ответ 6
Это действительно другая версия ответа @AlphaMale, но улучшена несколькими способами:
# Message displayed to user. Depending on browser and if it is a turbolink,
# regular link or user-driven navigation this may or may not display.
msg = "This page is asking you to confirm that you want to leave - data you have entered may not be saved."
# Default state
unsaved = false
# Mark the page as having unsaved content
$(document).on 'change', 'form[method=post]:not([data-remote]) :input', -> unsaved = true
# A new page was loaded via Turbolinks, reset state
$(document).on 'page:change', -> setTimeout (-> unsaved = false), 10
# The user submitted the form (to save) so no need to ask them.
$(document).on 'submit', 'form[method=post]', ->
unsaved = false
return
# Confirm with user if they try to go elsewhere
$(window).bind 'beforeunload', -> return msg if unsaved
# If page about to change via Turbolinks also confirm with user
$(document).on 'page:before-change', (event) ->
event.preventDefault() if unsaved && !confirm msg
Это лучше в следующих случаях:
- Это кофейник, который ИМХО автоматически делает его лучше.:)
- Он полностью основан на пузырьках событий, поэтому динамический контент автоматически обрабатывается (обновление @AlphaMale также имеет это).
- Он работает только с формами POST, поскольку формы GET не имеют данных, которые мы обычно хотим избежать потерять (т.е. формы GET, как правило, являются полями поиска и критериями фильтрации).
- Не обязательно привязываться к определенной кнопке для сохранения. В любое время, когда форма отправляется, мы предполагаем, что подача сохраняется.
- Turbolinks совместим. Если вам не нужно, просто удалите два привязки событий
page:
.
- Он разработан так, чтобы вы могли просто включить его вместе с остальной частью вашего JS, и весь ваш сайт будет защищен.
Ответ 7
Я использую функцию $('form').change
и т.д. для установки грязной битовой переменной. Не подходит для всех изменений (как и в предыдущих ответах), но улавливает все, что меня интересует, в моем приложении.