Closed goblinJoel closed 1 year ago
Hi @goblinJoel
this should work on master now. If you have time and want to test it, that'd be really cool!
<%= live_select form, :field, mode: :tags %>
Now if the field
in the form has value ["B", "C"]
, then B and C will be selected initially.
Alternatively, initial selection can be set explicitly, bypassing whatever is in the form:
<%= live_select form, :field, mode: :tags, value: ["D", "E"] %>
closed with 8c9b2a0a8a3326086eda89a06fc83da3651a3e6e
Messed with this on main some on Friday, but didn't get it all the way working because my use-case is goofy and doesn't use changesets the normal way due to a thru-table situation. But yesterday, I was able to finish that and confirm this works for me on the latest release. I'm using the :value
param approach. Thank you!
Great! Thanks for the feedback!
@maxmarcon looks like the code in https://github.com/maxmarcon/live_select/commit/8c9b2a0a8a3326086eda89a06fc83da3651a3e6e has been changed, and there's no longer way to set an initial value that will then be overridden by user's selection.
Do you have any tips for an idiomatic approach to this problem? This is a typical use case where opening a form you would expect each input to have the exiting value already selected.
E.g. This obviously doesn't work anymore:
<.live_select
label="Nationality"
value={@person.nationality_id}
field={@form[:nationality_search]}
options={[{"None", nil} | Cb.Countries.options_for_select]} />
Yes, the value
is meant to override what is in the form.
The solution is to set the default value in the form :)
@maxmarcon thanks! I know this is out of the scope of this issue now, but do you know by any chance how to set the default value on a form field, without having to add an additional field to the underlying schema of my struct (e.g. nationality_search
)? If not, all good, thank you for your time and help so far!
hey no worries! Happy to help. Well the form is generated from some data, and the data source will contain the value for the field.
so if the data for your form is an Ecto schema with a nationality_search
field:
embedded_schema do
field(:nationality_search, :integer, default: @default_value)
end
(I'm assuming it's an embedded schema). Or you could assign a value to nationality_search
before creating the form for it.
It depends on how you're creating your form.
Thanks!
I'm creating the form
from an ecto schema changeset of a db record. Basic Phoenix LiveView crud form basically:
# person.ex
schema "people" do
belongs_to(:nationality, Cb.Countries.Country, foreign_key: :nationality_id)
end
# person_live_form.ex:
def update(%{person: person} = assigns, socket) do
{:ok, assign(socket, form: to_form(People.change_person(person)))}
end
I can certainly add a virtual field to the schema, in order to keep track of the live_select's
value:
schema "people" do
belongs_to(:nationality, Cb.Countries.Country, foreign_key: :nationality_id)
field(:nationality_search, :integer, virtual: true)
end
# then in liveview:
def update(%{person: person} = assigns, socket) do
changeset = People.change_person(person, %{nationality_search: person.nationality_id})
{:ok, assign(socket, form: to_form(changeset))}
end
But this seems to be a poor choice to me, poluting db schema definition with virtual fields for front-end components.
If there was a way to modify the form struct, it would be nice as it wouldn't require to modify the underlying schema, e.g.:
def update(%{person: person} = assigns, socket) do
form = to_form(People.change_person(person))
form = Map.put(form, :nationality_search, person.nationality_id)
{:ok, assign(socket, form: form)}
end
Though the above obviously doesn't work, as form
is not a map, and I couldn't find any docs in phoenix_html
to modifying the Phoenix.HTML.Form
struct, but thought you might know.
This seems like a common scenario users of the package would need to handle, so if anybody has simple solutions, please share.
I can certainly add a virtual field to the schema, in order to keep track of the live_select's value:
why do you need that? live_select could be used to enter nationality_id
directly. No need for a virtual field.
<.live_select field={@form[:nationality_id]} />
@maxmarcon ah, I misunderstood the docs 😅 I thought live_select
maintains the value in a separate field named "#{field_name}_search"
for it to work. All works now, thank you so much!
You're welcome! No the actual field that will be selected is the one you pass with the field
assign. But live_select does keep an extra field called #{field_name}_text_input
to store the value of the text input box. You can ignore that one.
I would like to be able to restore selections that hadn't been submitted yet, or that encountered an error on submission, like other forms seem to do via their changesets.
For example, I have a tabbed interface where switching tabs switches what info and form you're looking at. This live select is the only one that loses your work if you click away (within the same liveview) without saving.
It may be possible to simply take the current value from the form data using Phoenix.HTML.Form.input_value/2 in the template.