178 lines
8.5 KiB
HTML
178 lines
8.5 KiB
HTML
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Styleguide – Pattern Formular mit Abschnitten</title>
|
||
<link rel="stylesheet" href="../styleguide.css">
|
||
</head>
|
||
<body>
|
||
|
||
<h1 class="sg-main-heading">Pattern – Formular mit Abschnitten</h1>
|
||
<section id="pattern-formular-mit-abschnitten">
|
||
<p class="sg-preview-label">Pattern: Formular mit Abschnitten</p>
|
||
|
||
<div class="sg-form-sections-card-wrapper" data-pattern="form-sections" aria-label="Formular mit Abschnitten">
|
||
<form class="sg-form-sections-card" action="#" method="post">
|
||
<div class="sg-form-sections-card__body" data-pattern-part="form-body">
|
||
<h2 class="sg-strong sg-form-sections-card__title">Formular</h2>
|
||
|
||
<section class="sg-form-sections-card__chapter" aria-labelledby="form-kapitel-1">
|
||
<h2 id="form-kapitel-1" class="sg-strong sg-form-sections-card__chapter-title">Persoenliche Auswahl</h2>
|
||
|
||
<p class="sg-body sg-form-sections-card__sentence">Bitte waehlen Sie Ihre bevorzugte Kontaktart fuer die Rueckmeldung.</p>
|
||
|
||
<div class="sg-form-sections-card__option-group" role="radiogroup" aria-label="Kontaktart">
|
||
<label class="sg-checkbox-field-option sg-body" data-component="radio-field" data-component-state="inactive-selectable">
|
||
<button class="sg-radio-field sg-radio-field--inactive-selectable" type="button" role="radio" aria-checked="false" aria-label="Kontakt per E-Mail">
|
||
<span class="sg-radio-field__mark" aria-hidden="true"></span>
|
||
</button>
|
||
<span>E-Mail</span>
|
||
</label>
|
||
|
||
<label class="sg-checkbox-field-option sg-body" data-component="radio-field" data-component-state="inactive-selectable">
|
||
<button class="sg-radio-field sg-radio-field--inactive-selectable" type="button" role="radio" aria-checked="false" aria-label="Kontakt per Telefon">
|
||
<span class="sg-radio-field__mark" aria-hidden="true"></span>
|
||
</button>
|
||
<span>Telefon</span>
|
||
</label>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="sg-form-sections-card__chapter" aria-labelledby="form-kapitel-2">
|
||
<h2 id="form-kapitel-2" class="sg-strong sg-form-sections-card__chapter-title">Optionale Angaben</h2>
|
||
|
||
<p class="sg-body sg-form-sections-card__sentence">Bitte markieren Sie die zusaetzlichen Informationen, die wir beruecksichtigen sollen.</p>
|
||
|
||
<div class="sg-form-sections-card__option-group" aria-label="Zusatzoptionen">
|
||
<label class="sg-checkbox-field-option sg-body" data-component="checkbox-field" data-component-state="inactive-selectable">
|
||
<button class="sg-checkbox-field sg-checkbox-field--inactive-selectable" type="button" role="checkbox" aria-checked="false" aria-label="Newsletter abonnieren">
|
||
<span class="sg-checkbox-field__mark" aria-hidden="true">✓</span>
|
||
</button>
|
||
<span>Newsletter abonnieren</span>
|
||
</label>
|
||
|
||
<label class="sg-checkbox-field-option sg-body" data-component="checkbox-field" data-component-state="inactive-selectable">
|
||
<button class="sg-checkbox-field sg-checkbox-field--inactive-selectable" type="button" role="checkbox" aria-checked="false" aria-label="Rueckruf am Vormittag erlauben">
|
||
<span class="sg-checkbox-field__mark" aria-hidden="true">✓</span>
|
||
</button>
|
||
<span>Rueckruf am Vormittag erlauben</span>
|
||
</label>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="sg-form-sections-card__chapter" aria-labelledby="form-kapitel-3">
|
||
<h2 id="form-kapitel-3" class="sg-strong sg-form-sections-card__chapter-title">Freitext und Details</h2>
|
||
|
||
<p class="sg-body sg-form-sections-card__sentence">Bitte erfassen Sie einen kurzen Betreff und eine genauere Beschreibung Ihres Anliegens.</p>
|
||
|
||
<div class="sg-form-sections-card__field-group">
|
||
<label class="sg-labeled-input-row">
|
||
<span class="sg-label">Betreff</span>
|
||
<input
|
||
class="sg-interaction-element sg-input-single-line sg-input-single-line--inactive-selectable sg-form-inactive-selectable"
|
||
type="text"
|
||
placeholder="Betreff eingeben"
|
||
aria-label="Betreff"
|
||
>
|
||
</label>
|
||
|
||
<label class="sg-labeled-input-row">
|
||
<span class="sg-label">Nachricht</span>
|
||
<textarea
|
||
class="sg-input-multi-line sg-form-inactive-selectable"
|
||
rows="3"
|
||
placeholder="Nachricht eingeben"
|
||
aria-label="Nachricht"
|
||
></textarea>
|
||
</label>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<footer class="sg-form-sections-card__actions-segment" data-pattern-part="form-actions-segment">
|
||
<div class="sg-form-sections-card__actions" data-pattern-part="form-actions">
|
||
<button class="sg-interaction-element sg-button sg-button--active sg-form-sections-card__action" type="button">Abbrechen</button>
|
||
<button class="sg-interaction-element sg-button sg-button--process sg-button--process-inactive sg-form-sections-card__action" type="submit" disabled aria-disabled="true">Prozess Button</button>
|
||
</div>
|
||
</footer>
|
||
</form>
|
||
</div>
|
||
</section>
|
||
|
||
<script>
|
||
(() => {
|
||
const formCard = document.querySelector('.sg-form-sections-card');
|
||
if (!formCard) {
|
||
return;
|
||
}
|
||
const processButton = formCard.querySelector('.sg-button--process');
|
||
if (!processButton) {
|
||
return;
|
||
}
|
||
|
||
const updateProcessButtonState = () => {
|
||
const hasCheckedOption = Array.from(formCard.querySelectorAll('[role="radio"], [role="checkbox"]'))
|
||
.some((field) => field.getAttribute('aria-checked') === 'true');
|
||
const hasTextInput = Array.from(formCard.querySelectorAll('input[type="text"], textarea'))
|
||
.some((field) => field.value.trim().length > 0);
|
||
const isActive = hasCheckedOption || hasTextInput;
|
||
|
||
processButton.disabled = !isActive;
|
||
processButton.setAttribute('aria-disabled', String(!isActive));
|
||
processButton.classList.toggle('sg-button--process-inactive', !isActive);
|
||
};
|
||
|
||
formCard.querySelectorAll('[role="radiogroup"]').forEach((group) => {
|
||
group.querySelectorAll('[data-component="radio-field"]').forEach((option) => {
|
||
option.addEventListener('click', () => {
|
||
const selectedRadio = option.querySelector('.sg-radio-field');
|
||
if (!selectedRadio || selectedRadio.disabled) {
|
||
return;
|
||
}
|
||
|
||
group.querySelectorAll('[data-component="radio-field"]').forEach((otherOption) => {
|
||
const otherRadio = otherOption.querySelector('.sg-radio-field');
|
||
if (!otherRadio) {
|
||
return;
|
||
}
|
||
|
||
const isSelected = otherRadio === selectedRadio;
|
||
otherRadio.setAttribute('aria-checked', String(isSelected));
|
||
otherRadio.classList.toggle('sg-form-active', isSelected);
|
||
otherRadio.classList.toggle('sg-radio-field--inactive-selectable', !isSelected);
|
||
otherOption.setAttribute('data-component-state', isSelected ? 'active' : 'inactive-selectable');
|
||
});
|
||
|
||
updateProcessButtonState();
|
||
});
|
||
});
|
||
});
|
||
|
||
formCard.querySelectorAll('[data-component="checkbox-field"]').forEach((option) => {
|
||
option.addEventListener('click', () => {
|
||
const checkbox = option.querySelector('.sg-checkbox-field');
|
||
if (!checkbox || checkbox.disabled) {
|
||
return;
|
||
}
|
||
|
||
const nextState = checkbox.getAttribute('aria-checked') !== 'true';
|
||
checkbox.setAttribute('aria-checked', String(nextState));
|
||
checkbox.classList.toggle('sg-form-active', nextState);
|
||
checkbox.classList.toggle('sg-checkbox-field--inactive-selectable', !nextState);
|
||
option.setAttribute('data-component-state', nextState ? 'active' : 'inactive-selectable');
|
||
updateProcessButtonState();
|
||
});
|
||
});
|
||
|
||
formCard.querySelectorAll('input[type="text"], textarea').forEach((field) => {
|
||
field.addEventListener('input', updateProcessButtonState);
|
||
});
|
||
|
||
updateProcessButtonState();
|
||
})();
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|