LoginSignup
blue-night-blue
@blue-night-blue

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

RailsのTurboStreamsにてformむき出しでcreate後、formが空にならない

解決したいこと

タイトルのとおりです。createアクションが成功した後に、直前に入力した文字が入ったままなのを、空にしたいです。実際の挙動をご覧くださった方が分かりやすいと思いますので下記に提示します。現状、追記2のとおり力技で空にしてます。
https://bnb-turbotest-b851620cb1f4.herokuapp.com/

経緯としては、TurboStreamsの理解を深めようと、Hotrailsのチュートリアル( https://www.hotrails.dev/turbo-rails/turbo-frames-and-turbo-streams )等からエッセンス的なものを作り、いごいご動かしてました。その際に件名のとおり、壁にぶち当たりました。TurboStreamsのサンプルはかなり見ましたが、新規投稿も編集も、それぞれのボタンを押してからフォームが出てくるものしかなかったので万事休すとなりました。

どなたかアドバイスいただけると大変ありがたく存じます。何卒お願いいたします。

コード

以下、関係ない箇所は省略しています。
(念のためGitHub:https://github.com/blue-night-blue/turbotest)

quotes_controller.rb
class QuotesController < ApplicationController
  before_action :set_quote, only: %i[ edit update destroy ]

  def index
    @quotes = Quote.ordered
    @quote = Quote.new
  end

  def create
    @quote = Quote.new(quote_params)
    name = @quote.name
  
    if @quote.save
      respond_to do |format|
        format.html { redirect_to quotes_path, notice: "Quote was successfully created." }
        format.turbo_stream { flash.now.notice = "#{name}を投稿しました" }
      end
    else
      render :new, status: :unprocessable_entity
    end
  end
  
  def update
    name = @quote.name
    if @quote.update(quote_params) && @quote.saved_change_to_attribute?(:name)
      respond_to do |format|
        if @quote.update(quote_params)
          format.html { redirect_to quotes_path, notice: "Quote was successfully updated." }
          format.turbo_stream { flash.now[:notice] = "#{name}を修正しました" }
        else
          format.html { render :edit, status: :unprocessable_entity }
        end
      end
    end
  end

  
  
  
  private
    def set_quote
      @quote = Quote.find(params[:id])
    end

    def quote_params
      params.require(:quote).permit(:name)
    end
end
index.html.erb
<h1>Quotes</h1>
  
<div class="container_new">
  <%= turbo_frame_tag "new_quote" do %>
      <%= render "form", quote: @quote %>
  <% end %>
</div>

<%= turbo_frame_tag "quotes" do %>
  <%= render @quotes %>
<% end %>
_form.html.erb
<% if quote.errors.any? %>
  <% quote.errors.each do |error| %>
    <div class="container_error">
      <%= error.full_message %>
    </div>
  <% end %>
<% end %>

<div>
  <%= form_with(model: quote) do |form| %>
    <%= form.text_field :name %>
    <%= form.submit %>
  <% end %>
</div>
create.turbo_stream.erb
<%= turbo_stream.prepend "quotes", @quote %>
<%= turbo_stream.update "flash", partial: "flash" %>
_quote.html.erb
<%= turbo_frame_tag quote do %>
  <div class="container_flex">
    <%= render "form", quote: quote %>
    <div>
      <%= button_to "Delete",quote_path(quote),method: :delete %>
    </div> 
  </div> 
<% end %>

自分で試したこと

createアクションで@quote = Quote.newを足してみましたがContent missing のエラーが出ます。

create.turbo_stream.erb
format.turbo_stream { 
    flash.now.notice = "#{name}を投稿しました" ,
    @quote = Quote.new
}

あと、formをむき出しにしない場合はうまく行きます(うまく行くというかnew_quoteのリンクをポチっと押すと空白のフォームが出てくる仕様です)

追記1

暫定処置としてJavaScriptを追加して、focus時に空白になるようにはしました。が、根本解決ではないです。(こんな挙動にはしたくない)

追記2

力技というかバッドノウハウですが、下記コードで無理くり空にしました。

toBlank.js
const formArea = document.querySelector('.container_new form');
const inputArea = document.querySelector(".container_new [type='text']");

formArea.addEventListener('submit',()=>{
    setTimeout( ()=> {
        location.reload();
    }, 1000);
});

window.onload = ()=> {
    inputArea.focus();
};
0

No Answers yet.

Your answer might help someone💌