Domanda

Nella mia forma ho una serie di caselle di input in cui un utente può inserire un valore. Al cambio di una di queste caselle, il modulo viene automaticamente inviato.

Il problema ora è tuttavia che un utente rimane nell'ultimo campo, prende il mouse e preme il pulsante OK (di un altro modulo) senza lasciare prima la casella di testo. L'evento change non viene attivato e i vecchi valori errati vengono passati alla pagina successiva.

Voglio attivare l'evento onchange dopo alcuni millisecondi di tastiera inattiva. Proprio come fanno la maggior parte dei plugin con completamento automatico.
Penso che potrei implementare un timer che inizia a cronometrare nel momento in cui entri in un campo di input e viene reimpostato ogni volta che viene gestita una sequenza di tasti e quindi quando raggiunge lo zero viene attivato l'evento onchange.

Non ho intenzione di reinventare la ruota e mi chiedevo se tale funzione fosse disponibile da qualche parte.
Suggerimenti?

È stato utile?

Soluzione

Ho avuto un problema simile e ho creato un plugin jQuery attualmente in uso in un'applicazione interna. Dovrebbe attivare l'evento change dopo che l'utente ha terminato di digitare.

Se non si utilizza jQuery, il codice è ancora adattabile a qualsiasi altra cosa.

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

Utilizzo:

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

Altri suggerimenti

Non funziona per fare un onBlur, quindi sia quando l'utente passa al campo successivo o fa clic su qualcos'altro, il valore viene salvato?

Non so che una soluzione del genere sarebbe considerata "reinventare". nulla. Come hai detto, sembra che non sia altro che un semplice setTimeout una volta caricata la pagina. Dopo circa 3000 millisecondi, esegue form.submit ().

Probabilmente ricomincerei il conto alla rovescia anche con ogni sequenza di tasti, per dare all'utente il tempo sufficiente per effettuare l'inserimento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top