chore(badges): add 'Start Here' helper button to focus fulltext search input

This commit is contained in:
Scott Idem
2026-04-08 15:14:18 -04:00
parent d5b2b557f3
commit 3659fef17c

View File

@@ -12,7 +12,10 @@ import {
LoaderCircle,
QrCode,
RemoveFormatting,
Search
Search,
StepForward
} from '@lucide/svelte';
import { ae_loc, ae_api } from '$lib/stores/ae_stores';
import { events_sess } from '$lib/stores/ae_events_stores';
@@ -92,82 +95,115 @@ function handle_qr_scan_result(event: {
handle_search_trigger();
})}
autocomplete="off"
class="search_form bg-primary-50-950 border-primary-100-900 flex w-full max-w-7xl flex-col sm:flex-row flex-wrap items-center justify-center gap-2 rounded-lg px-2 py-2 shadow-md md:px-12">
class="search_form bg-primary-50-950 border-primary-100-900 flex w-full max-w-4xl flex-col sm:flex-row flex-wrap items-center justify-center gap-2 rounded-lg px-2 py-2 shadow-lg md:px-12 outline">
<div
class="flex grow flex-col md:flex-row flex-wrap items-center justify-center gap-2">
class="flex grow flex-col xl:flex-row flex-wrap items-center justify-center gap-2">
{#if ($ae_loc.trusted_access && $ae_loc.edit_mode) || $ae_loc.manager_access}
<span class="flex flex-row flex-wrap items-center justify-center gap-1">
<select
bind:value={badges_loc.current.search_badge_type_code}
onchange={handle_search_trigger}
class="select select-sm max-w-fit px-1 text-xs">
<option value="">-- All Badge Types --</option>
{#each badge_type_code_li as badge_type_code (badge_type_code.code)}
<option value={badge_type_code.code}
>{badge_type_code.name}</option>
{/each}
</select>
<div class="flex flex-row flex-wrap items-center justify-center gap-1">
<span class="flex flex-row flex-wrap items-center justify-center gap-1">
<select
bind:value={badges_loc.current.search_badge_type_code}
onchange={handle_search_trigger}
class="select select-sm max-w-fit px-1 text-xs">
<option value="">-- All Badge Types --</option>
{#each badge_type_code_li as badge_type_code (badge_type_code.code)}
<option value={badge_type_code.code}
>{badge_type_code.name}</option>
{/each}
</select>
<select
bind:value={badges_loc.current.qry_printed_status}
onchange={handle_search_trigger}
class="select select-sm max-w-fit px-1 text-xs">
<option value="all">-- All Print Status --</option>
<option value="printed">Printed</option>
<option value="not_printed">Not Printed</option>
</select>
<select
bind:value={badges_loc.current.qry_printed_status}
onchange={handle_search_trigger}
class="select select-sm max-w-fit px-1 text-xs">
<option value="all">-- All Print Status --</option>
<option value="printed">Printed</option>
<option value="not_printed">Not Printed</option>
</select>
<select
bind:value={badges_loc.current.qry_sort_order}
onchange={handle_search_trigger}
class="select select-sm max-w-fit px-1 text-xs">
<option value="">-- Default Sort --</option>
<option value="name_asc">Name ASC</option>
<option value="name_desc">Name DESC</option>
<option value="updated_desc">Updated DESC</option>
<option value="updated_asc">Updated ASC</option>
<option value="print_count_desc"
>Print Count DESC</option>
<option value="print_first_desc"
>First Printed DESC</option>
<option value="print_last_desc"
>Last Printed DESC</option>
<option value="badge_type_asc">Badge Type ASC</option>
<option value="affiliations_asc"
>Affiliations ASC</option>
</select>
</span>
<select
bind:value={badges_loc.current.qry_sort_order}
onchange={handle_search_trigger}
class="select select-sm max-w-fit px-1 text-xs">
<option value="">-- Default Sort --</option>
<option value="name_asc">Name ASC</option>
<option value="name_desc">Name DESC</option>
<option value="updated_desc">Updated DESC</option>
<option value="updated_asc">Updated ASC</option>
<option value="print_count_desc"
>Print Count DESC</option>
<option value="print_first_desc"
>First Printed DESC</option>
<option value="print_last_desc"
>Last Printed DESC</option>
<option value="badge_type_asc">Badge Type ASC</option>
<option value="affiliations_asc"
>Affiliations ASC</option>
</select>
</span>
<input
type="search"
placeholder="Affiliations"
bind:value={badges_loc.current.qry_affiliations}
onkeyup={(e) => {
if (
e.key === 'Enter' ||
(badges_loc.current.qry_affiliations?.length ??
0) >= 3
) {
handle_search_trigger();
}
}}
class="input input-sm max-w-fit px-1 text-xs" />
</div>
{/if}
<div class="flex grow flex-row items-center justify-center gap-2">
<!-- An extra "start" button that will just set the focus to the input form field -->
<button
type="button"
onclick={() => document.getElementById('badge_fulltext_search_qry_str')?.focus()}
aria-label="Start here focus search field"
data-testid="badge-start-btn"
class="btn btn-sm preset-filled-secondary-300-700"
class:opacity-30={!!badges_loc.current.fulltext_search_qry_str}
>
<StepForward size="1em" class="mx-1" />
Start Here
</button>
<!-- svelte-ignore a11y_autofocus -->
<input
type="search"
placeholder="Affiliations"
bind:value={badges_loc.current.qry_affiliations}
autofocus
placeholder="name, email, company, organization, etc."
id="badge_fulltext_search_qry_str"
bind:value={badges_loc.current.fulltext_search_qry_str}
autocomplete="off"
data-lpignore="true"
class="
input grow
min-w-96 md:max-w-1/2
transition-all
font-mono text-lg
bg-red-50-900 dark:bg-red-50-950
focus:bg-white
focus:text-black
border border-l-2 border-b-2
border-l-primary-500 border-b-primary-500
border-r-primary-300 border-t-primary-300
dark:border-l-primary-800 dark:border-b-primary-800
"
onkeyup={(e) => {
if (
e.key === 'Enter' ||
(badges_loc.current.qry_affiliations?.length ??
0) >= 3
) {
if (e.key === 'Enter') {
handle_search_trigger();
}
}}
class="input input-sm max-w-fit px-1 text-xs" />
{/if}
title="Search by name, email, etc. Press Enter." />
<input
type="search"
placeholder="name, email, company, organization, etc."
id="badge_fulltext_search_qry_str"
bind:value={badges_loc.current.fulltext_search_qry_str}
autocomplete="off"
data-lpignore="true"
class="input grow font-mono text-lg transition-all focus:bg-white min-w-96 md:max-w-1/2 border-l-2 border-b-2 border-l-primary-500 border-b-primary-500"
onkeyup={(e) => {
if (e.key === 'Enter') {
handle_search_trigger();
}
}}
title="Search by name, email, etc. Press Enter." />
</div>
</div>
{#if (badges_loc.current.fulltext_search_qry_str ?? '').trim().length < effective_min_chars}
@@ -202,6 +238,8 @@ function handle_qr_scan_result(event: {
badges_loc.current.qry_printed_status = 'all';
badges_loc.current.qry_affiliations = '';
handle_search_trigger();
document.getElementById('badge_fulltext_search_qry_str')?.focus();
}}
class="
hover:text-tertiary-800-200 hover:bg-tertiary-200-800 active:bg-surface-200-700 flex items-center justify-center gap-1 px-3 py-2 text-sm font-bold transition-all duration-1000 hover:duration-300 min-w-0 preset-outlined-tertiary rounded-lg border border-tertiary-200-800