オートコンプリート機能とは、検索する時などに勝手に候補リストが出現し、ユーザの入力補助をしてくれるものです。
動画で見るとこのような感じです。これを目指します。
フォーム
まず、フォーム側のソースを載せておきます。(一部省略)
<%= form_with model: Message.new do |form| %>
<div>
題名 <%= form.text_field :title, class: "form-control book-title", aria_describedby: "basic-addon2", autocomplete: "off" %>
</div>
<div>
著者 <%= form.text_field :writer, class: "form-control book-writer", aria_describedby: "basic-addon2", autocomplete: "off" %>
</div>
<% end %>
本フォームの仕様としては、ユーザがキーワードを入力した際に、Google Books APIより該当する本のタイトルを取得し、その一覧をオートコンプリートで表示させるというものです。
オートコンプリートとは直接関係ないですが、候補を選択した際に自動的にその著者が「著者」欄に補完されるようになっています。
jQuery部分
オートコンプリートの実装にはjQuery UIを用いるのが一番簡単です。jQuery UIとは、jQueryの中でも便利な部品をまとめたライブラリのことです。
jQuery(document).on('turbolinks:load', function () {
$(".book-title").on("keyup", function () {
$(".book-title").autocomplete({
source: getSource,
open: function () {
$('.ui-autocomplete').css('z-index', 2147483647);
$('.ui-menu').css('z-index', 2147483647);
}
});
});
});
一つ一つ説明していきます。
“.book-title”はフォーム部分のソースからも分かるように、本の題名を入力するテキストボックスです。
オートコンプリートを実装するのは簡単で、上記のようにautocomplete関数を用いるだけでOKです。sourceオプションを使用し、getSource(後述)からデータを受け取り、それを入力候補として表示させます。
openは、入力候補が表示されるときの挙動をカスタマイズするイベントオプションです。ここではz-index を指定していますが、これはたまに入力候補欄が他の要素の下に潜り込んでしまうことがあるからです。(必要ないかもしれません)
他にもオプションはたくさんあります。
詳しくは公式ドキュメントを参照してください。
https://api.jqueryui.com/autocomplete/
データを持ってくる部分 & ajax
上記でgetSourceとしていた部分です。
$.ajax({
type: "GET",
url: "/booksuggest",
data: {
keyword: request.term
},
dataType: 'json',
}).fail( function (xhr, ts, err) {
$('.input-group').after('<p>ページを再読み込みしてください。</p>');
}).done(function (data) {
//***何らかの処理***
response(titles);
});
ajax通信には、$.ajaxを用います。url, typeでアクセス先を指定しています。ここではコントローラを指定しており、keyup => コントローラ => APIで情報取得 => getSource => autocompleteで表示のようなデータの流れで進んでいきます。
その際には、dataオプションでkeywordパラメータとしてrequest.termを送っています。request.termとは、ここではテキストボックスに入力した文字列を指します。これによりコントローラ側でparams[:keyword]とすることで文字列を取得できます。
その後、コントローラから受け取ったデータをresponseとしてそれを指定することで、autocompleteのsourceオプションで受け取ることができます。
その他オプション
動画内で、入力候補が選ばれた際に著者欄に「夏目漱石」と自動補完されていました。
選択された際の挙動をカスタマイズするには、selectイベントを用います。
select: function (e, ui) {
//**略**
//著者のテキストボックス
$(".book-author").val(selected_data["author"]);
}
コメント