どうもこんにちは。
今回も、RailsでのAjax通信について紹介をしようと思います。
Ajax通信とはなんぞやということは前回の記事に記載していますので、ぜひこちらもご参照ください。
今回は、「パーシャルを使用してページの一部を更新する」ということをやっていこうと思います。
早速実装
「パーシャルを使用してページの一部を更新する」という動作を実現するためには以下のようなの順序で行います。
- モーダルでフォームにデータを入力する
- モーダルで登録ボタンを押す
- 登録ボタンを押されたことをトリガーにjavascriptのクリックイベントが動作する
- javascript側で入力された情報を取得する
- javascript側からAjax通信によってcreate_ajaxメソッドが動作する
- create_ajaxメソッドで登録処理が行われる
- 登録処理が終わったらページを更新するためにパーシャルの内容を動的に書き換える
- 更新したパーシャルを表示する
html.erb
今回はモーダルの中の表の中身を動的に変えるコードを示していきます。
id="display_title"
のところにパーシャルを入れ込みます。
<div id="sample_ajax_modal" class="modal fade show" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" style="display: none;" aria-modal="true" data-toggle="modal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">タイトル追加</h4>
<button type="button" class="closeModal close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body p-4">
<div class="row">
<div class="col-md-12">
<div class="form-group row">
<div class="col-sm-2">
<label class="control-label">タイトル</label>
</div>
<div class="col-sm-10">
<%= text_field_tag 'sample_ajax_title', "", class: 'form-control' %>
</div>
</div>
</div>
</div>
<button type="button" id="create_title" class="btn btn-success waves-effect waves-light pull-right ml-2 mt-2">追加</button>
<button type="button" class="closeModal btn btn-light waves-effect waves-light pull-right ml-2 mt-2">キャンセル</button>
<div class="row">
<div id="display_title" >
</div>
</div>
</div>
</div>
</div>
javascript
javascriptのファイル名は、モデル名.jsにしておきましょう。パスの設定も忘れずに。
document.addEventListener('DOMContentLoaded', function() {
// ボタンを押された時のクリックイベント
document.getElementById('create_title').addEventListener('click', function() {
// テキストフィールドからタイトルを取得します
var title = document.getElementById('sample_ajax_title').value;
// Ajax通信を開始します
fetch('/sample_ajax/create_change_ajax', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
// RailsのCSRFトークンを設定します
'X-CSRF-Token': document.querySelector('[name="csrf-token"]').content
},
body: JSON.stringify({ title: title })
})
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
});
});
controller
format.js { render 'sample_ajaxs/display_title' }
というようにレスポンドフォーマットをjs
に指定することで、Viewのディレクトリからsample_ajaxs/display_title.js.erb
ファイルを探します。
ルーティングの設定をGET
としてconfig/routes.rb
に記述をしておきましょう。
def create_change_ajax
sample_ajax = SampleAjax.new(title: params[:title])
respond_to do |format|
if sample_ajax.save
@sample_ajaxs = SampleAjax.all
format.js { render 'sample_ajaxs/display_title' }
format.json { render json: 'save ok' }
else
@sample_ajaxs = SampleAjax.all
format.js { render 'sample_ajaxs/display_title' }
format.json { render json: 'save fail' }
end
end
end
view(display_title.js.erb)
コントローラでこのファイルが呼ばれます。
以下のコードの意味は、「IDがdisplay_title
の要素にdisplay_table_partial
というパーシャルをhtml形式で入れ込みます。」です。
$("#display_title").html("<%= j render 'display_table_partial' %>");
view(_display_table_partial.html.erb)
display_title.js.erb
で呼ばれるパーシャルです。
<table>
<thead>
<tr>
<th>タイトル</th>
<th>作成日時</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= @sample_ajaxs.title %></td>
<td><%= @sample_ajaxs.created_at %></td>
</tr>
</tbody>
</table>
上記の実装によってボタンがクリックされた時に登録処理が実行され、ページを更新しなくても表の内容を変えることができるようになります。
まとめ
今回もAjax通信についてまとめてみました。
前回と同様にJavascriptを使用したことに加えて、js.erb
ファイルを使用することで、画面表示を非同期で行うことができるようになります。
Javascriptファイルからもhtmlを呼び出すことはできますが、コントローラからJavascriptへレコードの入った変数を渡すことはできないので、titleの入った配列、作成日時の入った配列を作らなきゃいけません。さらにJavascriptで配列を展開してhtmlに落とし込む。これが非常にめんどくさい。
↓Javascriptファイルからもhtmlを呼び出す時のコントローラのコード↓
respond_to do |format|
if sample_ajax.save
@sample_ajaxs = SampleAjax.all
sample_ajaxs_array = @sample_ajaxs.pluck(:title, :created_at)
format.json { render json: sample_ajaxs_array }
else
@sample_ajaxs = SampleAjax.all
sample_ajaxs_array = @sample_ajaxs.pluck(:title, :created_at)
format.json { render json: sample_ajaxs_array }
end
end
なので、こういう場合は今回のようにjs.erbファイルを有効的に活用していくことをおすすめします。
以上