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"
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 ?
Brilliant solution Chris! This is the cleanest lines of code I've ever seen for using stimulus dynamic select!
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
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.
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"
}
}
)
%>
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...", ""]
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.
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/
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.
Hey Chris, I am trying to implement this in the Devise new user registration. I am not sure where to put the def states method. Should I create the Devise registrations controller override and put it there?
I had added the states method to the users controller but that would mean adding the turbolinks partial under the user/ views and not with the registrations/new views.
Thanks for all that you do for the community!
I wasn't able to import @rails/request.js. I got:
Uncaught TypeError: Failed to resolve module specifier "@rails/request.js". Relative references must start with either "/", "./", or "../".
I have another question. If there is another city column that depends on the state, do I repeat the same steps to dynamically show the cities based on the result of the state? Thank you.