前回、collection_selectによりプルダウンリストを作る方法を整理しましたが、
今回は入力フォーム画面で、プルダウンで事前に作っておいたテンプレートを選択したらそれを自動でフォームに反映されるような機能の実装の仕方をまとめておきます
ポイントとしては、フォームにテンプレートを反映させる際に、フォーム画面から移動したりページ更新したりせずに自動でぽんと文字を出したいのです。
この処理にはAjaxを利用します。
Ajaxについては参考リンク1がざっくり概要を掴むにはいいかも。
実装中に理解が追いつかずかなりテンパりながら実装していましたw
先生に教えてもらい完全に理解したと言えないもののとりあえず意図したように動くものができてます
書き起こすとちょっとボリュームが多そうなので何回かに分けます。
プルダウンリストでTemplateのnameを選択すると、そのTemplateのbodyカラムがページ遷移せずに自動で指定のフォームに入力される、という機能を作りたい。
(1)まずjQueryをRailsで動かせるようにする
- Gemfile と application.js に書き足す
(2)ルーティング
- routes.rb に記述
(3)ajax通信したいフォームをパーシャル化して中身を記述
- views/works以下に_work_body.html.erbというパーシャル作成
<↑今回ココまで↑>
(4)プルダウンを選択したらJavascriptの機能を呼び出すように記述
- collection_selectにHTMLオプションでonchangeでJavascriptメソッドを
(5)Javascriptで具体的な機能を記述
(6)コントローラーの中にajaxに関連する処理を記述
- templatesコントローラーに記述
- respond_toの中にformat.jsを記述してajaxを使用可能に
(7)ajaxで呼び出されるjsファイルを作成し、中身を記述
- views/templates以下にget_body.js.erbというファイル作成
具体的にみていきます。
今回は(1)〜(3)まで。
参考リンク2を参照ということにして詳細は別の機会に。
ルートファイルにルーティングを記述します。
後ほど、templatesコントローラーにget_bodyメソッドを追加して、そこで選択されたtemplateの内容を取得する処理を記述することになります。
なので先にパスを生成しちゃいます。
この時のHTTPメソッドはgetで良さそうです。
config/locales/routes.rb
get 'templates/get_body'
ajax通信する部分をパーシャル化する必要があるようです。
ここでは、プルダウンリストを選択したら自動で内容を反映させたいフォームに当たります。
まずは_work_body.html.erb
という名前でviews/works
ディレクトリの以下にパーシャルファイルを作ります。
次にビューのフォーム画面の該当フォーム部分を、下記のように変更します。
views/works/_form.html.erb
<div><%= render 'work_body', form: form %></div>
こんな感じ。renderで同じviews/works
ディレクトリ内の、_work_body.html.erb
を探して読み込んでくれます。
後半のform: form
についてですが、form_with
でformという変数を渡しているので、これもrender先に渡す必要があるのでこのように記述しています。
この部分、ちょっと全体像が見えづらいので補足にコードを書いておきます。
次に肝心のパーシャル化したフォームに必要な記述を書いておきます。
views/works/_work_body.html.erb
<%= form.text_area :body, id: "template_body", :size => "40x10" %>
先述した通りform変数が渡されてきているので、form_with
によりフォームが生成されます。
idで謎のtemplate_bodyというものが出てきますが、後述。
(続く)
フォームのビューの全体像が見えづらいので補足。
最終的なコードはこんな感じになります。
views/works/_form.html.erb
<%= form_with(model: [diary, work], local: true) do |form| %>
<label>日付</label>
<div><%= diary.date %></div>
<label>カテゴリ</label>
<div><%= form.text_field :category %></div>
<label>内容</label>
<div><%= form.text_field :title %></div>
<label>詳細</label>
<div>
<%= collection_select(:template, :name, templates, :id, :name, {:include_blank => true},{class: 'ChoseTemplate', :onchange => "changeTemplate($(this).val())"}) %>
<%= link_to "新規テンプレート追加", new_template_path(diary_id: diary.id) %>
<div><%= render 'work_body', form: form %></div>
</div>
<label>写真</label>
<div><%= form.text_field :picture %></div>
<% if local_assigns[:edit_flag].present? %>
<div><%= form.submit '更新' %></div>
<% else %>
<div><%= form.submit '登録' %></div>
<% end %>
<% end %>
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント