【问题标题】:Rails autocomplete - customize behavior to list all items before enteringRails 自动完成 - 自定义行为以在进入之前列出所有项目
【发布时间】:2012-05-23 22:13:45
【问题描述】:

我正在尝试为 Rails 3.2 中的字段实现具有特殊行为的自动完成功能。我正在使用 rails 自动完成 gem,我想要做的是:

表单中有一个字段,我希望自动完成在该字段上工作,其中包含配方成分的数量和数量类型。三个不同的输入示例:

100 gramms
2 pices
3.2 kilos

我希望当用户按下空格键并在列表中包含所有可用选项时,该行为具有下拉菜单。当用户输入另一个键时,列表当然会过滤该输入。

是否可以为上述行为自定义 rails 自动完成功能?

【问题讨论】:

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


    【解决方案1】:

    已更新。我原来的回答误解了这个问题。

    第一个选项。

    你修改你的控制器动作。

    # units_controller
    def autocomplete
       term = params[:term]
       quantity, unit = term.split(/\s/)
       items = unit ? Unit.where('units.name LIKE ?',"#{unit}%") : []
       json = items.collect do |item| 
         { "id" => item.id.to_s, 
           "label" => item.name, 
           "value" => "#{quantity} #{item.name} "  
         }
       end
       render json: json
    end
    

    虽然自动完成行为已经正确,但此解决方案不是最理想的,因为即使在我输入数量时它也会访问服务器(并且没有给出任何结果)。

    完整的解决方案涉及修补 rails 自动完成器驱动程序。 保留 abave 自定义控制器操作,只需放置一个自定义 minLength 函数 https://github.com/crowdint/rails3-jquery-autocomplete/blob/master/lib/assets/javascripts/autocomplete-rails-uncompressed.js#L63

    您将此部分修改为:

       search: function() {
         // custom minLength
         var term = extractLast( this.value );
         var filter = jQuery(this).attr('data-input-filter');
         if (filter != null) { 
            var re = new RegExp(filter,"");
            term = term.replace(re, "$1"); //ignore parts of it
         }
         if ( term.length < 1 ) { //modify to 1
           return false;
         }
       },
    

    现在如果你把这个 minlength 过滤器放到你的字段标签中

    'data-input-filter' => j("^.*\s+([^\s]+)$")
    

    它将正确地忽略用户输入的第一位(直到最后一个空格之后),并且仅在您到达单位的第一个字符时才访问服务器。 (这里有点不确定逃脱)

    这种方法的一个优点是您可以将成分自动完成添加到控制器中,并使用逗号并只需将此选项添加到自动完成文本字段帮助程序即可获取多种成分输入:

    "data-delimiter" => ','
    

    然后您可以正确地自动完成输入,例如:

    1 kilo flour, 2 spoons sugar, 100 gramms yeast.
    

    【讨论】:

    • 你是说我的用户输入应该是这样的形式:“10,鸡蛋”?我认为空格会更合适,我希望下拉菜单出现在用户在数字之后的空格之后。
    • 哦,等等,我想我完全误解了你的帖子,你只想要一个自动完成(我以为你想要几个项目一个接一个,就像在 stackoverflow 标记中一样)。相反,您只想要一个而不是仅在空间之后才按数量射击?这也是可能的。
    • 是的,在列表中最初所有可能性的空格后触发数量(因为您没有输入任何字母),然后在输入第一个字母后正常功能。你对如何做到这一点有什么建议吗?
    • 你在使用 rails3-jquery-autocomplete 吗?
    • 是的,我正在使用 rails3-jquery-autocomplete。
    【解决方案2】:

    还有一个纯js的解决方案,所以你可以在你的控制器中保持简单

    # units controller
    autocomplete :unit, :name
    

    你需要修改rails3-jquery-autocomplete js驱动。

    一个关键的线是这个。 https://github.com/crowdint/rails3-jquery-autocomplete/blob/master/lib/assets/javascripts/autocomplete-rails-uncompressed.js#L45 您可以在此处自定义用户输入与发送到服务器以完成的实际术语的关系。

    问题是您还必须确保在选择中插入的值包含数量。由于这个值是从服务器 json 响应中获取的,如果你不将数量发送到服务器,你必须在 extract 的 js 属性中记住它

    function extractLast( term ) {
      var last = split( term ).pop().replace(/^\s+/,"");
      var arr = last.split(/\s+/);
      if (arr.length > 1) {  
         var res = arr.pop();
         jQuery(this).attr('data-quantity').val(arr.join(' '));
      }
      return res;
    }
    

    并在线插入 https://github.com/crowdint/rails3-jquery-autocomplete/blob/master/lib/assets/javascripts/autocomplete-rails-uncompressed.js#L77

    terms.push( (jQuery(this).attr('data-quantity')) + ' ' + ui.item.value );
    

    当然更好的代码会使这取决于我接受的答案中的输入字段数据属性。

    此解决方案也不允许根据数量解析成分或过滤单位,因为只有单位部分是随请求发送的。

    【讨论】:

    • 谢谢 - 我会在 2-3 天内深入研究这个问题,并及时通知你们。
    猜你喜欢
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 2013-09-06
    • 2014-08-23
    • 1970-01-01
    • 2013-10-15
    • 2021-12-05
    • 1970-01-01
    相关资源
    最近更新 更多