mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 08:09:18 +02:00
WCAG 3.3.1 (Error Identification): failing fields now get aria-errormessage pointing to the flash-error container and aria-invalid="true". WCAG 3.3.3 (Error Suggestion): <small> hint text on inputs, selects, and file fields is now linked via aria-describedby (always, not just on error). Changes: - text-field.php, select-field.php, checkbox-list.php: accept $errorFieldName; add aria-errormessage/aria-invalid on match; add id to <small> and aria-describedby on the control - fieldset-tfe-info.php: aria-invalid on synopsis textarea - fichiers-fragment.php: aria-describedby on cover, note d'intention, TFE, annexes, and website inputs; aria-invalid on format checkboxes when error matches 'formats' - form.php: id="flash-error" + tabindex="-1" on flash-error div; accept $errorFieldName from callers - admin/add.php: set $errorFieldName, wire $withAutofocusFn (was identity default) - admin/edit.php: set $errorFieldName - partage/index.php: consume autofocus field, wire autofocus function, add App::flashAutofocus() in submit catch block Also fixes WCAG standards issue: removed invalid 'required' HTML attribute from <fieldset> elements in checkbox-list.php and fichiers-fragment.php (only aria-required stays). Added role="group" for explicit ARIA semantics.
82 lines
4.0 KiB
PHP
82 lines
4.0 KiB
PHP
<?php
|
|
/**
|
|
* Shared partial — "Informations du TFE" fieldset.
|
|
*
|
|
* Variables consumed:
|
|
* callable|null $oldFn — callable($key, $default='') to retrieve old/current values;
|
|
* defaults to the global old() function when null.
|
|
* callable|null $withAutofocusFn — callable($field, $attrs=[]) to inject autofocus;
|
|
* defaults to identity when null.
|
|
* array $allowedObjet — list of allowed objet values; when count > 1 a radio group
|
|
* is shown; when count === 1 a hidden input is emitted instead.
|
|
* array $formData — raw form data array (used for checkbox states).
|
|
* string $synopsisExtra — optional HTML block injected after the synopsis label.
|
|
*/
|
|
|
|
$oldFn = $oldFn ?? (function_exists('old') ? 'old' : fn($k, $d = '') => $d);
|
|
$withAutofocusFn = $withAutofocusFn ?? fn($field, $attrs = []) => $attrs;
|
|
$allowedObjet = $allowedObjet ?? [];
|
|
$formData = $formData ?? [];
|
|
$synopsisExtra = $synopsisExtra ?? '';
|
|
$adminMode = $adminMode ?? false;
|
|
$errorFieldName = $errorFieldName ?? null;
|
|
?>
|
|
<fieldset>
|
|
<legend>Informations du TFE</legend>
|
|
|
|
<?php if (!empty($allowedObjet)): ?>
|
|
<?php if (count($allowedObjet) > 1): ?>
|
|
<div class="admin-form-group">
|
|
<label>Type de travail : <span class="asterisk">*</span></label>
|
|
<div class="form-radio-group">
|
|
<?php foreach ($allowedObjet as $objetVal): ?>
|
|
<label class="admin-checkbox-label">
|
|
<input type="radio" name="objet" value="<?= htmlspecialchars($objetVal) ?>"
|
|
<?= ($oldFn('objet') ?: $allowedObjet[0]) === $objetVal ? 'checked' : '' ?>
|
|
<?= $adminMode ? '' : 'required' ?>>
|
|
<?= htmlspecialchars(ucfirst($objetVal)) ?>
|
|
</label>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<input type="hidden" name="objet" value="<?= htmlspecialchars($allowedObjet[0]) ?>">
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
|
|
<?php
|
|
$name = 'titre'; $label = 'Titre du TFE :'; $value = $oldFn('titre'); $required = !$adminMode;
|
|
$attrs = $withAutofocusFn('titre');
|
|
include APP_ROOT . '/templates/partials/form/text-field.php';
|
|
?>
|
|
<?php
|
|
$name = 'subtitle'; $label = 'Sous-titre (si applicable) :'; $value = $oldFn('subtitle'); $required = false;
|
|
include APP_ROOT . '/templates/partials/form/text-field.php';
|
|
?>
|
|
<?php
|
|
$name = 'auteurice'; $label = 'Auteur·ice(s) :'; $value = $oldFn('auteurice'); $required = !$adminMode;
|
|
$attrs = $withAutofocusFn('auteurice', ['autocomplete' => 'name']);
|
|
$hint = 'Séparez les auteur·ices par des virgules.';
|
|
include APP_ROOT . '/templates/partials/form/text-field.php';
|
|
?>
|
|
<?php
|
|
$name = $adminMode ? 'contact_visible' : 'mail';
|
|
$label = 'Contact visible (optionnel) :';
|
|
$value = $oldFn($adminMode ? 'contact_visible' : 'mail');
|
|
$attrs = ['autocomplete' => 'email'];
|
|
$placeholder = 'mail/site/insta/etc.';
|
|
$hint = 'Un seul contact. Collez l\'URL complète du site ou du profil (Instagram, Mastodon, site perso…) ou l\'adresse mail. Le lien sera automatiquement raccourci à l\'affichage (ex: https://instagram.com/pseudo → @pseudo, https://www.erg.be → erg.be).';
|
|
include APP_ROOT . '/templates/partials/form/text-field.php';
|
|
?>
|
|
|
|
<div>
|
|
<label for="synopsis">Synopsis :<?= $adminMode ? '' : ' <span class="asterisk">*</span>' ?></label>
|
|
<?= $synopsisExtra ?>
|
|
<textarea id="synopsis" name="synopsis" rows="7" <?= $adminMode ? '' : 'required' ?>
|
|
<?= ($withAutofocusFn('synopsis')['autofocus'] ?? false) ? 'autofocus' : '' ?>
|
|
<?= ($errorFieldName === 'synopsis') ? 'aria-invalid="true" aria-errormessage="flash-error" aria-describedby="flash-error"' : '' ?>><?= $oldFn('synopsis') ?></textarea>
|
|
</div>
|
|
</fieldset>
|
|
<?php
|
|
unset($allowedObjet, $synopsisExtra);
|