如何在Rails中设置jquery-ui自动完成

Osc*_*car 53 jquery-ui autocomplete ruby-on-rails jquery-ui-autocomplete

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

我想将自动填充添加到用户可以输入客户名称的文本字段中.由于可能有数百个客户,我需要从表中"远程"拉出建议的自动完成值(至少这是我所理解的).

我无法理解的要点是如何为自动完成文本框提供建议值.我已经阅读了jquery-ui文档,但在这个问题上我似乎有点密集.

所以我真正追求的是一个如何在Rails应用程序中使用它的示例,不一定是javascript如何构建的完整描述(这就是jquery-ui团队为我做的事情=)).

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

Osc*_*car 146

好吧,我从来没有得到上面的问题的答案,所以我最终不得不为自己弄明白.我想我应该发布我提出的解决方案,以防有任何其他人想知道同样的事情.

你应该知道的第一件事是这是我第一次使用javascript,我只是掌握了Rails.所以无论如何,随时随地编辑,评论您认为我出错的地方.对或错至少我知道它的功能是我想要的.

我认为展示这个的最好方法就是举例.以下是我如何让自动完成小部件在我的应用程序中工作.即使您不了解正在发生的事情,您也可以继续将以下代码放入您的应用程序中,然后我们可以通过示例了解每个部分的工作方式.在此之后,您应该掌握如何修改它以供您使用或折射它.


在您的铁路APP中包含JQUERY UI.

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

像这样在您的application.html.erb文件中包含jQuery UI文件和jQuery文件.
(您可以根据需要命名文件,只要它们匹配)

<%= javascript_include_tag 'jquery.min', 'jquery-ui-1.8.2.custom.min.js' %>
Run Code Online (Sandbox Code Playgroud)

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

<%= stylesheet_link_tag 'cupertino/jquery-ui-1.8.2.custom' %>
Run Code Online (Sandbox Code Playgroud)


示例AUTOCOMPLETE JAVASCRIPT

现在,将以下代码块放在一个" "视图中.你可以在任何视图中使用它,但是我意识到我从属于名为'links_controller'的控制器的现有视图中获取它,并且它从'people_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 %>
Run Code Online (Sandbox Code Playgroud)

- 结束大代码 -

好的,现在连接点.


为自动提供自动提供数据作为建议使用

让我们首先连接自动填充文本字段可以在下拉建议中显示的一些数据.我们将使用的格式是JSON,但如果您不熟悉它,请不要担心......我也不是.).很高兴知道它是一种格式化文本的方式,以便您/其他应用程序的其他部分可以使用它.

自动填充所需的文本字段数据在' source: '选项中指定.因为我们想要将人名和他们的ID列表发送到自动完成,所以我们将以下内容作为源.

source: '<%= people_path(:json) %>'  
Run Code Online (Sandbox Code Playgroud)

上面的rails helper将转换为字符串" /people.json ".您无需在" /people.json " 处创建页面.您需要做的是告诉您的people_controller在收到/ .json格式的人的请求时该怎么做.将以下内容放入people_controller:

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
Run Code Online (Sandbox Code Playgroud)

现在我们将@people中的所有人都发送到自动填充文本字段.这提出了下一点.


基于输入的过滤数据用于自动建议

自动填充文本字段如何根据您键入的内容了解如何过滤结果?

分配给文本字段的自动完成小部件会将您输入的任何内容作为参数发送到文本字段:发送的参数是" term ".因此,如果您在文本字段中键入"Joe",我们将执行以下操作:

/people.json?term=joe
Run Code Online (Sandbox Code Playgroud)

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

# 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
Run Code Online (Sandbox Code Playgroud)

现在我们根据输入到自动填充文本字段的内容限制了分配给@people的记录数量,现在我们可以将其转换为JSON格式以获取自动填充建议.

respond_to do |format|  
      format.html # index.html.erb  
      format.json { render :json => @people.to_json }
    end 
Run Code Online (Sandbox Code Playgroud)

现在,只需查看"Big Chunk of Code"中的评论,这些评论应该解释其中如何联系在一起的其余部分.

最后,您应该在页面上有一个充当自动完成的文本字段和一个隐藏字段,该字段将参数中的ID发送到您的控制器.


自定义您自动完成的自定义

一旦理解了上述内容并且想要修改它以供您使用,您应该知道从控制器返回的格式JSON如下所示:

[{"person":{"id":1,"given_name":"joe","middle_name":"smith","family_name":"jones","nationality":"australian"}}]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,从javascript中的JSON字符串访问不同值的方法是:

ui.item.person.name_of_some_attribute_such_as_given_name

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

最后一点.我花了很多时间寻找一种不同的方式来提供隐藏值,因为我认为这个函数应该已经内置到jquery小部件中.然而,这种情况并非如此.官方jQuery示例中清楚地显示,发送不同值然后选择作为参数的方法是使用隐藏字段.

好吧,我希望能帮到别人.

戴尔

  • +1自己搞清楚并分享财富!谢谢! (4认同)
  • @paz你应该拥有自己的博客,如果你还没有:)非常好,正是我想要的. (3认同)
  • 为我工作,但是,我必须将item.person.property_name更改为item.property_name,返回的json没有"person":{...} (3认同)
  • 谢谢.这是一个很大的帮助. (2认同)
  • 很好的解释.这个地方有很多零碎的提示和技巧,但直到现在我还没有找到一个简洁的端到端的例子.谢谢您的帮助... (2认同)

Aru*_*run 11

jQuery 1.9/1.10删除了密钥自动完成并添加了uiAutocomplete

.data("uiAutocomplete") instead of .data("autocomplete")
Run Code Online (Sandbox Code Playgroud)

修改为上面后,它对我有用.


小智 7

戴尔的答案就是教程.需要注意的一点是,使用您的第一个查询,数据源将仅返回以您键入的字符串开头的匹配项.如果您想在单词中的任何位置进行搜索,则需要更改:

@people = Person.find(:all,:conditions =>
    ['given_name LIKE ?', "#{params[:term]}%"])
Run Code Online (Sandbox Code Playgroud)

@people = Person.find(:all,:conditions =>
    ['given_name LIKE ?', "%#{params[:term]}%"])
Run Code Online (Sandbox Code Playgroud)

(%为查询添加了额外的内容)