Обнаружение изменений данных в формах с использованием jQuery - PullRequest
22 голосов
/ 30 апреля 2009

Я использую ASP.NET 2.0 с главной страницей, и мне было интересно, если кто-нибудь знает, как определить, когда поля в пределах определенного <div> или fieldset были изменены (например, помечены 'IsDirty)

Ответы [ 9 ]

43 голосов
/ 30 апреля 2009

Вы можете привязать событие 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; 
   }); 
});
26 голосов
/ 03 августа 2012

Быстрое (но очень грязное) решение

Это быстро, но не позаботится о 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. 
  }
});

Проверьте это с помощью этой скрипки.

21 голосов
/ 16 мая 2014

Простое и элегантное решение (в реальном времени обнаруживает изменения элементов формы):

var formChanged = false;

$('#my-div form').on('keyup change paste', 'input, select, textarea', function(){
    formChanged = true;
});
5 голосов
/ 30 апреля 2009

Просто чтобы уточнить, потому что вопрос "в пределах определенного набора полей / 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; 
   }); 
});
3 голосов
/ 06 апреля 2018

Для формы вы можете сериализовать содержимое при загрузке, а затем сравнить сериализацию позже, например ::

$(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');
        });
    });
});
2 голосов
/ 31 июля 2013

Я придумал этот кусок кода в 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()
2 голосов
/ 30 апреля 2009

Вы можете присвоить 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
});
0 голосов
/ 03 ноября 2016

У меня сработало следующее решение:

$("#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!');
}

Спасибо

0 голосов
/ 23 апреля 2014

.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;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...