Обнаружение изменений данных в формах с помощью 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!');
}