How to set-up jquery-ui autocomplete in Rails

后端 未结 7 1140
被撕碎了的回忆
被撕碎了的回忆 2020-11-27 09:55

I need some help on how to implement a jquery-ui autocomplete in my Rails app.

I want to add autocompletion to a text field where the user can enter in a customer na

7条回答
  •  渐次进展
    2020-11-27 10:19

    Well I never got an answer to my question above so I ended up having to figure it out for myself. I thought I should post the solution I came up with in case there are any other guys out there who are wondering the same thing.

    First thing you should know is that this is my first experience with javascript, and I am just getting the hang of Rails. So by all means, feel free to edit, comment anywhere you feel I have gone wrong with this. Right or wrong at least I know that it functions the way I wanted it to.

    I think the best way to show this is by example. So the following is how I got the autocomplete widget to work in my app. You can go ahead and put the following code in your app even if you don't understand what is happening, then we can go over how each part is working by example. After this you should have a grasp on how to modify it for your use or refractor it.


    INCLUDE JQUERY UI IN YOUR RAILS APP.

    Download a copy of the jQuery UI and place jquery-ui-1.8.2.custom.min.js inside your /public/javascript directory. Also make sure you have a copy of jQuery itself and that this is also in the same folder.

    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' %>
    

    In your download of jQuery UI, you will have a folder that contains all of your CSS data. The name will vary based on the theme you chose, for example I chose the theme 'cupertino'. Place the entire folder containing your CSS data into '/public/stylesheets/'. Then include the CSS file in your application.html.erb like this.

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


    EXAMPLE AUTOCOMPLETE JAVASCRIPT

    Now take the following chunk of code and place it in one of your 'new' views. You can use this in any view, but realize that I have literally taken it from an existing view belonging to a controller called 'links_controller', and it is pulling data from a 'people_controller'. Hopefully you know enough about Rails to work out what you need to change so this works for you.

    -- Begin big chunk of code --

        
    
    
    
    

    New link

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

    Select which person you want to link:

    <%= f.label :rcvd_id %>
    <%= f.text_field :rcvd_id %>

    <%= f.label :link_type %>
    <%= f.text_field :link_type %>

    <%= f.label :summary %>
    <%= f.text_area :summary %>

    <%= f.label :active %>
    <%= f.check_box :active %>

    <%= f.submit 'Create' %>

    <% end %>

    -- End Big Chunk of Code --

    Okay now to connect the dots.


    PROVIDE DATA FOR AUTOCOMPLETE TO USE AS SUGGESTIONS

    Lets start by connecting up some data that the autocomplete textfield can display in the drop down suggestions. The format we will be using is JSON, but don't worry if you are not familiar with it ... neither am I =). It is good enough to know that it is a way to format text so that other parts of yours/other applications can use it.

    The data the textfield will need for the autocomplete is specified in the 'source:' option. Because we want to send a list of peoples names and their ID to the autocomplete we will put the following as the source.

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

    The rails helper above will translate to a string "/people.json". You do not need to create a page at "/people.json". What you do need to do is tell your people_controller what to do when it receives a request for /people with the .json format. Put the following into your 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
    

    Now we have all the people in @people being sent to the autocomplete textfield. This brings up the very next point.


    FILTER DATA USED FOR AUTOCOMPLETE SUGGESTION, BASED ON INPUT

    How does the autocomplete textfield know how to filter the results based on what you type?

    The autocomplete widget assigned to the textfield will send whatever you type into the textfield as a parameter to your source:. The parameter being sent is "term". So if you were to type "Joe" into the textfield, we would be doing the following:

    /people.json?term=joe
    

    That is why we have the following in the controller:

    # 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
    

    Now that we have limited the number of records assigned to @people based on what is typed into the autocomplete textfield, we can now turn that into JSON format for the autocomplete suggestions.

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

    Now, just review the comments inside the "Big Chunk of Code" which should explain the rest of how this ties together.

    At the end you should have a textfield on your page that acts as the autocomplete and a hidden field that will send the ID in a parameter to your controller.


    CUSTOMIZE YOUR OWN AUTOCOMPLETE

    Once you understand the above and you want to modify it for your use, you should know that the format JSON returned from your controller looks like this:

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

    The way to access the different values from the JSON string in your javascript in this case would be:

    ui.item.person.name_of_some_attribute_such_as_given_name

    Pretty, simple. A lot like accessing an ActiveRecord attribute in Rails.

    One last note. I spent a lot of time looking for a different way to supply the hidden value, as I thought this function should have been built into the jquery widget. However, this is not the case. It is clearly shown in the official jQuery example that the way to send a different value then selected as a parameter, is to use a hidden field.

    Well I hope that helps somebody.

    Dale

提交回复
热议问题