【Jquery】【Ruby on Rails】select2でAjaxを使う

select2の説明は至るところにあるので省きます。

最初に作成したもののデモ

http://workshops.ddns.net/

手順

まずは、APIを返す側のコントローラーのルートを設定。 私はこんな感じ

# vi config/routes.rb
get "api/v1/addresses/select2"

コントローラーの設定

    # vi app/controllers/api/v1/addresses_controller.rb
    def select2
      if params[:term]
        @addresses = Address.where('full_text LIKE ?', '%' + params[:term].to_s + '%')
        @address = @addresses.page(params[:page]).per(params[:page_limit])
      end
      puts @address.count
      respond_to do |format|
        format.json {
          render :json => {
            :addresses => @address,
            :total => @addresses.count,
            :links => { :self => @address.current_page , :next => @address.next_page}
          }
        }
      end
    end

APIの返却値は以下のような住所を返すよう設計

{
    "addresses":[
      {"id": 10589, "state": "千葉県", "city": "松戸市", "street_number": "",…},
      {"id": 11030, "state": "千葉県", "city": "いすみ市", "street_number": "",…},
      {"id": 11253, "state": "千葉県", "city": "印西市", "street_number": "",…},
      (略)
    ],
    "total": 2219,
    "links":{
      "self": 1,
      "next": 2
    }
}

次にJavaScript

  $("#address-search").select2({
    ajax: {
      url: "http://workshops.ddns.net/api/v1/addresses/select2",
      dataType: 'json',
      delay: 250,
      data: function (params, page) {
        return {
          term: params, // ?term=params
          page_limit: 10,
          page: page,
        };
      },
      results: function (data, page) {
        var more = (page * 10) < data.total;                
          return {results: data.addresses, more: more};
      }
    },
    formatResult: addressFormatResult,
    formatSelection: addressFormatSelection, 
    minimumInputLength: 1,
  });
  
  function addressFormatResult(address) {
    var markup = "<table class='address-result'><tr>";
    markup += "<td class='address-info'><div class='address-value'>" + address.state +' '+ address.city + "</div>";
    markup += "</td></tr></table>"
    return markup;
  }
  
  function addressFormatSelection(address) {
     return (address.state + ' ' + address.city);
  }

最後にフォーム

    <input type="hidden" name="address" id="address-search" placeholder="東京">

以上