Hi,
I’ve run into a problem and I don’t know what’s the best way for solving it.
I was creating a selector component for forms, where the user can select many items. For example, when creating a task, a user has to select which users must complete it.
The selector may have many items, so I wanted to add a search box to filter through the list. To make it more reusable, my idea was to pass as a prop a query function that accepts a search option, and when the user types, the component handles the event, and runs the query function with the search option updating the elements in the selector.
def update(%{id: id, query: query}, socket) do
items = query.(search: "the search query")
socket = socket
|> assigns(items: items)
{:ok, socket}
end
The problem is that I would end up with nested forms:
Form > Selector Field > Form (for filtering)
But browsers don’t allow nested forms and so the inner form gets converted into a div, this means that every time I type to filter, the outer form’s phx-change event gets triggered. I could implement a handle event in the outer component, but that would mean that I would have write the filtering logic each time I use the selector component and trigger a send_update to the selector component to update the elements. This seems like a bit of a mess.
As a solution I was thinking of creating a pseudo-form component using Hooks that captures change events in the inputs, stops the bubbling of the event so that the outer form is not validated and triggers a change event. I’m not fully onboard with this solution either.
With the hook it would look like this:
Form > Selector Field > Div (with Filter hook that captures change events)
Any ideas? Should I frame the problem differently? If you have encountered a similar problem, how did you solve it?