Question Détection des modifications de données dans les formulaires à l'aide de jQuery


J'utilise ASP.NET 2.0 avec une page maître, et je me demandais si quelqu'un connaissait un moyen de détecter quand les champs d'un certain <div> ou fieldset ont été changés (par exemple, marqué "IsDirty')?


18
2018-04-30 14:19


origine


Réponses:


Vous pouvez lier l'événement Change pour toutes les entrées et marquer une variable comme true. Comme ça.

var somethingChanged = false;
$(document).ready(function() { 
   $('input').change(function() { 
        somethingChanged = true; 
   }); 
});

Mais, gardez à l'esprit que si l'utilisateur change quelque chose, puis revient aux valeurs d'origine, il sera toujours marqué comme modifié.

METTRE À JOUR: Pour un div ou des champs spécifiques. Utilisez simplement l'identifiant du champ ou du div donné. Exemple:

var somethingChanged = false;
$(document).ready(function() { 
   $('#myDiv input').change(function() { 
        somethingChanged = true; 
   }); 
});

38
2018-04-30 14:27



Solution rapide (mais très sale)

C'est rapide, mais ça ne prendra pas soin de ctrl+z ou cmd+z et cela vous donnera un faux positif en appuyant sur shift, ctrl ou la tab clé:

$('#my-form').on('change keyup paste', ':input', function(e) {
    // The form has been changed. Your code here.
});

Testez-le avec ce violon.


Solution rapide (moins sale)

Cela évitera les faux positifs pour shift, ctrl ou la tab clé, mais il ne va pas gérer ctrl+z ou 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.

  }

});

Testez-le avec ce violon.


Solution complète (moins rapide)

Si vous voulez gérer tout les cas, vous devez utiliser:

// 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. 
  }
});

Testez-le avec ce violon.


25
2017-08-03 11:53



Une solution simple et élégante (elle détecte les modifications d'éléments en temps réel):

var formChanged = false;

$('#my-div form').on('keyup change paste', 'input, select, textarea', function(){
    formChanged = true;
});

19
2018-05-16 13:16



Juste pour clarifier parce que la question est "dans un certain champ / div":

var somethingChanged = false;
$(document).ready(function() { 
   $('fieldset > input').change(function() { 
        somethingChanged = true; 
   }); 
});

ou

var somethingChanged = false;
$(document).ready(function() { 
   $('div > input').change(function() { 
        somethingChanged = true; 
   }); 
});

5
2018-04-30 14:31



Vous pouvez donner le champset ou div un ID et lier l'événement change à lui ... l'événement doit se propager à partir des enfants internes.

var somethingChanged = false;
$('#fieldset_id').change(function(e)
{
    // e.target is the element which triggered the event
    // console.log(e.target);
    somethingChanged = true;
});

De plus, si vous souhaitez avoir une fonction d'écoute d'événement unique, vous pouvez placer l'événement de modification sur le formulaire, puis vérifier quel champ a été modifié:

$('#form_id').change(function(e)
{
    var changedFieldset = $(e.target).parents('fieldset');
    // do stuff
});

2
2018-04-30 14:35



J'ai trouvé ce code dans CoffeeScript (pas encore testé sur le terrain):

  • Ajoutez la classe 'change_warning' aux formulaires à surveiller pour les modifications.

  • Ajoutez la classe 'change_allowed' au bouton Enregistrer.

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
2017-07-31 00:54



La solution suivante a fonctionné pour moi:

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

Merci


0
2017-11-03 15:46



.live est maintenant obsolète et remplacé par .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;
});

0
2018-04-22 20:33



Pour un formulaire, vous pouvez sérialiser le contenu lors du chargement, puis comparer la sérialisation ultérieurement, par exemple:

$(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');
        $.post('settings.php',$('form').serialize()).done(function(){
            initdata=$('form').serialize();
        });
    });
});

0
2018-04-06 01:37