LoginSignup
22
25

More than 5 years have passed since last update.

RailsとjQueryでインクリメンタルサーチ

Posted at

Ruby(Rails3)とjQueryでインクリメンタルサーチの処理を書いてみたのでまとめました。

元記事

下記エントリの転載になります。
RailsとjQueryで、簡単インクリメンタルサーチ - rokuroFire

本エントリの前提

  • インクリサーチは、ポスト(Model:Post)のタイトル(title)を検索
  • json形式でデータを受け取り、JSでページを更新

ルーティング

今回はposts/newページ内で利用するので:postsのcollection内に入れました。

config/routes.rb
resources :posts do
    collection do
        get 'search', :action => :search
        # posts/search
    end
end

Controller

params[:q]に、クエリのデータが入っています。
Model:Postのtitleから、クエリの文字列を含むものを最大3件取得しています。

app/controllers/posts_controller.rb
def search
    raise unless params[:q]

    lists = []
    results = Post.where("title like ?", "%#{params[:q]}%").order('count DESC').limit(3)
    results.each do |result|
        lists.push({:title => result.title) if result.title
    end
    render :json => { :lists => lists, :result => "success"}
    return true

    rescue
    render :json => {:result => "error_search" }
end

JavaScript

検索枠にテキストを入力し、500ms経ったあとに1回ajax通信を行います。
onkeypressでイベントを発生させているため、文字入力を行う度にincSearch関数が実行されます。関数内でclearTimeoutを実行することで、関数実行時にタイマーがリセットされるため、関数の実行回数 = 通信の回数にはならないようにしています。

※ DOMの処理は省略
※ 実際は、エンターキーを押した時の分岐やonblurイベントも加えないと、思い通り動かないかも?

application.js
// ajax処理
function incSearch(){
    // タイマーをストップ
    clearTimeout(incSearch.timeid);

    // setTimeout 500ms
    incSearch.timeid = setTimeout(function(){
        // inputに入力されているテキストを取得
        var query = tgtInput.value;
        if(query.length == 0) return false;

        // ajax処理
        jQuery.ajax({
            type : 'GET',
            url : '/posts/search',
            data : {
                q : query
            },
            timeout : 1500,
            success:function(data){
                if(data.result != "success") return false;
                changeDom(data.lists);
            },
            error:function(){
                // エラー時の処理をここに書く
                return false;
            }
        });

    },500);

};
incSearch.timeid = "";

// DOMの変更
// 引数listsに検索結果が入っている
function changeDom(lists){
    if(lists.length == 0) return false;
    // ここにDOMを書き換える処理を書く
};

// ターゲットとなるinputタグにイベント追加
var tgtInput = document.getElementById('tgtInput');
tgtInput.onkeydown = incSearch;

22
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
25