4
2

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 3 years have passed since last update.

Rails+jQuery イベントの発火により部分テンプレートを更新させる方法

Posted at

はじめに

インクリメンタルサーチについて書いた記事ではajaxとjsonの組み合わせを使ってビューを変化させていましたが、今回はjsonを使わずRailsの部分テンプレートを更新させる方法でビューを変更する方法について自分なりにまとめていきます。

環境

Ruby 2.5.1
Rails 6.0.2
haml、jQueryを使っていきます。

やりたいこと

form_withのsubmitを使わず、jsのイベント発火(clickやchangeなど)により非同期通信で部分テンプレートを更新させたいです。
jsonを活用して更新する方法もありますが、ここでは部分テンプレートを活用して、js内の記述を簡略化させていきます。

まずはsubmitを使った時の更新

post_controller.rb
class PostController < ApplicationController
  def index
    @posts = Post.all
  end

  def create
    @post = Post.create(message: params[:message])
    @posts = Post.all
    render partial: "post", collection: @posts
  end
end
index.html.haml
%h2
  Posts

= form_with model: @post do |f|
  = f.text_field :message
  = f.submit "Post", id: :submit

.posts
  = render partial: "post", collection: @posts
_post.html.haml
= post.message

pict1.png

まずは比較として、jsを使わず更新してみます。

結果

pict2.png
部分テンプレートのみの更新ではなく、ページ全体を部分テンプレートに変更されてしまいました。

部分テンプレートのみ更新させる

post_controller_rb
class PostController < ApplicationController
  def index
    @posts = Post.all
  end

  def create
    @post = Post.create(message: params[:message])
    @posts = Post.all
    #  partial: "post", collection: @posts  <- 削除
  end
end
create.js.haml(新規作成)
$('.posts').html("#{j(render partial: "post", collection: @posts)}");

結果

pict3.png
pict4.png
部分テンプレートのみ更新させることができました。

本題 submitでの送信ではなく、jsのイベントで部分テンプレートの更新を行う

post.js
$(function() {
  $('#submit').on('click', function(event) {
    event.preventDefault();
    var input = $('#message').val();
    console.log(input)
    $.ajax({
      type: "POST",
      url: "/post",
      data: {message: input}
    })
    .done(function(response) {
      $('.posts').html(response);
    })
  })
})
post_controller.rb
class PostController < ApplicationController
  def index
    @posts = Post.all
  end

  def create
    @post = Post.create(message: params[:message])
    @posts = Post.all
    render partial: "post", collection: @posts  <- 復元
  end
end

サーバーから返されるデータの形式を指定しないことで、標準的なHTMLで記述された部分テンプレートの情報が返されてきているようです。

結果

pict5.png
jsで更新させる部分にajax通信で返されたデータを置換させることで部分テンプレートの更新が実現できました。

活用できそうな場面

マウスオーバーと組み合わせてマウスの位置によってビューを更新させたり、一時的に処理を停止させたりといったjsとの組み合わせで活用できそうです。

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?