308 votes

jQuery - Détecter le changement de valeur d'un champ de saisie caché

J'ai un champ de texte caché dont la valeur est mise à jour via une réponse AJAX.

<input type="hidden" value="" name="userid" id="useid" />

Lorsque cette valeur change, je voudrais déclencher une requête AJAX. Quelqu'un peut-il me conseiller sur la manière de détecter le changement ?

J'ai le code suivant, mais je ne sais pas comment chercher la valeur :

$('#userid').change( function() {  
    alert('Change!'); 
})

2 votes

S'il est mis à jour via une réponse ajax, pourquoi ne pas simplement lancer la nouvelle requête ajax dans la fonction de réussite de la réponse ?

2 votes

$('#userid').val() vous donnera la valeur si c'est ce que vous demandez.

0 votes

MISE À JOUR : un événement de modification est désormais déclenché lorsque la valeur d'un champ caché est mise à jour.

687voto

yycroman Points 2542

C'est un peu tard, mais j'ai découvert une réponse, au cas où elle serait utile à quelqu'un qui tomberait sur ce fil.

Les changements de valeur des éléments cachés ne déclenchent pas automatiquement l'événement .change(). Ainsi, quel que soit l'endroit où vous définissez cette valeur, vous devez également indiquer à jQuery de le déclencher.

function setUserID(myValue) {
     $('#userid').val(myValue)
                 .trigger('change');
}

Une fois que c'est le cas,

$('#userid').change(function(){
      //fire your ajax call  
})

devrait fonctionner comme prévu.

5 votes

Est .trigger() Il est généralement préférable de l'utiliser plutôt que de simplement appeler change() ?

1 votes

Cela fonctionne, mais il semble qu'il déclenche l'événement de changement deux fois ! C'est comme si je mettais ce code, il le déclenche deux fois, si j'enlève le code, il n'y a pas de déclenchement !

1 votes

Pour qu'il se comporte de la même manière que change vous devez ajouter le code dans setUserID() pour vérifier si la valeur est réellement modifiée ou non. if ($('#userid').val() != myVaule) { // set val() and trigger change }

52voto

lulalala Points 3895

Comme l'entrée cachée ne déclenche pas l'événement "change" en cas de modification, j'ai utilisé MutationObserver pour le déclencher à la place.

(Parfois, les changements de valeurs d'entrée cachées sont effectués par d'autres scripts que vous ne pouvez pas modifier).

Cela ne fonctionne pas dans IE10 et les versions inférieures

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var trackChange = function(element) {
  var observer = new MutationObserver(function(mutations, observer) {
    if(mutations[0].attributeName == "value") {
        $(element).trigger("change");
    }
  });
  observer.observe(element, {
    attributes: true
  });
}

// Just pass an element to the function to start tracking
trackChange( $("input[name=foo]")[0] );

9voto

Tarun Gupta Points 1369

Vous pouvez simplement utiliser la fonction ci-dessous, Vous pouvez également changer l'élément de type.

 $("input[type=hidden]").bind("change", function() {
       alert($(this).val()); 
 });

Les modifications de la valeur des éléments masqués ne déclenchent pas automatiquement l'événement .change(). Ainsi, quel que soit l'endroit où vous définissez cette valeur, vous devez également indiquer à jQuery de le déclencher.

HTML

 <div id="message"></div>
<input type="hidden" id="testChange" value="0"  />    

JAVASCRIPT

var $message = $('#message');
var $testChange = $('#testChange');
var i = 1;

function updateChange() {
    $message.html($message.html() + '<p>Changed to ' + $testChange.val() + '</p>');
}

$testChange.on('change', updateChange);

setInterval(function() {
    $testChange.val(++i).trigger('change');; 
    console.log("value changed" +$testChange.val());
}, 3000);

updateChange();

devrait fonctionner comme prévu.

http://jsfiddle.net/7CM6k/3/

1 votes

Cela ne fonctionne pas pour moi... De toute façon, comment est-il possible de coller une valeur dans un champ caché ? :/

0 votes

Merci, le collage ne devrait pas être là, mais la modification peut détecter l'événement de modification du champ caché.

0 votes

@KrisErickson Merci pour le fiddle, j'ai mis à jour le code afin qu'il puisse détecter le changement explicitement, S'il vous plaît suivre le fiddle mis à jour jsfiddle.net/7CM6k/3

7voto

Nitin Patil Points 1
$('#userid').change(function(){
  //fire your ajax call  
});

$('#userid').val(10).change();

5voto

GuyPaddock Points 448

En s'appuyant sur La réponse de Viktar Dans le cas d'un élément d'entrée caché, voici une mise en œuvre que vous pouvez appeler une fois sur un élément d'entrée caché donné pour vous assurer que les événements de changement ultérieurs sont déclenchés chaque fois que la valeur de l'élément d'entrée change :

/**
 * Modifies the provided hidden input so value changes to trigger events.
 *
 * After this method is called, any changes to the 'value' property of the
 * specified input will trigger a 'change' event, just like would happen
 * if the input was a text field.
 *
 * As explained in the following SO post, hidden inputs don't normally
 * trigger on-change events because the 'blur' event is responsible for
 * triggering a change event, and hidden inputs aren't focusable by virtue
 * of being hidden elements:
 * https://stackoverflow.com/a/17695525/4342230
 *
 * @param {HTMLInputElement} inputElement
 *   The DOM element for the hidden input element.
 */
function setupHiddenInputChangeListener(inputElement) {
  const propertyName = 'value';

  const {get: originalGetter, set: originalSetter} =
    findPropertyDescriptor(inputElement, propertyName);

  // We wrap this in a function factory to bind the getter and setter values
  // so later callbacks refer to the correct object, in case we use this
  // method on more than one hidden input element.
  const newPropertyDescriptor = ((_originalGetter, _originalSetter) => {
    return {
      set: function(value) {
        const currentValue = originalGetter.call(inputElement);

        // Delegate the call to the original property setter
        _originalSetter.call(inputElement, value);

        // Only fire change if the value actually changed.
        if (currentValue !== value) {
          inputElement.dispatchEvent(new Event('change'));
        }
      },

      get: function() {
        // Delegate the call to the original property getter
        return _originalGetter.call(inputElement);
      }
    }
  })(originalGetter, originalSetter);

  Object.defineProperty(inputElement, propertyName, newPropertyDescriptor);
};

/**
 * Search the inheritance tree of an object for a property descriptor.
 *
 * The property descriptor defined nearest in the inheritance hierarchy to
 * the class of the given object is returned first.
 *
 * Credit for this approach:
 * https://stackoverflow.com/a/38802602/4342230
 *
 * @param {Object} object
 * @param {String} propertyName
 *   The name of the property for which a descriptor is desired.
 *
 * @returns {PropertyDescriptor, null}
 */
function findPropertyDescriptor(object, propertyName) {
  if (object === null) {
    return null;
  }

  if (object.hasOwnProperty(propertyName)) {
    return Object.getOwnPropertyDescriptor(object, propertyName);
  }
  else {
    const parentClass = Object.getPrototypeOf(object);

    return findPropertyDescriptor(parentClass, propertyName);
  }
}

Appelez cela sur le document prêt comme ceci :

$(document).ready(function() {
  setupHiddenInputChangeListener($('myinput')[0]);
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X