Question

Dans mon formulaire, j'ai un ensemble de zones de saisie dans lesquelles un utilisateur peut saisir une valeur. Lors du changement de l'une de ces cases, le formulaire est automatiquement envoyé.

Le problème, c’est que maintenant, un utilisateur reste dans le dernier champ, prend la souris et appuie sur le bouton OK (d’un autre formulaire) sans quitter au préalable la zone de texte. L'événement de modification ne se déclenche pas et les anciennes valeurs incorrectes sont transmises à la page suivante.

Je souhaite déclencher l'événement onchange après quelques millisecondes de clavier inactif. Tout comme la plupart des plugins autocomplete.
Je pense pouvoir implémenter une minuterie qui commence à chronométrer au moment où vous entrez dans un champ de saisie et qui est réinitialisée à chaque fois qu'une touche est manipulée, puis lorsqu'il atteint zéro, l'événement onchange est déclenché.

Je ne suis pas prêt à réinventer la roue et je me demandais si une telle fonction est disponible quelque part.
Suggestions?

Était-ce utile?

La solution

J'ai eu un problème similaire et créé un plugin jQuery actuellement utilisé dans une application interne. Cela devrait déclencher l'événement change après que l'utilisateur ait fini de taper.

Si vous n'utilisez pas jQuery, le code est toujours adaptable.

jQuery.fn.handleKeyboardChange = function(nDelay)
{
    // Utility function to test if a keyboard event should be ignored
    function shouldIgnore(event) 
    { 
        var mapIgnoredKeys = {
             9:true, // Tab
            16:true, 17:true, 18:true, // Shift, Alt, Ctrl
            37:true, 38:true, 39:true, 40:true, // Arrows 
            91:true, 92:true, 93:true // Windows keys
        };
        return mapIgnoredKeys[event.which];
    }

    // Utility function to fire OUR change event if the value was actually changed
    function fireChange($element)
    {
        if( $element.val() != jQuery.data($element[0], "valueLast") )
        {
            jQuery.data($element[0], "valueLast", $element.val())
            $element.trigger("change");
        }
    }

    // The currently running timeout,
    // will be accessed with closures
    var timeout = 0;

    // Utility function to cancel a previously set timeout
    function clearPreviousTimeout()
    {
        if( timeout )
        { 
            clearTimeout(timeout);
        }
    }

    return this
    .keydown(function(event)
    {
        if( shouldIgnore(event) ) return;
        // User pressed a key, stop the timeout for now
        clearPreviousTimeout();
        return null; 
    })
    .keyup(function(event)
    {
        if( shouldIgnore(event) ) return;
        // Start a timeout to fire our event after some time of inactivity
        // Eventually cancel a previously running timeout
        clearPreviousTimeout();
        var $self = $(this);
        timeout = setTimeout(function(){ fireChange($self) }, nDelay);
    })
    .change(function()
    {
        // Fire a change
        // Use our function instead of just firing the event
        // Because we want to check if value really changed since
        // our previous event.
        // This is for when the browser fires the change event
        // though we already fired the event because of the timeout
        fireChange($(this));
    })
    ;
}

Utilisation:

$("#my_input").handleKeyboardChange(300).change(function()
{
    // value has changed!
});

Autres conseils

Cela ne fonctionne-t-il pas de faire un onBlur, donc lorsque l'utilisateur passe au champ suivant ou clique sur un autre bouton, la valeur est enregistrée?

Je ne sais pas si une telle solution serait considérée comme une "réinvention". n'importe quoi. Comme vous l'avez dit, cela ne semble être qu'un simple setTimeout une fois la page chargée. Après environ 3 000 millisecondes, il exécute form.submit ().

Je recommencerais probablement le compte à rebours à chaque frappe, pour donner à l'utilisateur suffisamment de temps pour effectuer sa saisie.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top