Обнаружение изменений данных в формах с помощью jQuery
Я использую ASP.NET 2.0 с главной страницей, и мне было интересно, знал ли кто-нибудь о способе обнаружения, когда поля в пределах определенного <div>
или fieldset
были изменены (например, отмечены "IsDirty
')?
Ответы
Ответ 1
Вы можете связать событие Change для всех входов и пометить переменную как true. Вот так.
var somethingChanged = false;
$(document).ready(function() {
$('input').change(function() {
somethingChanged = true;
});
});
Но имейте в виду, что если пользователь что-то меняет, а затем возвращается к исходным значениям, он по-прежнему будет помечен как измененный.
ОБНОВЛЕНИЕ: Для определенного набора div или полей. Просто используйте идентификатор для данного набора полей или div. Пример:
var somethingChanged = false;
$(document).ready(function() {
$('#myDiv input').change(function() {
somethingChanged = true;
});
});
Ответ 2
Быстрое (но очень грязное) решение
Это быстро, но не позаботится о ctrl+z
или cmd+z
и даст ложное срабатывание при нажатии shift
, ctrl
или клавиши tab
:
$('#my-form').on('change keyup paste', ':input', function(e) {
// The form has been changed. Your code here.
});
Проверьте это с помощью этой скрипки.
Быстрое (менее грязное) решение
Это предотвратит ложные срабатывания клавиш shift
, ctrl
или tab
, но не будет обрабатывать ctrl+z
или cmd+z
:
$('#my-form').on('change keyup paste', ':input', function(e) {
var keycode = e.which;
if (e.type === 'paste' || e.type === 'change' || (
(keycode === 46 || keycode === 8) || // delete & backspace
(keycode > 47 && keycode < 58) || // number keys
keycode == 32 || keycode == 13 || // spacebar & return key(s) (if you want to allow carriage returns)
(keycode > 64 && keycode < 91) || // letter keys
(keycode > 95 && keycode < 112) || // numpad keys
(keycode > 185 && keycode < 193) || // ;=,-./' (in order)
(keycode > 218 && keycode < 223))) { // [\]' (in order))
// The form has been changed. Your code here.
}
});
Проверьте это с помощью этой скрипки.
Полное решение
Если вы хотите обрабатывать все дела, вам следует использовать:
// init the form when the document is ready or when the form is populated after an ajax call
$(document).ready(function() {
$('#my-form').find(':input').each(function(index, value) {
$(this).data('val', $(this).val());
});
})
$('#my-form').on('change paste', ':input', function(e) {
$(this).data('val', $(this).val());
// The form has been changed. Your code here.
});
$('#my-form').on('keyup', ':input', function(e) {
if ($(this).val() != $(this).data('val')) {
$(this).data('val', $(this).val());
// The form has been changed. Your code here.
}
});
Проверьте это с этой скрипкой.
Ответ 3
Простое и элегантное решение (оно обнаруживает изменения элементов формы в реальном времени):
var formChanged = false;
$('#my-div form').on('keyup change paste', 'input, select, textarea', function(){
formChanged = true;
});
Ответ 4
Для формы вы можете сериализовать содержимое при загрузке, а затем сравнить сериализацию позже, например:
$(function(){
var initdata=$('form').serialize();
$('form').submit(function(e){
e.preventDefault();
var nowdata=$('form').serialize();
if(initdata==nowdata) console.log('nothing changed'); else console.log('something changed');
// save
initdata=nowdata;
$.post('settings.php',nowdata).done(function(){
console.log('saved');
});
});
});
Ответ 5
Просто чтобы уточнить, потому что вопрос "внутри определенного набора полей /div ":
var somethingChanged = false;
$(document).ready(function() {
$('fieldset > input').change(function() {
somethingChanged = true;
});
});
или
var somethingChanged = false;
$(document).ready(function() {
$('div > input').change(function() {
somethingChanged = true;
});
});
Ответ 6
Вы можете дать fieldset или div идентификатор и связать событие изменения с ним... событие должно распространяться от внутренних дочерних элементов.
var somethingChanged = false;
$('#fieldset_id').change(function(e)
{
// e.target is the element which triggered the event
// console.log(e.target);
somethingChanged = true;
});
Кроме того, если вы хотите иметь одну функцию прослушивания событий, вы можете поместить событие изменения в форму и затем проверить, какой файл изменился:
$('#form_id').change(function(e)
{
var changedFieldset = $(e.target).parents('fieldset');
// do stuff
});
Ответ 7
Я придумал этот кусок кода в CoffeeScript (пока еще не тестировался на поле):
-
Добавить класс 'change_warning' в формы, которые следует отслеживать для изменений.
-
Добавить класс 'change_allowed' в кнопку сохранения.
change_warning.coffee:
window.ChangeWarning = {
save: ->
$(".change_warning").each (index,element) ->
$(element).data('serialized', $(element).serialize())
changed: (element) ->
$(element).serialize() != $(element).data('serialized')
changed_any: ->
$.makeArray($(".change_warning").map (index,element) -> ChangeWarning.changed(element)).some (f)->f
# AKA $(".change_warning").any (element) -> ChangeWarning.changed(element)
# But jQuery collections do not know the any/some method, yet (nor are they arrays)
change_allowed: ->
ChangeWarning.change_allowed_flag = true
beforeunload: ->
unless ChangeWarning.change_allowed_flag or not ChangeWarning.changed_any()
"You have unsaved changes"
}
$ ->
ChangeWarning.save()
$(".change_allowed").bind 'click', -> ChangeWarning.change_allowed()
$(window).bind 'beforeunload', -> ChangeWarning.beforeunload()
Ответ 8
.live
теперь устарела и заменена на .on
:
var confirmerSortie = false;
$(document).on('change', 'select', function() {
confirmerSortie = true;
});
$(document).on('change keypress', 'input', function() {
confirmerSortie = true;
});
$(document).on('change keypress', 'textarea', function() {
confirmerSortie = true;
});
Ответ 9
Следующее решение работало для меня:
$("#myDiv :input").change(function() { $("#myDiv").data("changed",true);});
}
if($("#myDiv").data("changed")) {
console.log('Form data changed hence proceed to submit');
}
else {
console.log('No change detected!');
}