All threads / Dynamic Select Fields in Rails with Hotwire Discussion
Ask A Question

Notifications

You’re not receiving notifications from this thread.

Dynamic Select Fields in Rails with Hotwire Discussion

If I'm reading this error correctly does this mean the url value and param value are not being pulled from the data fields?

GET "/undefined?undefined=Head&target=muscle-table"

Reply

Lets say i have a form where a user can select something.

Is it also possible to use this method to render than depending on the selection different templates of a child form ?

Reply

Brilliant solution Chris! This is the cleanest lines of code I've ever seen for using stimulus dynamic select!

Reply

I love how you make it so generic in the end! 👌

Reply

Great explanation, Chris!

I'd like to know the difference between use Request.js#get and the native #fetch.
I was trying with #fetch, the request and turbo_stream was triggered but the state>select was not filled with the data.

Does anyone know why is that?

A little bit late but hope this will help others. In my case, I can't make the Request.js#get work, so I use fetch instead. The controller response as turbo-stream format so you must tell the client to render it - Turbo instance is automatically assigned to window.Turbo upon import import "@hotwired/turbo-rails"

    fetch(url, {
      method: 'GET',
      mode: 'cors',
      cache: 'no-cache',
      credentials: 'same-origin',
      headers: {
        'Accept': "text/vnd.turbo-stream.html",
        'X-CSRF-Token': csrfToken
      },
    })
    .then(response => response.text())
    .then(html => Turbo.renderStreamMessage(html)) // this will render the turbo-stream as HTML
Reply

Posted this in the GoRails discord, but thought it might be more of an evergreen question, so also sharing it here:

I'm implementing dynamic select using Hotwire just like in this episode. In Chris's example from this episode, he makes a new action named states in his AddressesController. For my similar action I had to bypass my Pundit policy to get it to work. The simplest thing was to just skip Pundit for that action like this after_action :verify_authorized, except: [:categories].

So, here's my question: Is this opening up any sort of security hole that I'm not thinking about? Is there a better way to do this? My Category model and the model for the form object where I'm using this dynamic select already have Pundit policies, so it doesn't seem like a problem, but just wanted to bounce it off someone to see if there is another way I should do this. Thanks!

Update: the consensus from GoRails Discord seems to be just create a Pundit policy for any custom action like this one.

Reply

Is there a way to include blank when doing this? I have tried several variations (not related to country/state but team/user) but haven't had any success.

<%= turbo_stream.update @target do %>
  <%= options_for_select(@team_users.map { |k,v| ["#{k.first_name} #{k.last_name}", v = k.id] }, include_blank: true) %>
<% end %>

Were you able to find a solution here? I am having the same problem with include_blank and any of the other values initially set before the turbo_stream updates the id.

<%= f.select(
              :food_id,
              options_from_collection_for_select(
                @foods,
                :id,
                :name
              ),
              { 
                include_blank: true, 
                required: false
              },
              {
                class: "form-input-group-text-field",
                multiple: false,
                data: {
                  filteredforms_target: "foodSelect"
                }
              }
            )
          %>
Reply

well figured it out you can do this just incase someone is having the same issue. Its just inserting a blank value at 0.

<%= turbo_stream.update @target do %>
  <%= options_for_select @team_users.map { |k,v| ["#{k.first_name} #{k.last_name}", v = k.id] }.insert(0, "") %>
<% end %>

step further if you want to show some text but have no value for that option you can also do the following:

<%= turbo_stream.update @target do %>
  <%= options_for_select @team_users.map { |k,v| ["#{k.first_name} #{k.last_name}", v = k.id] }.insert(0, ["Please select...", ""]) %>
<% end %>

Basically adding this at the end .insert[0, ["please select...", ""]

Haha cheers... after reading on :)

Found that this is harder if using options_from_collection_for_select so gave up and ended up plucking my main value (in this case name) from the collection and using options_for_select then using a lookup on the name when sending the data back to the controller on submission.

Reply

Hey Crhis! I worked out an alternative solution for dynamic forms using Hotwire and I would love your feedback. Check out my blog post here: https://codestoa.com/2022/02/08/dynamic-forms-with-hotwire-turbo/

Sorry for the typo. I can't edit it. *Chris

Reply

Hey Chris, thanks for the tutorial! One thing I'd like to know, is there a way to do this and display the full name of the country rather than the country code? Would I need to use a hidden field and submit the full name independently? Thanks, Owen.

Reply
Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 64,380+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more. Icons by Icons8

    © 2022 GoRails, LLC. All rights reserved.