2019-11-15に更新

【Rails】Ajaxでプルダウンを選択したらフォームに自動挿入 1

参考にしたサイト

はじめに

前回、collection_selectによりプルダウンリストを作る方法を整理しましたが、
今回は入力フォーム画面で、プルダウンで事前に作っておいたテンプレートを選択したらそれを自動でフォームに反映されるような機能の実装の仕方をまとめておきます

ポイントとしては、フォームにテンプレートを反映させる際に、フォーム画面から移動したりページ更新したりせずに自動でぽんと文字を出したいのです。
この処理にはAjaxを利用します。
Ajaxについては参考リンク1がざっくり概要を掴むにはいいかも。

実装中に理解が追いつかずかなりテンパりながら実装していましたw
先生に教えてもらい完全に理解したと言えないもののとりあえず意図したように動くものができてます

書き起こすとちょっとボリュームが多そうなので何回かに分けます。

1.実装したいこと

プルダウンリストでTemplateのnameを選択すると、そのTemplateのbodyカラムがページ遷移せずに自動で指定のフォームに入力される、という機能を作りたい。

スクリーンショット 2019-11-14 12.43.29.png
スクリーンショット 2019-11-14 12.43.43.png

2.実装の流れ

(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というファイル作成

3.実装内容

具体的にみていきます。
今回は(1)〜(3)まで。

(1)まずjQueryをRailsで動かせるようにする

参考リンク2を参照ということにして詳細は別の機会に。

(2)ルーティング

ルートファイルにルーティングを記述します。
後ほど、templatesコントローラーにget_bodyメソッドを追加して、そこで選択されたtemplateの内容を取得する処理を記述することになります。
なので先にパスを生成しちゃいます。
この時のHTTPメソッドはgetで良さそうです。

config/locales/routes.rb

get 'templates/get_body'

(3)ajax通信したいフォームをパーシャル化して中身を記述

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というものが出てきますが、後述。

(続く)

4.解説・補足

フォームのビューの全体像が見えづらいので補足。
最終的なコードはこんな感じになります。
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 %>

MEMO

続き書きました
【Rails】Ajaxでプルダウンを選択したらフォームに自動挿入2


Massa

北海道の畑作専業農家・WEBエンジニア修行中の30代。「自然の中で感じたことをカタチにする」をモットーに、農業とITを掛け合わせた仕事に携わりたいなあと思ってます。農業の効率化と発展を目指して。のんびり畑を耕したいw ■Ruby/Rails ■Capoeiraがライフワーク ◇noteでブログ書いてます

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!

ボードとは?

コメント