web-dev-qa-db-fra.com

Comment gérez-vous un changement de formulaire dans jQuery?

Dans jQuery, existe-t-il un moyen simple de tester si TOUS les éléments d'un formulaire ont changé?

EDIT: J'aurais dû ajouter que je n'ai besoin que de vérifier un événement click().

EDIT: Désolé, j'aurais vraiment dû être plus précis! Dites que j'ai un formulaire et que j'ai un bouton avec les éléments suivants:

$('#mybutton').click(function() {
  // Here is where is need to test
  if(/* FORM has changed */) {
     // Do something
  }
});

Comment pourrais-je tester si le formulaire a changé depuis son chargement?

69
mike

Tu peux le faire:

$("form :input").change(function() {
  $(this).closest('form').data('changed', true);
});
$('#mybutton').click(function() {
  if($(this).closest('form').data('changed')) {
     //do something
  }
});

Cela modifie un gestionnaire d'événements change avec les entrées du formulaire. Si l'un d'entre eux change, il utilise .data() pour définir une valeur changed sur true, nous vérifions simplement que cette valeur est sélectionnée, cela suppose que #mybutton est à l'intérieur du form (sinon remplacez simplement $(this).closest('form') par $('#myForm')), mais vous pourriez le rendre encore plus générique, comme ceci:

$('.checkChangedbutton').click(function() {
  if($(this).closest('form').data('changed')) {
     //do something
  }
});

Références: Mise à jour

Selon jQuery, il s'agit d'un filtre permettant de sélectionner tous les contrôles de formulaire.

http://api.jquery.com/input-selector/

Le sélecteur: input sélectionne fondamentalement tous les contrôles de formulaire.

127
Nick Craver

Si vous souhaitez vérifier si les données de formulaire, telles qu'elles vont être envoyées au serveur, ont changé, vous pouvez sérialiser les données de formulaire au chargement de la page et les comparer aux données de formulaire actuelles:

$(function() {

    var form_original_data = $("#myform").serialize(); 

    $("#mybutton").click(function() {
        if ($("#myform").serialize() != form_original_data) {
            // Something changed
        }
    });

});
45
Udi

Une solution simple et en temps réel:

$('form').on('keyup change paste', 'input, select, textarea', function(){
    console.log('Form changed!');
});
14
Marcio Mazzucato

Vous pouvez utiliser plusieurs sélecteurs pour attacher un rappel à l'événement change pour tout élément de formulaire.

$("input, select").change(function(){
    // Something changed
});

MODIFIER

Puisque vous avez mentionné que vous n’avez besoin de cela que pour un clic, vous pouvez simplement modifier mon code original en ceci:

$("input, select").click(function(){
    // A form element was clicked
});

EDIT # 2

Ok, vous pouvez définir un global qui est défini une fois que quelque chose a été modifié comme ceci:

var FORM_HAS_CHANGED = false;

$('#mybutton').click(function() {
    if (FORM_HAS_CHANGED) {
        // The form has changed
    }
});

$("input, select").change(function(){
    FORM_HAS_CHANGED = true;
});
10
Joe D

En regardant la question mise à jour, essayez quelque chose comme

$('input, textarea, select').each(function(){
    $(this).data("val", $(this).val());
});
$('#button').click(function() {
    $('input, textarea, select').each(function(){
        if($(this).data("val")!==$(this).val()) alert("Things Changed");
    });
});

Pour la question initiale, utilisez quelque chose comme

$('input').change(function() {
    alert("Things have changed!");
});
3
Pez Cuckow
var formStr = JSON.stringify($("#form").serializeArray());
...
function Submit(){
   var newformStr = JSON.stringify($("#form").serializeArray());
   if (formStr != newformStr){
      ...
         formChangedfunct();
      ...
   }
   else {
      ...
         formUnchangedfunct();
      ...
   }
}
2
Péter Tajti

Voici une solution élégante.

Il existe une propriété masquée pour chaque élément d'entrée du formulaire que vous pouvez utiliser pour déterminer si la valeur a été modifiée ou non . Chaque type d'entrée a son propre nom de propriété. Par exemple

  • pour text/textarea c'est defaultValue
  • pour select c'est defaultSelect
  • pour checkbox/radio c'est defaultChecked

Voici l'exemple.

function bindFormChange($form) {

  function touchButtons() {
    var
      changed_objects = [],
      $observable_buttons = $form.find('input[type="submit"], button[type="submit"], button[data-object="reset-form"]');

    changed_objects = $('input:text, input:checkbox, input:radio, textarea, select', $form).map(function () {
      var
        $input = $(this),
        changed = false;

      if ($input.is('input:text') || $input.is('textarea') ) {
        changed = (($input).prop('defaultValue') != $input.val());
      }
      if (!changed && $input.is('select') ) {
        changed = !$('option:selected', $input).prop('defaultSelected');
      }
      if (!changed && $input.is('input:checkbox') || $input.is('input:radio') ) {
        changed = (($input).prop('defaultChecked') != $input.is(':checked'));
      }
      if (changed) {
        return $input.attr('id');
      }

    }).toArray();

    if (changed_objects.length) {
      $observable_buttons.removeAttr('disabled')   
    } else {
      $observable_buttons.attr('disabled', 'disabled');
    }
  };
  touchButtons();

  $('input, textarea, select', $form).each(function () {
    var $input = $(this);

    $input.on('keyup change', function () {
      touchButtons();
    });
  });

};

Il suffit maintenant de parcourir les formulaires de la page. Les boutons de soumission doivent être désactivés par défaut. Ils ne seront activés UNIQUEMENT que si vous modifiez certaines valeurs du formulaire.

$('form').each(function () {
    bindFormChange($(this));
});

L'implémentation en tant que plug-in jQuery est ici https://github.com/kulbida/jmodifiable

2
Developer
$('form :input').change(function() {
    // Something has changed
});
2
VoteyDisciple

Vous avez besoin de jQuery Form Observe plugin. C'est ce que vous recherchez.

1
Sarfraz

En prolongeant la réponse d'Udi, cela ne concerne que la soumission du formulaire, pas à chaque changement d'entrée.

$(document).ready( function () {
  var form_data = $('#myform').serialize();
  $('#myform').submit(function () {
      if ( form_data == $(this).serialize() ) {
        alert('no change');
      } else {
        alert('change');
      }
   });
});
1
Ruby Racer

Premièrement, j'ajouterais une entrée masquée à votre formulaire pour en suivre l'état. Ensuite, j'utiliserais cet extrait de code jQuery pour définir la valeur de l'entrée masquée lorsqu'un élément du formulaire est modifié:

    $("form")
    .find("input")
    .change(function(){
        if ($("#hdnFormChanged").val() == "no")
        {
            $("#hdnFormChanged").val("yes");
        }
    });

Lorsque vous cliquez sur votre bouton, vous pouvez vérifier l'état de votre entrée masquée:

$("#Button").click(function(){
    if($("#hdnFormChanged").val() == "yes")
    {
        // handler code here...
    }
});
0
JMP

$('form[name="your_form_name"] input, form[name="your_form_name"] select').click(function() {
  $("#result").html($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Form "your_form_name"</h2>
<form name="your_form_name">
  <input type="text" name="one_a" id="one_a" value="AAAAAAAA" />
  <input type="text" name="one_b" id="one_b" value="BBBBBBBB" />
  <input type="text" name="one_c" id="one_c" value="CCCCCCCC" />
  <select name="one_d">
    <option value="111111">111111</option>
    <option value="222222">222222</option>
    <option value="333333">333333</option>
  </select>
</form>
<hr/>
<h2>Form "your_other_form_name"</h2>
<form name="your_other_form_name">
  <input type="text" name="two_a" id="two_a" value="DDDDDDDD" />
  <input type="text" name="two_b" id="two_b" value="EEEEEEEE" />
  <input type="text" name="two_c" id="two_c" value="FFFFFFFF" />
  <input type="text" name="two_d" id="two_d" value="GGGGGGGG" />
  <input type="text" name="two_e" id="two_f" value="HHHHHHHH" />
  <input type="text" name="two_f" id="two_e" value="IIIIIIII" />
  <select name="two_g">
    <option value="444444">444444</option>
    <option value="555555">555555</option>
    <option value="666666">666666</option>
  </select>
</form>
<h2>Result</h2>
<div id="result">
  <h2>Click on a field..</h2>
</div>

En plus des réponses ci-dessus @ JoeD.

Si vous souhaitez cibler des champs dans un formulaire particulier (en supposant qu'il en existe plusieurs), vous pouvez utiliser le code suivant:

$('form[name="your_form_name"] input, form[name="your_form_name"] select').click(function() {
    // A form element was clicked
});
0
Anjana Silva

Essaye ça:

<script>
var form_original_data = $("form").serialize(); 
var form_submit=false;
$('[type="submit"]').click(function() {
    form_submit=true;
});
window.onbeforeunload = function() {
    //console.log($("form").submit());
    if ($("form").serialize() != form_original_data && form_submit==false) {
        return "Do you really want to leave without saving?";
    }
};
</script>
0
Vinod saraswat