今作ってるアプリケーションではTurbolinksを効かせてて、かなりいい感じだな〜と思ってるのですが、一覧で検索した結果や表示件数を変更した場合に、ページの更新が発生してサクサク移動してたのに、ここでもたつくなぁ…と課題に感じていました。
なんとなくググってみたところ、TurbolinksのTipsとしてissueに上げられていたのでこりゃいい!と思ったので、やり方を書いておきます。
元ネタはここです。
元ネタのほうだと、jQueryを使っていたりしたので依存度を下げたい。また、data-remote=true
を対象にしていたりして、なんかよくわかりません・・・。data-remote=true
はもともとAjaxで値を取得しにいくから、ダメじゃないの?って思うんですが…。画面の一部を書き換えるときとかならわかるのですが、全体を書き換えたいのを対象にするのであれば、上記の一番最初のサンプルコードのように、data-remote=false
を対象とするべきでしょう。しかし、form_with
ヘルパーメソッドでlocal=true
にした場合、data-remote=false
という属性は出力されていないので、data-remote=true
を除外する、というアプローチをとります。
コードを紹介
gistを作っておいたのでそちらを見てみましょう。
Support GET from with Turbolinks.
解説
やっていることは以下の通り。
turbolinks:load
イベントで、Turbolinksに委ねてもいいフォームを抽出する- フォームの
submit
イベントを拾うよう設定する - 本来のsubmitイベントをキャンセルする
- 現在のページと遷移先にページが同じ場合、perパラメータを引き継ぐ(kaminariの表示件数)
- フォームに入力されたものをクエリ文字列に変換する
Turbolinks.visit
で移動する
これの肝はクエリセレクタでうまいこと対象のフォームだけを抽出することです。
document.querySelectorAll('form[method=get]:not([data-remote=true])')
で、GETメソッドだけどdata-remote=true
のものは除外しています。
また、ページングのgemであるkaminariを使っているので、表示件数をコントロールできるようにするため、pathnameに変更がない場合はperパラメータは引き継ぐようにしました。
まとめ
これで、検索フォームも超速くなりました🚀