Hi together,
i want to build a filter UI where the user can select some items with a checkbox and then the results get filtered based on the selected checkboxes. For example, a use case where we have some categories in a DB and give the user a checkbox for each category to filter for. So far so good and i had no problem implementing that.
But i want to have another checkbox which lets the user select all the categories at once or deselect every category at once. Additionally, the behaviour should be, that when a user deselects one category while the select all box is checked it should become unchecked and vice versa, when the user selects every category by hand, the select all checkbox should be checked as well.
My first step was to define a schema for the form which looks something like this:
defp parse_filter(default_filter, attrs \\ %{}) do
fields = %{
all: :boolean,
selected: {:array, :integer}
}
{default_filter, fields}
|> Ecto.Changeset.cast(attrs, Map.keys(fields))
|> Map.put(:action, :validate)
end
Is store the filter params in the URL with:
def handle_event("change-categories", %{"categories" => params}, socket) do
form = parse_filter(socket.assigns.filter, params)
filter = apply_filter(form)
{:noreply, socket |> push_patch(to: ~p"/?#{filter}")}
end
def handle_params(params, _, socket) do
form = parse_filter(socket.assigns.filter, params)
filter = apply_filter(form)
{:noreply,
socket
|> assign(
filter: filter,
filtered_categories: filter_categories(socket.assigns.categories, filter)
)
|> assign_form(form)}
end
I’ve tried with some Ecto.Changeset.get_change/put_change
in the validation with parse_filter/2
but all
and selected
would overwrite each other.
I’ve prepared a gist with my idea, but i can’t figure out if i am on the right track with my plan. Does anybody have a solution for this problem or can point me in the right direction?