Yeah Im an idiot.
This works for me, so, IDK, good luck.
defmodule PhxcomponentsWeb.Index2Live do
use PhxcomponentsWeb, :live_view
defmodule Component do
use PhxcomponentsWeb, :live_component
def update(assigns, socket) do
socket =
socket
|> assign(:all_columns, assigns.all_columns)
|> assign(:columns, assigns.all_columns)
{:ok, socket}
end
def handle_event("toggle-one", params, socket) do
# bit jank but whatever
columns =
case params do
%{"column" => col_key, "value" => "on"} ->
[{col_key, String.to_existing_atom(col_key)} | socket.assigns.columns]
|> Enum.uniq()
%{"column" => col_key} ->
Enum.reject(socket.assigns.columns, fn {_name, key} ->
key == String.to_existing_atom(col_key)
end)
end
socket = assign(socket, :columns, columns)
{:noreply, socket}
end
def handle_event("toggle-all", _params, socket) do
Enum.reduce(
["colors", "dogs", "cats"],
{:noreply, socket},
fn key_string, {:noreply, socket} ->
handle_event("toggle-one", %{"column" => key_string, "value" => "on"}, socket)
end
)
end
defp col_checked?(target_key, columns) do
Enum.any?(columns, fn {_col_name, col_key} -> col_key == target_key end)
end
def render(assigns) do
~H"""
<div>
<%= for {name, key} <- @all_columns do %>
<input
type="checkbox"
id={"id-#{key}"}
name={"col-#{key}"}
phx-click="toggle-one"
phx-value-column={key}
phx-target={@myself}
checked={col_checked?(key, @columns)}
/>
<label for={"id-#{key}"}><%= name %></label>
<% end %>
<button class="ml-8 border" type="button" phx-click={JS.push("toggle-all", target: @myself)}>
check all
</button>
<div class="flex gap-4">
<%= for {name, _key} <- @columns do %>
<span><%= name %></span>
<% end %>
</div>
</div>
"""
end
end
def mount(_params, _session, socket) do
socket =
assign(
socket,
:all_columns,
[{"colors", :colors}, {"dogs", :dogs}, {"cats", :cats}]
)
{:ok, socket}
end
def render(assigns) do
~H"""
<div>
<.live_component module={Component} all_columns={@all_columns} id={:comp} />
</div>
"""
end
end