Question

J'ai une forme qui est soumis à distance lorsque les différents éléments changent. Sur un champ de recherche en particulier, je suis sur un keyup pour détecter le texte dans les changements sur le terrain. Le problème est que lorsque quelqu'un tape « poulet », puis le formulaire est soumis sept fois, avec seulement le dernier comptage.

Quelle serait mieux est quelque chose comme ceci

  • keyup détectée - début d'attente (une seconde)

  • une autre keyup détectée - le temps d'attente restart

  • finitions attente - obtenir la valeur et soumettre le formulaire

avant que je pars et le code ma propre version de ce (je suis vraiment un gars de back-end avec seulement un peu js, j'utilise jQuery pour tout), il est déjà une solution existante à ce sujet? Il semble que ce serait une exigence commune. Un plugin jQuery peut-être? Sinon, quelle est la plus simple et la meilleure façon de coder cela?

Mise à jour - code actuel ajouté pour Dan (ci-dessous)

Dan - cela peut être utile. L'un des plugins jQuery que je utilise sur la page (tablesorter) nécessite ce fichier - « tablesorter / jquery-latest.js », qui, si inclus, conduit à la même erreur avec votre code comme avant:

  

jQuery données ( "entrée # recherche"). ( "Délai d'attente", null) est définie   http: //192.168.0.234/javascripts/main.js 1264084467?   Ligne 11

Peut-être qu'il ya une sorte de conflit entre les différentes définitions jQuery? (Ou quelque chose)

$(document).ready(function() {
  //initiate the shadowbox player
//  Shadowbox.init({
//    players:  ['html', 'iframe']
//  });
}); 

jQuery(function(){
  jQuery('input#search')
    .data('timeout', null)
    .keyup(function(){
      jQuery(this).data('timeout', setTimeout(function(){
          var mytext = jQuery('input#search').val();
          submitQuizForm();
          jQuery('input#search').next().html(mytext);
        }, 2000)
     )
     .keydown(function(){
       clearTimeout(jQuery(this).data('timeout'));
     });
    });
});

function submitQuizForm(){
  form = jQuery("#searchQuizzes");
  jQuery.ajax({
    async:true, 
    data:jQuery.param(form.serializeArray()), 
    dataType:'script', 
    type:'get', 
    url:'/millionaire/millionaire_quizzes',
    success: function(msg){ 
     // $("#chooseQuizMainTable").trigger("update"); 
    }
  }); 
  return true;
}
Était-ce utile?

La solution

Désolé, je ne l'ai pas testé et il est un peu du haut de ma tête, mais quelque chose le long de ces lignes devrait, espérons faire l'affaire. Modifiez le 2000 mais le nombre de millisecondes dont vous avez besoin entre les messages du serveur

<input type="text" id="mytextbox" style="border: 1px solid" />
<span></span>

<script language="javascript" type="text/javascript">
    jQuery(function(){
      jQuery('#mytextbox')
        .data('timeout', null)
        .keyup(function(){
            clearTimeout(jQuery(this).data('timeout'));
            jQuery(this).data('timeout', setTimeout(submitQuizForm, 2000));
        });
    });
</script>

Autres conseils

Voici votre extension de fantaisie jquery:

(function($){

$.widget("ui.onDelayedKeyup", {

    _init : function() {
        var self = this;
        $(this.element).keyup(function() {
            if(typeof(window['inputTimeout']) != "undefined"){
                window.clearTimeout(inputTimeout);
            }  
            var handler = self.options.handler;
            window['inputTimeout'] = window.setTimeout(function() {
                handler.call(self.element) }, self.options.delay);
        });
    },
    options: {
        handler: $.noop(),
        delay: 500
    }

});
})(jQuery);

Utilisez comme ceci:

    $("input.filterField").onDelayedKeyup({
        handler: function() {
            if ($.trim($(this).val()).length > 0) {
                //reload my data store using the filter string.
            }
        }
    });

Est-ce qu'un délai d'une demi-seconde par défaut.

Comme une mise à jour, j'ai fini avec ce qui semble bien fonctionner:

function afterDelayedKeyup(selector, action, delay){
  jQuery(selector).keyup(function(){
    if(typeof(window['inputTimeout']) != "undefined"){
      clearTimeout(inputTimeout);
    }  
    inputTimeout = setTimeout(action, delay);
  });
}

J'appelle alors cela depuis la page dans le bloc document.ready de question

  afterDelayedKeyup('input#search',"submitQuizForm()",500)

Ce qui serait bien serait de faire un nouvel événement jquery qui utilise cette logique, par exemple .delayedKeyup pour aller à côté .keyup, donc je pouvais dire quelque chose comme ça pour le bloc document.ready d'une page individuelle.

  jQuery('input#search').delayedKeyup(function(){
    submitQuizForm();
  });

Mais, je ne sais pas comment personnaliser jquery de cette façon. C'est une belle tâche de devoirs bien.

Nice job, Max, qui était très utile pour moi! Je l'ai fait une légère amélioration de votre fonction en la rendant plus générale:

function afterDelayedEvent(eventtype, selector, action, delay) {
    $(selector).bind(eventtype, function() {
        if (typeof(window['inputTimeout']) != "undefined") {
            clearTimeout(inputTimeout);
        }
        inputTimeout = setTimeout(action, delay);
    });
}

De cette façon, vous pouvez l'utiliser pour tout type d'événement, bien que keyup est probablement ici le plus utile.

Je sais que c'est vieux, mais il était l'un des premiers résultats quand je cherchais comment faire quelque chose comme ça, donc je si je partage ma solution. J'ai utilisé une combinaison des réponses fournies pour obtenir ce que je devais sortir.

Je voulais un événement personnalisé qui a fonctionné tout comme les événements jQuery existants, et il fallait travailler avec keypress + supprimer, et entrez backspace.

Voici mon plugin jQuery:

$.fn.typePause = function (dataObject, eventFunc)
    {
        if(typeof dataObject === 'function')
        {
            eventFunc = dataObject;
            dataObject = {};
        }
        if(typeof dataObject.milliseconds === 'undefined')
            dataObject.milliseconds = 500;
        $(this).data('timeout', null)
            .keypress(dataObject, function(e)
            {
                clearTimeout($(this).data('timeout'));
                $(this).data('timeout', setTimeout($.proxy(eventFunc, this, e), dataObject.milliseconds));
            })
            .keyup(dataObject, function(e)
            {
                var code = (e.keyCode ? e.keyCode : e.which);
                if(code == 8 || code == 46 || code == 13)
                    $(this).triggerHandler('keypress',dataObject);
            });
    }

J'utilisé $.proxy() pour préserver le contexte de l'événement, mais il pourrait y avoir une meilleure façon de faire, en terme de performance.

Pour utiliser ce plugin, il suffit de faire:

$('#myElement').typePause(function(e){ /* do stuff */ });

ou

$('#myElement').typePause({milliseconds: 500, [other data to pass to event]},function(e){ /* do stuff */ });    
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top