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


8

オートコンプリートが機能しているように見えるのと同じ方法で、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);
  }
});

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


そのコードはkeyup / keydownやあなたが言及しているイベントバインディングとは何の関係もありません-実際のコードを追加できますか?一般的なJavaScriptヘルプを探しているだけの場合は、ここで見つけることはできません。ルールは、まずDrupalの外部で機能させることです。Drupalの内部で機能させることができない場合は、こちらから質問してください
Clive

Cliveに感謝します。入力を作成するためのコードを追加しました。私は試してみて、それをDrupalで動作させるようにしました。まだ学習中です。私はそれを外に出して、私の頭の中のもう少し確率を明確にすることができないかどうかを確認します。
Inigo Montoya 2014年

私はあまりにも早く話しました、あなたがこれを作ろうとしているDrupalとどれほど結びついているかを理解していませんでした。これはかなり興味深い問題になります:)
クライヴ

1
一番下のコードスニペットは、イベントが発生した後にフィールドがフォーカスを失うことを除いて、私にとってはうまく機能します。発射後も要素にフォーカスが留まるようにするには、どうすればよいですか。
VanD 2015

回答:


7

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


すごい!私はまさにそれを探していました:)ありがとうございました。ただし、ビューの公開されたフォームの入力を変更するときにこれを適用する方法についてのヒントがあれば。コールバックを$ form ['my_input'] ['#ajax']に設定しないと、何も起こりません。送信ビュー公開フォームsubmit fnをコールバック(またはその他)として追加すると、機能しますが、未定義のインデックスform_build_idが返されます。 ..また、$ form_state ['rebuild'] = TRUEを追加する方法と場所もわかりません。事前に感謝
Kojo

1
@Kojoこれについて新しい質問をして、ビューのAJAX設定、公開されたフィルター、使用しているカスタムコード、および発生した問題の説明を含めてください。Btw CToolsの自動送信には、0.5秒のテキストフィールドからの送信で(ハードコードされた)遅延がすでにあります(auto-submit.jsを参照)。
アンディ14

ああ、これが設定です!特定の入力に対して「オンザフライ」で変更することはできませんか?簡単ではない場合は、質問を投稿します:)ご協力ありがとうございます。
Kojo 14

1
@Kojoそれがあるべきほど簡単ではありません!それが私なら、おそらく自分でauto-submit.jsを作成し、hook_js_alter()それを使用してオリジナルの代わりに使用することになります。(ただし、ctoolsコードはハードコードされた値ではなくDrupal.settingsを使用する必要があります。)
Andy

1
@Kojoまた、drupal.org / node / 2023705を見てください。これは、(テキスト入力だけでなく)自動送信エクスペリエンスの改善に関するものです。あなたには十分かもしれないパッチがあります。編集:そしてそれを使用しようとする場合は、問題が機能したかどうかをコメントに残すことを忘れないでください。
アンディ14

0

このアプローチには、このスクリプトが実行されるすべてのページでキーアップによってトリガーされるすべての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);

-1

これは私が書いたコードです:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt-br" lang="pt-br">
<head><title>Submit after typing finished</title>
<script language="javascript" type="text/javascript">
function DelayedSubmission() {
    var date = new Date();
    initial_time = date.getTime();
    if (typeof setInverval_Variable == 'undefined') {
            setInverval_Variable = setInterval(DelayedSubmission_Check, 50);
    } 
}
function DelayedSubmission_Check() {
    var date = new Date();
    check_time = date.getTime();
    var limit_ms=check_time-initial_time;
    if (limit_ms > 800) { //Change value in milliseconds
        alert("insert your function"); //Insert your function
        clearInterval(setInverval_Variable);
        delete setInverval_Variable;
    }
}

</script>
</head>
<body>

<input type="search" onkeyup="DelayedSubmission()" id="field_id" style="WIDTH: 100px; HEIGHT: 25px;" />

</body>
</html>

3
Drupal Answersへようこそ。cideの機能とOPの問題をどのように解決するかを説明する短い段落を書くことで、回答を改善できます。
フリーラジカル

-1

私も運がよからずbeforeSendを試してみました。次に「beforeSubmit」に偶然出会いましたが、それは私にとってはトリックです。この戦略を使用して、他のDrupal ajaxプロトタイプメソッドにフックすることもできます(すべての元のメソッドについては、/ misc / ajax.jsを参照してください)。

(function($, Drupal) {
    var delayedTimeoutId;
    var delayInterval = 500;

    /**
     * Modify form values prior to form submission.
     */
    Drupal.ajax.prototype.original_beforeSubmit = Drupal.ajax.prototype.beforeSubmit;
    Drupal.ajax.prototype.beforeSubmit = function (form_values, element, options) {
        // Some console stuff for info purposes:
        if(window.console) {
            console.log('beforeSubmit args:');
            console.log(this); // contains stuff like PHP AJAX callback, triggering selector, etc.
            console.log(form_values); // the form data
            console.log(element); // the triggering element
            console.log(options); // ajax options
        }

        // If it is the triggering selector or callback I want to delay, then do the delay:
        if(this.selector == '#my-text-input-id' || this.callback == '_my_module_ajax_callback') {
            // Clear timeout if it exists;
            clearTimeout(delayedTimeoutId);
            // Start waiting:
            delayedTimeoutId = setTimeout(function(drupalAjax, form_values, element, options) {
                delayedTimeoutId = null;
                // Execute original beforeSubmit:
                drupalAjax.original_beforeSubmit(form_values, element, options);
            }, delayInterval, this, form_values, element, options)
        } else {
            // Continue with original beforeSubmit:
            this.original_beforeSubmit(form_values, element, options);
        }
    };
}(jQuery, Drupal));

Drupal.ajax.prototype.beforeSubmitはデフォルトでは空の関数なので、このコードは実際には何もしません。遅延の有無にかかわらず、単にemptyを呼び出します。
tvanc

RE:空の関数-これは本当です。現時点では空です。しかし、Drupal APIは変更される可能性があり、空ではなくなる可能性があります。これは安全なオーバーライドです。また、上書きしたい値を挿入するのはOPの責任なので、現在は何もしていません。
jduhls 2017年

Drupalは、この関数をオーバーライドするようにコードで次のように述べています。/ ** *フォームを送信する前にフォームの値を変更します。* / Drupal.ajax.prototype.beforeSubmit = function(form_values、element、options){//この関数は、ここに機能を追加したいモジュールの//オーバーライドを簡単にするために空のままにします。};
jduhls 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.