我需要一些关于如何在Rails应用程序中实现jquery-ui autocomplete的帮助.

我想在文本字段中添加自动补全功能,用户可以在其中输入客户名称.由于可能有数百名客户,我需要从表中"远程"提取建议的自动完成值(至少我了解到这一点).

我没有理解的主要一点是如何向自动完成文本框提供建议值.我已经阅读了jquery ui文档,但我似乎对这件事有点不了解.

因此,我真正想要的是一个如何在Rails应用程序中实现这一点的示例,而不一定是对如何构建javascript的完整描述(这就是jquery ui团队为我所做的=).

例如,如何为自动完成准备数据,以及如何将自动完成功能附加到文本框.

推荐答案

嗯,我从来没有得到我上面问题的答案,所以我最终不得不自己找出答案.我想我应该发布我想出的解决方案,以防其他人也有同样的 idea .

你应该知道的第一件事是,这是我第一次使用javascript,我刚刚掌握了Rails的窍门.所以,无论如何,请随意编辑, comments 任何你觉得我有问题的地方.不管是对是错,至少我知道它的功能是我想要的.

我认为最好的方式是通过例子来说明这一点.下面是我如何让autocomplete小部件在我的应用程序中工作的.即使你不明白发生了什么,你也可以继续在你的应用程序中输入以下代码,然后我们可以通过示例来了解每个部分是如何工作的.在此之后,你应该掌握如何修改它供你使用或折射它.


INCLUDE JQUERY UI IN YOUR RAILS APP.

下载jQuery UI的副本,将jquery-ui-1.8.2.custom.min.js放在/public/javascript目录中.还要确保您有一份jQuery本身的副本,并且它也在同一个文件夹中.

Include the jQuery UI file and the jQuery file in your application.html.erb file like this.
(you can name the files as you please as long as they match)

<%= javascript_include_tag 'jquery.min', 'jquery-ui-1.8.2.custom.min.js' %>

在下载的jQuery UI中,您将拥有一个包含所有CSS数据的文件夹.名称将根据您 Select 的主题而有所不同,例如,我 Select 了主题"cupertino".将包含CSS数据的整个文件夹放入"/public/stylesheets/"中.然后在应用程序中包含CSS文件.html.像这样.

<%= stylesheet_link_tag 'cupertino/jquery-ui-1.8.2.custom' %>


EXAMPLE AUTOCOMPLETE JAVASCRIPT

现在,将下面的代码块放到"new"视图中.您可以在任何视图中使用它,但请注意,我实际上是从一个名为"links\u controller"的控制器的现有视图中获取它的,它正在从"people\u controller"中提取数据.希望您对Rails有足够的了解,能够找到需要更改的内容,从而使其适合您.

--开始大量代码--

    <script type="text/javascript">
    $(function() {

 // Below is the name of the textfield that will be autocomplete    
    $('#select_origin').autocomplete({
 // This shows the min length of charcters that must be typed before the autocomplete looks for a match.
            minLength: 2,
 // This is the source of the auocomplete suggestions. In this case a list of names from the people controller, in JSON format.
            source: '<%= people_path(:json) %>',
  // This updates the textfield when you move the updown the suggestions list, with your keyboard. In our case it will reflect the same value that you see in the suggestions which is the person.given_name.
            focus: function(event, ui) {
                $('#select_origin').val(ui.item.person.given_name);
                return false;
            },
 // Once a value in the drop down list is selected, do the following:
            select: function(event, ui) {
 // place the person.given_name value into the textfield called 'select_origin'...
                $('#select_origin').val(ui.item.person.given_name);
 // and place the person.id into the hidden textfield called 'link_origin_id'. 
        $('#link_origin_id').val(ui.item.person.id);
                return false;
            }
        })
 // The below code is straight from the jQuery example. It formats what data is displayed in the dropdown box, and can be customized.
        .data( "autocomplete" )._renderItem = function( ul, item ) {
            return $( "<li></li>" )
                .data( "item.autocomplete", item )
 // For now which just want to show the person.given_name in the list.
                .append( "<a>" + item.person.given_name + "</a>" )
                .appendTo( ul );
        };
    });
    </script>



<h1>New link</h1>

<% form_for(@link) do |f| %>
  <%= f.error_messages %>

<!-- Place the following text fields in your form, the names are not important. What is important is that they match the names in your javascript above -->
  <p>
        Select which person you want to link:<br /> 
<!-- This is the textfield that will autocomplete. What is displayed here is for the user to see but the data will not go anywhere -->
        <input id="select_origin"/>
<!-- This is the hidden textfield that will be given the Persons ID based on who is selected. This value will be sent as a parameter -->
      <input id="link_origin_id" name="link[origin_id]" type="hidden"/>
  </p>
<!-- end of notes -->
  <p>
    <%= f.label :rcvd_id %><br />
    <%= f.text_field :rcvd_id %>
  </p>
  <p>
    <%= f.label :link_type %><br />
    <%= f.text_field :link_type %>
  </p>
  <p>
    <%= f.label :summary %><br />
    <%= f.text_area :summary %>
  </p>
  <p>
    <%= f.label :active %><br />
    <%= f.check_box :active %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

--结束大量代码--

好的,现在把这些点连接起来.


PROVIDE DATA FOR AUTOCOMPLETE TO USE AS SUGGESTIONS

让我们首先连接自动完成文本字段可以在下拉建议中显示的一些数据.我们将使用的格式是JSON,但如果您不熟悉,请不要担心...我也是.知道这是一种格式化文本的方法就足够了,这样您/其他应用程序的其他部分就可以使用它了.

文本字段自动完成所需的数据在"source:"选项中指定.因为我们想向自动完成程序发送一份人名和ID列表,所以我们将以下内容作为源代码.

source: '<%= people_path(:json) %>'  

上面的rails助手将转换为字符串"/people.json".您不需要在"/people.json"处创建页面.您需要做的是告诉您的人员控制器,当它收到请求时,应该做什么.json格式.将以下内容放入您的people_控制器:

def index  
# I will explain this part in a moment.
  if params[:term]
    @people = Person.find(:all,:conditions => ['given_name LIKE ?', "#{params[:term]}%"])
  else
    @people = Person.all
  end

  respond_to do |format|  
    format.html # index.html.erb  
# Here is where you can specify how to handle the request for "/people.json"
    format.json { render :json => @people.to_json }
    end
end

现在,@people中的所有人都被发送到自动完成文本字段.这就引出了下一点.


FILTER DATA USED FOR AUTOCOMPLETE SUGGESTION, BASED ON INPUT

自动完成文本字段如何根据您键入的内容过滤结果?

分配给textfield的autocomplete小部件将把您在textfield中键入的任何内容作为参数发送到源:.发送的参数为"term".因此,如果要在文本字段中键入"Joe",我们将执行以下操作:

/people.json?term=joe

这就是为什么控制器中有以下内容:

# If the autocomplete is used, it will send a parameter 'term', so we catch that here
    if params[:term]
# Then we limit the number of records assigned to @people, by using the term value as a filter.
      @people = Person.find(:all,:conditions => ['given_name LIKE ?', "#{params[:term]}%"])
# In my example, I still need to access all records when I first render the page, so for normal use I assign all. This has nothing to do with the autocomplete, just showing you how I used it in my situation.
    else
      @people = Person.all
    end

现在,我们已经根据自动完成文本字段中键入的内容限制了分配给@people的记录数量,现在我们可以将其转换为JSON格式,用于自动完成建议.

respond_to do |format|  
      format.html # index.html.erb  
      format.json { render :json => @people.to_json }
    end 

现在,只需查看"大块代码"中的注释,这些注释应该可以解释其余的代码是如何联系在一起的.

最后,你的页面上应该有一个文本字段作为自动完成,还有一个隐藏字段将参数中的ID发送给你的控制器.


CUSTOMIZE YOUR OWN AUTOCOMPLETE

一旦您理解了上述内容,并希望对其进行修改以供使用,您应该知道从控制器返回的JSON格式如下所示:

[{"person":{"id":1,"given_name":"joe","middle_name":"smith","family_name":"jones","nationality":"australian"}}]

在本例中,从javascript中的JSON字符串访问不同值的方法是:

用户界面.项目人某些属性的名称,例如给定的名称

漂亮,简单.很像在Rails中访问ActiveRecord属性.

最后一个音符.我花了很多时间寻找一种不同的方式来提供隐藏值,因为我认为这个函数应该内置到jquery小部件中.然而,事实并非如此.在正式的jQuery示例中可以清楚地看到,发送不同的值然后 Select 作为参数的方法是使用隐藏字段.

我希望这能帮到别人.

山谷

Ruby-on-rails相关问答推荐

轨道强参数,怎么允许空参数?

Puma 工作人员无法在 Ubuntu 20.04 VM 上的 Rails 5.2 中启动

Trailblazor 操作 -> 集合 :attribute(has_many 通过关联) 与填充器 -> 如何填充 Reform::Form 形式的 slugs 数组?

如何从 New Relic 交易中获取 TraceId?

Ruby:如何通过谓词将一个集合拆分为 ruby​​ 中的两个集合?

来自控制台的 ActionCable.server.broadcast

SQLite3::BusyException

Rails 将 form_for 对象传递给部分

在 Ruby on Rails 中获取空临时目录的最佳方法是什么?

如何在where子句中组合两个条件?

从 before_action 中排除控制器

URL中的Rails点而不是斜杠

Ruby 和 Ruby on Rails 离线 API 文档

您将如何在 RoR 中创建类似 SO 或 Facebook 的通知系统?

counter_cache 实现的问题

Rails 4,Capistrano 3.0.0,无法加载这样的文件 - 部署

rails respond_to format.js API

rake db:回滚不起作用?

从模型中获取验证

rails 3,如何在 Settings.yml 文件中使用 ENV 配置变量?