前回の続きで、入力フォーム画面で、プルダウンで事前に作っておいたテンプレートを選択したらそれを自動でフォームに反映されるような機能の実装について。
具体的にJavascript(jQuery)の記述に入ってきますが、この辺の文法のインプットが追いついていないので手順メインの備忘録として。
おさらい。
(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というファイル作成
具体的に見ていきます。
プルダウンリストを作っているcollection_select
に追加します。
HTMLオプションとしてonchangeを使ってJavascript関数を呼び出すように記述します。
views/works/_form.html.erb
<%= collection_select(:template, :name, templates, :id, :name, {:include_blank => true},{class: 'ChoseTemplate', :onchange => "changeTemplate($(this).val())"}) %>
こんな感じですね。確認ですがnew.html.erb
から飛んできてるフォーム部分のパーシャルです。
{class: 'ChoseTemplate', :onchange => "changeTemplate($(this).val())"}
この部分がHTMLオプションになります。
onchange以降が、フォーム(ここではプルダウンリスト)が変更された時に関数(イベント)を呼び出す書き方です。関数名はchangeTemplate
と名前をつけましたが、この中身については次で記述します。
ビューの下にscript
タグで呼び出されるJavascript関数を記述してみます。
views/works/_form.html.erb
<script>
function changeTemplate(val){
var template_id = val;
$.ajax({
url: "/templates/get_body",
type: "GET",
data: {
template_id: template_id
}
})
}
</script>
文法の解説は省略!(すんませんw)
この関数によって色々とごにょごにょされて、変数template_id
にプルダウンで選択されたテンプレートのidが入って吐き出される訳です。
これを次のコントローラーに渡して処理してもらえれば良さそうです。
というか、ajaxの記述部分で渡しているっぽいですね。url: "/templates/get_body,"
のところで、変数を渡すコントローラー名とメソッド名を指定しています。メソッド名は何でも良さそうなのでget_body
とします。
ビューの中にscriptタグでJavascript関数を記述しましたが、
Javascript関数はapp/assets/javascripts
の中にjsファイルを作ってまとめておく方が後から探しやすかったり色々と便利そうです(メンターさんからは好みとも言われましたが)
ファイル名で動作がわかりやすいようにchange_templates.js
という名前ででも作っておきます。
templatesコントローラーに処理を書きます。
処理されるのは先ほどajaxで記述したget_body
メソッドなので、このメソッドを定義して記述します。
controllers/concerns/templates_controller.rb
def get_body
template = Template.find(params[:template_id])
@template_body = template.body
respond_to do |format|
format.js
end
end
うまくいっていれば先ほどプルダウンで選択したテンプレートのidがtemplate_id
で渡されてくるので、
コントローラー側ではまずそのidに該当するテンプレートを探してきて、そのbodyを取得して変数@template_body
に格納します。これが最終的にビューに表示させたい内容ですね。
その後のrespond_to
の中にformat.js
を書くのは「Ajaxリクエストの場合js形式で返す」という意味があるようです。
要するに普段はアクションが実行された時は、コントローラー名と同じフォルダのアクション名.html.erb
というファイルが呼び出されて画面に表示されますが、
今回はAjaxリクエストなので、アクション名.js.erb
というファイルが呼び出される、ということでしょうかね。
では最後にこのjsファイルを作成します。
views/templates
以下に、アクション名と同名のget_body.html.erb
というファイルを作成。その中に、取得したtemplate_bodyを画面に表示させる処理を書きます。
views/templates/get_body.html.erb
$("#template_body").html("<%= j(@template_body) %>")
文法の解説は省略!(すんませんw)
長くなりましたが、これでめでたく「プルダウンでテンプレートを選択し、そのテンプレートのbodyをフォームに表示させる」機能が実装完了となります!
参考リンクとして2つのページのリンクを貼っていますが、これらは僕が実装したかったことと全く同じではないですが、手がかりのない中で実装の流れを把握する上で大いに参考にさせてもらったサイトです。
参考リンク1は僕が学んでいる先生のRailsプログラミング学習サービスで、チュートリアル的に学習することができるようになっています。
今回の実装内容では、リストから選択したら自動でフォームに入力される挙動をとりますが、
プルダウンリストを選択した状態で「挿入」ボタンをクリックしたらそのテンプレートの内容が追加される、というものも実装できるようにしてみたいなーとか考えています。
自分の理解度が低すぎてこんなの公開していいのやら小一時間悩みましたが、
アウトプットは理解度を深めたり再現性を高めたりするために大切な作業だなあとも感じます。
クソ記事に分類されてしまう不安と戦いながら公開ボタンをポチッと
技術ブログをしっかり書いてみて困ったのが、用語を正確に使えないことでした。
調べながらやってはいますが、普段用語の正確な意味を理解せずなんとなくインプットしているんだな…と突きつけられます。
要素、属性、プロパティ、メソッド、アクションの使い方とかかなり怪しい。
JavascriptとjQueryの理解も怪しい。(正直言ってしまうとJavascriptとjQueryの違いすら曖昧なレベルでとてもはずかしい)
このテンプレート機能はしっかりまとめておくと面白そうなので、今後しっかり書き直すことを目標に実力をつけていきます!
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント