如何在Rails中设置jquery-ui自动完成
我需要一些关于如何在Rails应用程序中实现jquery-ui自动完成的帮助。
我想将自动完成添加到用户可以input客户名称的文本字段。 由于可能有数百个客户,我需要从表中提取“远程”build议的自动完成值,至less这是我所理解的。
我不明白的主要问题是如何提供build议值的自动完成文本框。 我已经阅读了jquery-ui文档,但在这个问题上我似乎有点密集。
所以,我真正想要的是一个如何让它在Rails应用程序中工作的例子,而不一定是如何构buildjavascript的完整描述(这就是jquery-ui团队为我所做的)。
例如,如何为自动完成准备数据,以及如何将自动完成function附加到文本框。
那么我从来没有得到上述问题的答案,所以我最终不得不为自己弄清楚。 我想我应该发布我提出的解决scheme,以防有其他人想知道同样的事情。
首先你应该知道的是,这是我第一次使用javascript,而我只是得到了Rails的窍门。 所以,无论如何,随意编辑,评论你觉得我错了这个地方。 至less我知道它的function是我想要的。
我认为最好的方式来展示这是通过示例。 所以下面是我得到的自动完成小部件在我的应用程序中工作。 即使您不明白正在发生的事情,您也可以继续在应用程序中放入以下代码,然后我们可以通过示例了解每个部分的工作方式。 在此之后,您应该掌握如何修改它以供您使用或折射。
包括您的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' %>
在你下载jQuery UI的时候,你将会有一个包含你所有CSS数据的文件夹。 名称会根据您select的主题而有所不同,例如我select了主题“ cupertino ”。 将包含CSS数据的整个文件夹放到“ / public / stylesheets / ”中。 然后像这样在你的application.html.erb中包含CSS文件。
<%= stylesheet_link_tag 'cupertino/jquery-ui-1.8.2.custom' %>
示例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 %>
– 结束大块代码 –
好吧,现在连接点。
提供数据供自动完成,以作为build议使用
让我们开始连接一些自动完成文本字段可以显示在下拉build议中的数据。 我们将使用的格式是JSON,但不要担心,如果你不熟悉它…我也不是=)。 知道这是一种格式化文本的方法,以便其他部分或其他应用程序可以使用它。
在“ source: ”选项中指定了文本字段需要用于自动完成的数据。 因为我们想发送一个人名和他们的ID到自动完成的列表,我们将把以下内容作为源代码。
source: '<%= people_path(:json) %>'
上面的rails helper会翻译成一个string“ /people.json ”。 您不需要在“ /people.json ”中创build页面。 你需要做的是告诉你的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
现在,我们已经将@people中的所有人发送到自动完成文本字段。 这引出了第二点。
用于基于input的自动完成build议的filter数据
自动填充文本字段如何根据您input的内容知道如何过滤结果?
分配给文本字段的自动完成小部件会将您键入的任何内容作为参数发送到您的源代码: 发送的参数是“ term ”。 所以,如果您要在文本框中input“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
现在我们已经根据input到自动完成文本字段的内容限制了分配给@people的logging数量,现在我们可以将其转换为JSON格式以提供自动填充build议。
respond_to do |format| format.html # index.html.erb format.json { render :json => @people.to_json } end
现在,回顾一下“大块代码”中的评论,这应该解释如何联系在一起的其余部分。
最后,你的页面上应该有一个textfield作为自动完成,还有一个隐藏字段,它会把参数中的ID发送给你的控制器。
自定义您自己的AUTOCOMPLETE
一旦你了解了上述内容,并且想要修改它以供使用,则应该知道从控制器返回的JSON格式如下所示:
[{"person":{"id":1,"given_name":"joe","middle_name":"smith","family_name":"jones","nationality":"australian"}}]
在这种情况下,从JavaScript中的JSONstring访问不同的值的方法是:
ui.item.person.name_of_some_attribute_such_as_given_name
漂亮,简单。 很像在Rails中访问ActiveRecord属性。
最后一个音符 我花了很多时间寻找不同的方式来提供隐藏的价值,因为我认为这个function应该已经内置到jQuery的小部件。 然而,这种情况并非如此。 在官方的jQuery示例中清楚地表明,发送不同值然后select作为参数的方式是使用隐藏字段。
那么我希望能帮助别人。
戴尔
jQuery 1.9 / 1.10删除了关键的自动完成并添加了uiAutocomplete
.data("uiAutocomplete") instead of .data("autocomplete")
修改到上面后,它为我工作。
戴尔的答案是相当的教程。 有一件事要注意的是,使用你的第一个查询,数据源将只返回匹配你开始input的string。 如果你想在单词的任何地方search,你需要改变:
@people = Person.find(:all,:conditions => ['given_name LIKE ?', "#{params[:term]}%"])
至
@people = Person.find(:all,:conditions => ['given_name LIKE ?', "%#{params[:term]}%"])
(在查询中增加了一个额外的%
)
我基本上遵循戴尔的build议,但我的控制器和js文件有点不同 – 他的版本给我的问题出于某种原因(也许是jQuery更新)
上下文:我正在尝试自动填充用户input的DJ的名称 – 也是一个新手
DJ控制器
class DjsController < ApplicationController def index if params[:term] @djs = Dj.is_dj.where('lower(name) LIKE ?', "%#{params[:term].downcase}%") respond_to do |format| format.html format.json { render :json => @djs.map(&:name) } end end end end
html.erb文件
<script type="text/javascript"> $(function() { $('#select_origin').autocomplete({ source: '<%= djs_path(:json) %>' }) $('.submit-comment').click(function(){ var dj_name = $('#select_origin').val(); $('#link_origin_id').val(dj_name); }) }) </script>
这是一个很大的帮助。
除了它的情况下,如果你需要提取用户的图像的URL,可能不可能与to_json
。 为此在模型中添加下面的代码。
def avatar_url avatar.url(:thumb) end
然后在控制器而不是to_json
使用as_json
respond_to do |format| format.json {render :json => @users.as_json(:only => [:id,:name,:username], :methods => [:avatar_url]) } end
需要注意的是,如果你的“来源”相对较小,例如50个元素,则实现应该是不同的(并且更简单)。 正式文件第四段提到:
https://api.jqueryui.com/autocomplete/
使用本地数据时,您只需要获取数据并将其传递给自动完成方法,并为您执行过滤。 每次input一个字词时,您都不需要往返于服务器。
function filterByTags(tags) { $("#stories-filter").autocomplete({ source: tags, autoFocus: true }); } $("#stories-filter").click(function() { $.ajax({ dataType: 'json', method: 'GET', url: 'tags/index', data: $(this).data('project-id'), success: function (response) { if(response.success) { var tags = response.data.tags; filterByTags(tags); } }, error: function (response) { if(response.status === 422) { var $errors = 'There are no tags in this project', $errorsContainer = $('.error-container'); $errorsContainer.append($errors); $errorsContainer.show(); } } }); });