5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Rails】Ajax通信でできること2(ページの一部だけを更新する編)

Last updated at Posted at 2023-11-06

どうもこんにちは。

今回も、RailsでのAjax通信について紹介をしようと思います。

Ajax通信とはなんぞやということは前回の記事に記載していますので、ぜひこちらもご参照ください。

今回は、「パーシャルを使用してページの一部を更新する」ということをやっていこうと思います。

早速実装

「パーシャルを使用してページの一部を更新する」という動作を実現するためには以下のようなの順序で行います。

  1. モーダルでフォームにデータを入力する
  2. モーダルで登録ボタンを押す
  3. 登録ボタンを押されたことをトリガーにjavascriptのクリックイベントが動作する
  4. javascript側で入力された情報を取得する
  5. javascript側からAjax通信によってcreate_ajaxメソッドが動作する
  6. create_ajaxメソッドで登録処理が行われる
  7. 登録処理が終わったらページを更新するためにパーシャルの内容を動的に書き換える
  8. 更新したパーシャルを表示する

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ファイルを有効的に活用していくことをおすすめします。

以上

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?