13

I've been testing Hotwire, using the demo that was put up by DHH. I have a default rails 6 setup & I know that it re-creates the javascript folder structure from the rails 5 < asset pipeline. The issue I am having is the form will not reset the text field after submission - despite setting up the stimulus controller for using this particular action. How can I reset the form for hotwire after the form is submitted by the user? My code is below

new.html.erb

<%= turbo_frame_tag 'new_conversation_comment', target: '_top' do %>
<%= form_with(model: [@conversation, @conversation_comment],
              data: { controller: "reset_form", action: 'turbo:submit-end->reset_form#reset' }, html: {class: 'form-inline'}) do |form| %>
    <%= form.submit 'Post', class: 'btn btn-primary mb-2', style: 'float: right;', 'data-reset_form-target': 'button' %>
  
    <div style="overflow: hidden; padding-right: .5em;">
      <%= form.text_field :content, class: 'form-control' %>
    </div>
<% end %>

_conversation_comment.html.erb

 <div class="p-1">
    <%= conversation_comment.content %>
    </div>

show.html.erb

  <div class="p-2">
     <%= turbo_stream_from @conversation %>
     <%= turbo_frame_tag 'conversation' do %>
         ....
     <% end %>
     <div class="conversation-comments-container" id="conversation_comments">
          <%= render @conversation.conversation_comments %>
     </div>
       <hr>
<%= turbo_frame_tag 'new_conversation_comment', src: new_conversation_conversation_comment_path(@conversation), target: :_top %>
</div>

assets/javascripts/controllers/reset_form_controller.js

import { Controller } from "stimulus"

export default class extends Controller {
    reset() {
        this.element.reset()
    }
}

Disclaimer: I'm using Webpack 4.0

valcod3r
  • 321
  • 4
  • 14

4 Answers4

19

Depending on setup underscore between controller name can be an issue. Replacing it with dash worked in my case.

turbo:submit-end->reset-form#reset
Canbey Bilgili
  • 754
  • 5
  • 12
  • I'll report back with my results, shortly. – valcod3r Dec 31 '20 at 17:29
  • 1
    I updated the gem, because I guess it had an autoload issue -- yet still, stimulus is not connecting with the form to reset it. – valcod3r Jan 01 '21 at 00:11
  • Can you upload a gist with your chat components, please? – valcod3r Jan 01 '21 at 00:11
  • 2
    @valcod3r I've created a gist; https://gist.github.com/cbilgili/c78f8e89515cd807f817f35d721570a6 Does your stimulus controller connect? You can check this by adding console.log to "connect" method as in gist. – Canbey Bilgili Jan 01 '21 at 19:20
  • 1
    Yes, the naming convention was incorrect -- this is the correct solution. – valcod3r Jan 30 '21 at 18:59
  • @valcod3r You can accept it as the answer if you think it is the correct solution! – VegaStudios Jun 19 '21 at 05:07
  • Can confirm renaming from: reset_form_controller --> reset-form_controller worked for me also. Strange thing. – Skull0inc Sep 22 '21 at 04:33
  • 4
    Worth noting that you'd need to replace it in both places, e.g.: `data: { controller: "reset-form", action: "turbo:submit-end->reset-form#reset" }` And as per the gist above. There was no need for me to rename the controller's file though as per @Skull0inc comment. – tomdonarski Jan 19 '22 at 09:11
  • Just want to say, this is absolutely the answer! There are a handful of discrepancies between the intro video vs the documentation. Here it shows the naming conventions to use https://stimulus.hotwired.dev/reference/controllers – Matt Barry Jan 27 '22 at 21:20
  • @tomdonarski had the same issue, changing both underscores in reset_form like you mentioned, helped. Strange that the underscore is also an issue with Cert Bot and changing it same helps in some cases. – doer123456789 May 31 '22 at 08:39
0

Disclaimer: I'm using Webpack 4.0

I ran into the same thing, also using Webpack.

The solution for me was:

  1. Change the underscores to dashes, like Canbey said.

  2. Move the stimulus controller from app/assets/javascripts/controllers/ to app/javascripts/controllers/ (somewhat per the stimulus docs so that webpack imported it properly — my application.js file was importing controllers from that directory rather than app/assets/javascripts.

Cara McCormack
  • 388
  • 1
  • 7
  • 21
0

A half SJR, half Hotwire approach would be this:

Working example here: https://rails-react-bootstrap.herokuapp.com/rooms

new.html.erb

<%= turbo_frame_tag 'new_note' do %>
  <%= form_with model: [@room, @note] do |form| %>
    <!-- Allow body validation error without message -->
    <div class="form-group">
      <%= form.rich_text_area :body, class: 'form-control comments', id: 'bodyText' %>
    </div><!-- .form-group -->
    <div class="form-group d-flex justify-content-center">
      <%= form.submit 'Add Note', class: 'btn btn-lg btn-tayberry btn-block' %>
    </div><!-- .form-group -->
  <% end %>
<% end %>

create_js.erb

// clear note textarea after submit
var input = document.getElementById("bodyText");
input.value = '';

notes_controller

  def create
    @note = @room.notes.create!(note_params)
    # @note.user = current_user
    respond_to do |format|
      if @note.save
        format.turbo_stream
        format.html { redirect_to @room }
        format.js
      else
        format.html { render action: 'new' }
      end
    end
  end
-2

If you still need an answer, here is how you can achieve what you need:

In your controller respond to requests like that:

format.html { redirect_to conversations_url }

Note: redirect to the page where new_conversation_comment frame is defined (i.e same page from where you are submitting form). Redirect will happen, but Hotwire will substitute form for you with a new one and append comment where you specified. It is a bit magic.

I suggest you to check this video:

https://gorails.com/episodes/hotwire-rails?autoplay=1

yerassyl
  • 2,958
  • 6
  • 42
  • 68