rails3-jquery-autocomplete:如何扩展select函数?

时间:2012-10-27 02:05:27

标签: jquery ruby-on-rails jquery-ui

我正在使用rails3-jquery-autocomplete 1.0.9和Rails 3.2.8。

我正在尝试使用自动填充功能替换组合框(<select>)。像组合框一样,如果用户选择了一个值,我想更新数据库中的id。也像组合框一样,不应该选择无效的值。

这方面的一个方面是,如果用户开始在字段中输入,但是离开字段而没有从选择列表中选择值,则字段本身和相应的隐藏#to_contact_id字段应该被消隐。

以下是字段定义:

<%= autocomplete_field_tag "to_contact_name", '',
      autocomplete_contact_display_name_messages_path,
      :id_element => "#to_contact_id",
      :value => to_contact_name %>
<%= f.hidden_field :to_contact_id, :id => "to_contact_id" %>

我的计划是在用户从选择列表中选择一个项目时设置一个标志,然后检查模糊标记(失去焦点)。我找到了一个覆盖自动完成函数here的示例,并对此Javascript进行了编码:

var picklist_value_selected = false;

$('input[data-autocomplete]').focus(function() {
  // add autocomplete event handler on focus
  $(this).autocomplete({
    select: function(event, ui) {
      picklist_value_selected = true;
    }
  });
});

$('input[data-autocomplete]').blur(function() {
  // If user leaves field without selecting value, clear values.
  if (!picklist_value_selected) {
    $(this).val('')
    $('#to_contact_id').val('');
  };
});

问题是,当我覆盖 select时,“默认”功能不会执行,这意味着#to_contact_id永远不会被填充。

我认为我需要的是扩展 select而不是覆盖它,所以我的代码和rails3-jquery-autocomplete基本代码都执行了?我怎么做?如下所示的各种尝试都不会被调用或抱怨未定义的方法:

$.extend($(this).autocomplete, {
  select: function(event, ui) {
    picklist_value_selected = true;
  }
});

1 个答案:

答案 0 :(得分:1)

执行此操作的最佳方法是使用自动填充功能change event。当字段模糊时触发,如果值已更改,则让您知道选择了哪个项目(如果有)。你可以像这样绑定它:

$('input[data-autocomplete]').bind('autocompletechange', function(event, ui) {
    if(!ui.item) {
        // clear the fields
    }
});

更新

  

由于我今天与它斗争了这么久,我仍然有兴趣了解如何扩展功能。

here。这是初始化自动完成的地方。 select是作为自动完成选项传递的匿名函数。你可以像这样扩展它(希望代码是自我解释的):

var originalSelect = $('input[data-autocomplete]').autocomplete('option', 'select');
$('input[data-autocomplete]').autocomplete('option', 'select', function(event, ui) {
    originalSelect.call(this, event, ui);
    doSomeOtherStuff();
});

然而,这不是一个好的代码,因为select是一个事件,所以如果你想在调用时做更多的事情,你可以将另一个函数绑定到它。这样,原始和你的函数都会被调用而不会像我之前的例子那样被黑客攻击:

$('input[data-autocomplete]').bind('autocompleteselect', function(event, ui) {
    doSomeOtherStuff();
});