はじめに
インクリメンタルサーチについて書いた記事ではajaxとjsonの組み合わせを使ってビューを変化させていましたが、今回はjsonを使わずRailsの部分テンプレートを更新させる方法でビューを変更する方法について自分なりにまとめていきます。
環境
Ruby 2.5.1
Rails 6.0.2
haml、jQueryを使っていきます。
やりたいこと
form_withのsubmitを使わず、jsのイベント発火(clickやchangeなど)により非同期通信で部分テンプレートを更新させたいです。
jsonを活用して更新する方法もありますが、ここでは部分テンプレートを活用して、js内の記述を簡略化させていきます。
まずはsubmitを使った時の更新
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
%h2
Posts
= form_with model: @post do |f|
= f.text_field :message
= f.submit "Post", id: :submit
.posts
= render partial: "post", collection: @posts
= post.message
まずは比較として、jsを使わず更新してみます。
結果
部分テンプレートのみの更新ではなく、ページ全体を部分テンプレートに変更されてしまいました。
部分テンプレートのみ更新させる
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
$('.posts').html("#{j(render partial: "post", collection: @posts)}");
結果
本題 submitでの送信ではなく、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);
})
})
})
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で記述された部分テンプレートの情報が返されてきているようです。
結果
jsで更新させる部分にajax通信で返されたデータを置換させることで部分テンプレートの更新が実現できました。
活用できそうな場面
マウスオーバーと組み合わせてマウスの位置によってビューを更新させたり、一時的に処理を停止させたりといったjsとの組み合わせで活用できそうです。