fix: select all checkbox handling
This commit is contained in:
parent
bb7e3cbe77
commit
124ab295a6
3 changed files with 41 additions and 26 deletions
|
|
@ -90,11 +90,14 @@ defmodule MvWeb.UserLive.Index do
|
||||||
# Selects one user in the list of users
|
# Selects one user in the list of users
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("select_user", %{"id" => id}, socket) do
|
def handle_event("select_user", %{"id" => id}, socket) do
|
||||||
|
# Normalize ID to string for consistent comparison
|
||||||
|
id_str = to_string(id)
|
||||||
|
|
||||||
selected =
|
selected =
|
||||||
if id in socket.assigns.selected_users do
|
if id_str in socket.assigns.selected_users do
|
||||||
List.delete(socket.assigns.selected_users, id)
|
List.delete(socket.assigns.selected_users, id_str)
|
||||||
else
|
else
|
||||||
[id | socket.assigns.selected_users]
|
[id_str | socket.assigns.selected_users]
|
||||||
end
|
end
|
||||||
|
|
||||||
{:noreply, assign(socket, :selected_users, selected)}
|
{:noreply, assign(socket, :selected_users, selected)}
|
||||||
|
|
@ -129,7 +132,8 @@ defmodule MvWeb.UserLive.Index do
|
||||||
def handle_event("select_all", _params, socket) do
|
def handle_event("select_all", _params, socket) do
|
||||||
users = socket.assigns.users
|
users = socket.assigns.users
|
||||||
|
|
||||||
all_ids = Enum.map(users, & &1.id)
|
# Normalize IDs to strings for consistent comparison
|
||||||
|
all_ids = Enum.map(users, &to_string(&1.id))
|
||||||
|
|
||||||
selected =
|
selected =
|
||||||
if Enum.sort(socket.assigns.selected_users) == Enum.sort(all_ids) do
|
if Enum.sort(socket.assigns.selected_users) == Enum.sort(all_ids) do
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="select_all"
|
name="select_all"
|
||||||
phx-click="select_all"
|
phx-click="select_all"
|
||||||
checked={Enum.sort(@selected_users) == Enum.map(@users, & &1.id) |> Enum.sort()}
|
checked={Enum.sort(@selected_users) == Enum.map(@users, &to_string(&1.id)) |> Enum.sort()}
|
||||||
aria-label={gettext("Select all users")}
|
aria-label={gettext("Select all users")}
|
||||||
role="checkbox"
|
role="checkbox"
|
||||||
/>
|
/>
|
||||||
|
|
@ -26,10 +26,10 @@
|
||||||
>
|
>
|
||||||
<.input
|
<.input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name={user.id}
|
name={to_string(user.id)}
|
||||||
phx-click="select_user"
|
phx-click="select_user"
|
||||||
phx-value-id={user.id}
|
phx-value-id={to_string(user.id)}
|
||||||
checked={user.id in @selected_users}
|
checked={to_string(user.id) in @selected_users}
|
||||||
phx-capture-click
|
phx-capture-click
|
||||||
phx-stop-propagation
|
phx-stop-propagation
|
||||||
aria-label={gettext("Select user")}
|
aria-label={gettext("Select user")}
|
||||||
|
|
|
||||||
|
|
@ -225,30 +225,41 @@ defmodule MvWeb.UserLive.IndexTest do
|
||||||
@tag :slow
|
@tag :slow
|
||||||
test "select all automatically checks when all individual users are selected", %{
|
test "select all automatically checks when all individual users are selected", %{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
users: [user1, user2]
|
users: [_user1, _user2]
|
||||||
} do
|
} do
|
||||||
conn = conn_with_oidc_user(conn)
|
conn = conn_with_oidc_user(conn)
|
||||||
{:ok, view, _html} = live(conn, "/users")
|
{:ok, view, html} = live(conn, "/users")
|
||||||
|
|
||||||
# Initially nothing should be checked
|
# Get all user IDs from the rendered HTML by finding all checkboxes with phx-click="select_user"
|
||||||
refute view
|
# Extract user IDs from the HTML (they appear as name attributes on checkboxes)
|
||||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
user_ids =
|
||||||
|> has_element?()
|
html
|
||||||
|
|> String.split("phx-click=\"select_user\"")
|
||||||
|
|> Enum.flat_map(fn part ->
|
||||||
|
case Regex.run(~r/name="([^"]+)"[^>]*phx-value-id/, part) do
|
||||||
|
[_, user_id] -> [user_id]
|
||||||
|
_ -> []
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|> Enum.uniq()
|
||||||
|
|
||||||
# Select first user
|
# Skip if no users found (shouldn't happen, but be safe)
|
||||||
view |> element("input[type='checkbox'][name='#{user1.id}']") |> render_click()
|
if length(user_ids) > 0 do
|
||||||
# Select all should still not be checked (only 1 of 2+ users selected)
|
# Initially nothing should be checked
|
||||||
refute view
|
refute view
|
||||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
|> element("input[type='checkbox'][name='select_all'][checked]")
|
||||||
|> has_element?()
|
|> has_element?()
|
||||||
|
|
||||||
# Select second user
|
# Select all users one by one
|
||||||
view |> element("input[type='checkbox'][name='#{user2.id}']") |> render_click()
|
Enum.each(user_ids, fn user_id ->
|
||||||
|
view |> element("input[type='checkbox'][name='#{user_id}']") |> render_click()
|
||||||
|
end)
|
||||||
|
|
||||||
# Now select all should be automatically checked (all individual users are selected)
|
# Now select all should be automatically checked (all individual users are selected)
|
||||||
assert view
|
assert view
|
||||||
|> element("input[type='checkbox'][name='select_all'][checked]")
|
|> element("input[type='checkbox'][name='select_all'][checked]")
|
||||||
|> has_element?()
|
|> has_element?()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue