web-dev-qa-db-fra.com

Retarder l'appel ajax sur le champ de texte pour permettre la saisie

Je voudrais retarder ajax de se déclencher de la même manière que la saisie semi-automatique semble fonctionner. Par exemple, si un utilisateur tape, l'ajax ne fonctionnera pas avant que 500 ms ne se soient écoulées depuis la dernière frappe.

Je regarde actuellement les comportements de drupal.be mais je ne suis pas en mesure de le faire fonctionner.

Drupal.behaviors.mymodule = {
  attach: function(context, settings) { 
    $('input.andtimer', context).delay(500).ajaxStart();
  }
};

Il s'agit de l'élément de formulaire auquel le comportement est attaché.

$form['my_input'] = array(
  '#type' => 'textfield',
  '#default_value' => $value,
  '#ajax' => array(
    'callback' => 'my_callback',        
    'event' => 'keyup',
    'wrapper' => 'my_wrapper',  
    'trigger_as' => array(
      'name' =>  'my_button',
  ),
  'progress' => array('type' => 'none'),
  ),
  '#attributes' => array(
    'class' => array('andtimer'),
  ),                      
);

Ce jsfiddle montre ce que j'essaie de réaliser.

Est-ce que Comment remplacer Drupal.ajax.prototype.beforeSend? serait un moyen de supprimer cela?

Ce qui suit fonctionne pour le premier "ensemble" d'entrées avec la classe .andtimer. Il ne fonctionne pour aucun autre ensemble, l'ajax continue toujours avec le premier ensemble. Une idée sur comment réparer ça?

(function($, Drupal) {
    Drupal.behaviors.bform = {
        attach : function(context, settings) {

            var events = $('.andtimer').clone(true).data('events');
            $('.andtimer').unbind('keyup');
            var typingTimer;
            var doneTypingInterval = 300;
            $('.andtimer').keyup(function() {
                clearTimeout(typingTimer);
                typingTimer = setTimeout(doneTyping, doneTypingInterval);
                function doneTyping() {
                    $.each(events.keyup, function() {
                        this.handler();
                    });
                }

                return false;
            });
        }
    };
})(jQuery, Drupal); 

Utiliser $ form ['my_input'] ['# ajax'] ['event'] = 'finishinput' comme suggéré et

var typingTimer;
var doneTypingInterval = 600;

$('.andtimer').on('keyup', function (e) {
  clearTimeout(typingTimer);
  if ($(this).val) {
    var trigid = $(this);
    typingTimer = setTimeout(function(){                    
      trigid.triggerHandler('finishedinput');
    }, doneTypingInterval);
  }
});

Fonctionne pour chaque "groupe" d'entrées où le nombre d'entrées remplies doit être obtenu.

8
Inigo Montoya

Une option consiste à utiliser un événement jQuery personnalisé, par exemple. quelque chose comme finishinput. Ensemble $form['my_input']['#ajax']['event'] = 'finishedinput' et fournissez du JS pour déclencher votre événement personnalisé après un délai approprié (similaire au JS du violon).

7
Andy

Cette approche présente à la fois l'avantage et l'inconvénient d'être appliquée à tous les événements déclenchés par des touches AJAX sur toutes les pages où ce script s'exécute.

!function ($) {
  const originalMethod = Drupal.ajax.prototype.eventResponse,
        timeoutDelay   = 500;

  var timeoutId;

  // Override the default event handler
  Drupal.ajax.prototype.eventResponse = function (element, event) {
    const self = this;
    clearTimeout(timeoutId);

    if ('keyup' === this.event) {
      // Fire the original event handler with a delay
      timeoutId = setTimeout(function (element, event) {
        originalMethod.apply(self, [element, event]);
      }, timeoutDelay, element, event);
    }
    else {
      // Fire the original event handler immediately
      originalMethod.apply(this, [element, event]);
    }
  };
}(jQuery);
0
tvanc