2012-10-27 125 views
1

我在Rails 3.2.8中使用rails3-jquery-autocomplete 1.0.9。rails3-jquery-autocomplete:如何扩展select函数?

我试图用自动完成替换组合框(<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的自动完成基本代码执行?我怎么做?各种尝试像下面要么没有得到所谓的或抱怨未定义的方法:

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

回答

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(); 
}); 
+0

有帮助,谢谢。几乎与我引用的文章中提到的一样,但是我错过了“ui.item”实际上已经填充了新选定的值(如果有的话)的事实。由于我今天与它斗争了很长时间,我仍然有兴趣知道如何扩展一个函数。也许这很困难?找不到好的例子。 –

+0

我更新了我的答案。 – mechanicalfish

+0

再次感谢,这两个扩展工作的例子。因此,要将新函数绑定到现有事件,可以将当前函数/事件名称混合在一起?永远不会猜到这一点。执行顺序是否有保证,即我的新函数是否总是首先执行?对于更明显的执行顺序控制,我更喜欢“黑客” - 并且更熟悉函数的“超级”调用。例如,我找到的“super”的另一种语法是'return $ .ui.sortable.prototype._init.apply(this,arguments);'但我永远无法找出正确的名称空间来调用它。 –