lubien
tl;dr: I want to know the most phoenix way of letting users fill a {:array, :string} input via live view form component.
defp deps do
[
{:argon2_elixir, "~> 2.0"},
{:phoenix, "~> 1.6.0"},
{:phoenix_ecto, "~> 4.4"},
{:ecto_sql, "~> 3.6"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 3.0"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:phoenix_live_view, "~> 0.16.0"},
]
end

I’m currently experimenting with the current schema and the relevant prop is :synonyms with {:array, :string} type. The user should be able to write any amount of items there.
defmodule MyApp.MyContext.Tag do
use Ecto.Schema
import Ecto.Changeset
schema "tags" do
field :synonyms, {:array, :string}
timestamps()
end
@doc false
def changeset(tag, attrs) do
tag
|> cast(attrs, [:synonyms])
end
end
I was able to make both edit and create work with some assignments called @synonyms and dynamically rendering inputs called name="tag[synonyms][]" using the code below:
defmodule MyAppWeb.TagLive.FormComponent do
use MyAppWeb, :live_component
alias MyApp.MyContext
@impl true
def update(%{tag: tag} = assigns, socket) do
changeset = MyContext.change_tag(tag)
{:ok,
socket
|> assign(assigns)
|> assign(:changeset, changeset)
|> assign(:synonyms, tag.synonyms)} # <---- relevant
end
@impl true
def handle_event("validate", %{"tag" => tag_params}, socket) do # <---- no changes needed
# tag_params => %{ "synonyms: ["foo", "bar"], rest... }, which is ok :)
changeset =
socket.assigns.tag
|> Jobs.change_tag(tag_params)
|> Map.put(:action, :validate)
{:noreply, assign(socket, :changeset, changeset)}
end
# unrelated ...
end
<.form
let={f}
for={@changeset}
id="tag-form"
phx-target={@myself}
phx-change="validate"
phx-submit="save">
<%= label f, :slug %>
<%= text_input f, :slug %>
<%= error_tag f, :slug %>
<%= label f, :type %>
<%= select f, :type, Ecto.Enum.values(MyApp.MyContext.Tag, :type), prompt: "Choose a value" %>
<%= error_tag f, :type %>
<%= for s <- @synonyms do %> <---------------- here
<%= label f, :slug %>
<input name="tag[synonyms][]" value={s}>
<%= error_tag f, :slug %>
<% end %>
<div>
<%= submit "Save", phx_disable_with: "Saving..." %>
</div>
</.form>
From there I should also make “add more” and “remove” inputs which is fine but I was left wondering if I’ve missed something obvious on the docs or somewhere else that I wasn’t able to find by my searches (as most results seem to deal with embedded schemas instead of an array on the very own schema)
Trending in Questions
Other Trending Topics
Latest Phoenix Threads
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #ai
- #phoenix_html
- #elixirconf-us
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 4- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
sukidhar
did u solve this
if so could u let me know
lubien
It’s been a while so I’m not certain but I think I just went ahead and used the things described on the original topic above
nilskj
Hello! I had the exact same requirement and a lot of troubles but I got it to work now with the new versions of stuff. Idk if idiomatic, I’m new here
So basically I have a similar Ecto schema with an array of strings as features that I want to edit in a form component:
In my form live component I used the same trick as presented earlier here from couple years ago, with the
product[features][]syntax in the name property for the input they get mapped correctly to this array.It was a bit tricky getting the index so I wrapped it into an
Enum.with_indexto make the deletion mutation easier to manage.Here are my working but a bit ugly? click handlers as well:
Is this maybe better to do in an embedded schema? Then I guess I could use
inputs_foror something. Maybe that is the way!kuzyn
Very insightful thread for me
Is the
name="map_name[list_name][]"behavior documented anywhere? It looks very strange to me since you could assume it’s a simple HTML name property without any template magic…