mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
86 lines
4.8 KiB
PHP
86 lines
4.8 KiB
PHP
<?php
|
|
/**
|
|
* Language search partial — interactive "Autre(s) langue(s)" input with HTMX-powered suggestions.
|
|
*
|
|
* Replaces the old plain text input with an interactive component:
|
|
* - Type to search among existing languages via HTMX
|
|
* - If the language doesn't exist, a "Créer" option appears
|
|
* - Selected languages are shown as pills with a round delete button (bin icon)
|
|
* - All language names are lowercased and deduplicated
|
|
*
|
|
* Variables consumed:
|
|
* string $name — base input name (hidden inputs will be name[]); default 'language_autre'
|
|
* string $label — visible label text
|
|
* string $placeholder — placeholder text for the search input
|
|
* string $hint — optional hint shown above the input
|
|
* string $hxPost — HTMX POST endpoint for language search
|
|
* array $selectedLanguages — array of ['id' => int|null, 'name' => string] for pre-filled languages
|
|
* string|null $id — override the id attribute prefix
|
|
* int $maxLanguages — maximum number of languages (default 10)
|
|
* bool $required — whether at least one "other language" is required (default false)
|
|
*/
|
|
|
|
$name = $name ?? 'language_autre';
|
|
$label = $label ?? 'Autre(s) langue(s)';
|
|
$placeholder = $placeholder ?? 'Rechercher une langue…';
|
|
$hint = $hint ?? null;
|
|
$hxPost = $hxPost ?? '/admin/fragments/pill-search.php';
|
|
$selectedLanguages = $selectedLanguages ?? [];
|
|
$id = $id ?? $name;
|
|
$maxLanguages = $maxLanguages ?? 10;
|
|
$required = $required ?? false;
|
|
$langCount = count($selectedLanguages);
|
|
?>
|
|
<div id="<?= htmlspecialchars($id) ?>-search-container" data-pill-search data-pill-name="<?= htmlspecialchars($name) ?>" data-pill-max="<?= (int)$maxLanguages ?>" data-pill-min="0" data-pill-required="0" data-pill-role="lang" data-search-container-id="<?= htmlspecialchars($id . '-search-container') ?>">
|
|
<span class="admin-row-label"><?= htmlspecialchars($label) ?><span id="language-autre-required"><?= $required ? ' <span class="asterisk">*</span>' : '' ?></span></span>
|
|
<div class="tag-search-wrapper">
|
|
<?php if ($hint): ?>
|
|
<small class="tag-search-hint"><?= htmlspecialchars($hint) ?></small>
|
|
<?php endif; ?>
|
|
|
|
<!-- Active language pills -->
|
|
<div class="tag-search-pills" id="<?= htmlspecialchars($id) ?>-pills">
|
|
<?php foreach ($selectedLanguages as $lang): ?>
|
|
<span class="tag-pill">
|
|
<input type="hidden" name="<?= htmlspecialchars($name) ?>[]" value="<?= htmlspecialchars($lang['name']) ?>">
|
|
<span class="tag-pill-name"><?= htmlspecialchars($lang['name']) ?></span>
|
|
<button type="button" class="tag-pill-remove" title="Retirer « <?= htmlspecialchars($lang['name']) ?> »" aria-label="Retirer <?= htmlspecialchars($lang['name']) ?>">
|
|
<?= icon('trash-slash') ?>
|
|
</button>
|
|
</span>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<!-- Counter visible only when languages exist or max reached -->
|
|
<div class="tag-search-counter" id="<?= htmlspecialchars($id) ?>-counter"<?= $langCount === 0 ? ' style="display:none"' : '' ?>>
|
|
<span class="tag-search-count" id="<?= htmlspecialchars($id) ?>-count"><?= $langCount ?>/<?= (int)$maxLanguages ?></span>
|
|
<?php if ($langCount >= $maxLanguages): ?>
|
|
<span class="tag-search-max-msg">Maximum de langues atteint</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<!-- Search input (hidden when max languages reached) -->
|
|
<div class="tag-search-input-wrap"<?= $langCount >= $maxLanguages ? ' style="display:none"' : '' ?>>
|
|
<input type="text"
|
|
name="language_search_q"
|
|
id="<?= htmlspecialchars($id) ?>-search"
|
|
class="tag-search-input"
|
|
placeholder="<?= htmlspecialchars($placeholder) ?>"
|
|
autocomplete="off"
|
|
hx-post="<?= htmlspecialchars($hxPost) ?>"
|
|
hx-trigger="input changed delay:200ms, focus"
|
|
hx-target="#<?= htmlspecialchars($id) ?>-suggestions"
|
|
hx-swap="innerHTML"
|
|
hx-vals='{"pill_type":"language"}'
|
|
hx-include="#<?= htmlspecialchars($id) ?>-pills">
|
|
</div>
|
|
|
|
<!-- Suggestions dropdown (positioned absolutely over content) -->
|
|
<div class="tag-search-suggestions" id="<?= htmlspecialchars($id) ?>-suggestions" role="listbox"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="<?= App::assetV('/assets/js/app/form-language-asterisk.js') ?>"></script>
|
|
<?php
|
|
unset($name, $label, $placeholder, $hint, $hxPost, $selectedLanguages, $id, $maxLanguages, $langCount, $required);
|