web-dev-qa-db-ja.com

入力を可能にするためにテキストフィールドでのajax呼び出しを遅らせる

オートコンプリートが機能しているように見えるのと同じ方法で、ajaxの起動を遅らせたいと思います。たとえば、ユーザーが入力すると、最後のキーアップから500msが経過するまでajaxは実行されません。

現在、drupal.behaviorsを調べていますが、機能させることができません。

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

これは、動作が関連付けられているフォーム要素です。

$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'),
  ),                      
);

この jsfiddle は、私が達成しようとしていることを示しています。

Drupal.ajax.prototype.beforeSendをオーバーライドする方法は? これを削除するためのルートでしょうか?

以下は、クラス.andtimerの最初の「セット」の入力に対して機能します。他のセットでは機能しません。ajaxは常に最初のセットで続行します。これを修正する方法はありますか?

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

推奨される$ form ['my_input'] ['#ajax'] ['event'] = 'finishedinput'を使用し、

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

入力の「グループ」ごとに機能し、入力された入力の数を取得する必要があります。

8
Inigo Montoya

1つのオプションは、カスタムjQueryイベントを使用することです。 finishedinputのようなもの。セットする $form['my_input']['#ajax']['event'] = 'finishedinput'および適切な遅延の後にカスタムイベントをトリガーするJSをいくつか提供します(フィドルのJSと同様)。

7
Andy

このアプローチには、このスクリプトが実行されるすべてのページのすべてのキーアップトリガーAJAXイベントに適用されるという利点と欠点の両方があります。

!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