延迟对文本字段的ajax调用以允许键入


8

我想以自动完成功能似乎起作用的方式延迟ajax的触发。例如,如果键入用户,则自上次键入键起经过500毫秒后,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有多紧密。这引起了一个非常有趣的问题:)
克莱夫(Clive

1
底部的代码段对我来说效果很好,除了触发事件之后,该领域失去了焦点。我该如何做,以便在射击后将注意力集中在元素上。
VanD

Answers:


7

一种选择是使用自定义jQuery事件,例如。像finishinput这样的东西。设置$form['my_input']['#ajax']['event'] = 'finishedinput'并提供一些JS,以在适当的延迟后触发您的自定义事件(类似于小提琴中的JS)。


惊人 !我正是在寻找:)非常感谢。但是,如果我可以提示您在更改视图公开表单的输入时如何应用此技巧。如果我没有将callback设置为$ form ['my_input'] ['#ajax'],则什么也不会发生,如果我将暴露的表单提交的提交视图提交给fn作为回调(或其他方法),它将起作用,但是返回未定义的索引:form_build_id。 ..而且我也不知道如何以及在何处添加$ form_state ['rebuild'] = TRUE预先感谢
Kojo

1
@Kojo您可以问一个新的问题,并包括对Views AJAX设置,公开的过滤器,您正在使用的任何自定义代码以及出现的问题的描述吗?Btw CTools自动提交从文本字段提交时已经有(硬编码)延迟0.5秒(请参阅auto-submit.js)。
安迪2014年

很好,这是设置!是否有可能针对特定输入“即时”修改它?如果不是很简单,我将发布一个问题:)谢谢您的帮助!
Kojo

1
@Kojo不应该那么容易!如果是我,我可能会创建自己的auto-submit.js并hook_js_alter()用来确保它代替了原始的。(但实际上,恕我直言,ctools代码应该使用Drupal.settings而不是硬编码的值。)
Andy

1
@Kojo另请参阅drupal.org/node/2023705,它旨在改善自动提交的体验(不仅限于文本输入)。有一个补丁可能对您来说已经足够。编辑:如果您确实尝试使用它,请不要忘记在问题上发表评论,说它是否有效。
安迪2014年

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答案。您可以通过写一段简短的段落来说明该cide的作用以及它将如何解决OPs问题,从而改善您的答案。
Free Radical

-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默认情况下是一个空函数,因此此代码实际上不执行任何操作。它只是在有或没有延迟的情况下调用一个空值。
tvanc

RE:空函数-是的。现在是空的。但是Drupal API可能会更改,并且可能不再为空。这是一个安全的替代。另外,它目前不执行任何操作,因为要由OP插入要覆盖的任何值。
jduhls

Drupal甚至在代码中表示要覆盖此功能:/ ** *在提交表单之前修改表单值。* / Drupal.ajax.prototype.beforeSubmit =函数(form_values,元素,选项){//此函数保留为空,以使其易于覆盖希望在此处添加功能的模块。};
jduhls
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.