การใช้ autocomplete ใน Rails

สร้างฐานข้อมูลโดยมี table ชื่อ dishes และมี field ดังนี้

create table dishes (
  id int not null auto_increment,
  name varchar(50) not null,
  descript varchar(100),
  primary key(id)
);

ใส่ข้อมูลลงในฐานข้อมูลที่ได้สร้างขึ้นมา โดยข้อมูลตัวอย่างมีดังนี้

insert into dishes (name, descript) values ("ข้าวผัดกะเพราหมูแดง", "ผัดกะเพราหมูแดง");
insert into dishes (name, descript) values ("ข้าวคะน้าหมูกรอบ", "ผัดคะน้าใส่หมูกรอบ");
insert into dishes (name, descript) values ("ข้าวคอหมูย่าง", "เนื้อหมูย่างราดน้ำจิ้มเผ็ด");

สร้าง controller ขึ้นมาเพื่อใช้งาน autocomplete โดยเพิ่ม auto_complete_for ตามด้วยชื่อ model และ field ที่ต้องการ

class DishController < ApplicationController
  auto_complete_for :dish, :name
end

ในส่วนของ view นั้นให้ใช้ text_field_with_auto_complete ดังนี้

  <head>
    <title>เพิ่มรายการอาหาร</title>
    <%= javascript_include_tag :defaults %>
  </head>
 
  <body>
    <h2>เพิ่มรายการอาหาร</h2>
    ชื่ออาหาร: <%= text_field_with_auto_complete :dish, :name, { :size => 20 }, {:skip_style => true} %><br />
    รายละเอียด: <%= text_field :dish, :descript %>
  </body>

หมายเหตุ

1. หากมีกรณีที่ต้องการ autocomplete หลายครั้งใน text field เดียวกันสามารถทำได้โดยการแบ่งคำด้วย token ที่กำหนดดังนี้

<%= text_field_with_auto_complete :dish, :name, { :size => 20 }, {:skip_style => true, :tokens => ", "} %>

2. หากต้องการให้ไปทำ autocomplete หลายๆ field นั้น สามารถทำได้โดยมีขั้นตอนดังนี้

  • เพิ่ม code ด้านล่างนี้ไว้ในส่วน controller และหากมี auto_complete_for :dish, :name ให้ลบทิ้งได้เลย
    def auto_complete_for_dish_name
      auto_complete_responder_for_dishes params[:dish][:name]
    end
     
    private
      def auto_complete_responder_for_dishes(value)
        @dishes = Dish.find(:all, :conditions => [ 'LOWER(name) LIKE ?', '%' + value.downcase + '%' ], :limit => 10)
        render :partial => 'dishes'
      end
  • สร้างไฟล์ _dishes.rhtml ไว้ในส่วนของ view และอยู่ใน folder ที่ชื่อเดียวกับ controller
    <ul class="dishes">
      <% unless @dishes.nil? -%>
        <% for dish in @dishes -%>
          <li>
            <%=h ("#{dish.name}") %>
            <div class="NAME" style="display: none;"><%=h dish.name %></div>
            <div class="DESCRIPT" style="display: none;"><%=h dish.descript %></div>
          </li>
        <% end -%>
      <% end -%>
    </ul>
  • ส่วนของ view นั้น แก้ไขเล็กน้อย เพื่อสามารถให้ค่ากับ field อื่นได้
      <head>
        <title>เพิ่มรายการอาหาร</title>
        <%= javascript_include_tag :defaults %>
      </head>
      <body>
        <h2>เพิ่มรายการอาหาร</h2>
        ชื่ออาหาร:
        <%=
            text_field_with_auto_complete :dish, :name, { :size => 50, :autocomplete => “off”, :select => “value”} , :after_update_element => “function (text, li)
                {
                  $(’dish_name’).value = Ajax.Autocompleter.extract_value(li, ‘NAME’);
                  $(’dish_descript’).value = Ajax.Autocompleter.extract_value(li, ‘DESCRIPT’);
                }%><br />
        รายละเอียด: <%= text_field :dish, :descript %>
      </body>