Hopp til innhold

Select

Vi bruker nedtrekkslister til å gi brukeren en liste med alternativ. Nedtrekkslister passer i de tilfellene det er for mange valg til å bruke radioknapper. Nedtrekkslisten må ha en overskrift, som forteller hva det er brukerne kan velge mellom i listen.

Prinsipper

Om du har fem eller færre valg kan det være bedre å bruke Radio buttons.

Hvis du trenger en nedtrekksliste med mange valg, kan du også legge inn en søke- eller filtreringsfunksjon. Dersom brukeren alltid må scrolle i listen over valg er det kanskje på tide å la de søke.

Når skal du bruke select

Vi bruker en nedtrekksliste når vi skal gi brukeren en liste med alternativ, og hvor Radio buttons ikke passer. Noen eksempler på bruk er:

  • Til å velge årsak eller skadetype
  • Til å velge diagnose
  • Til å velge stilling

En nedtrekksliste med søk har noen likhetstrekk med Autosuggest. En nyanseforskjell er at en nedtrekksliste ikke lar brukeren velge noe annet enn de forhåndsbestemte alternativene. Om du ønsker at brukerens søk skal være et gyldig valg uansett, bruk Autosuggest.

Tekst og validering

Bruk prinsippene for skjemadesign til å velge størrelse på overskriften til listen. Lag en kort og tydelig tekst, som forteller hva det er brukeren skal gjøre i nedtrekkslisten. Hvis det trengs, kan du legge en hjelpetekst under listen for å forklare mer.

Hvis nedtrekkslisten ikke validerer, viser systemet en feilmelding som forklarer hva som er galt. Feilmeldingen erstatter en eventuell hjelpetekst, så den må eventuelt gjenta informasjonen fra hjelpeteksten.

For eksempel, gitt en hjelpetekst "Velg landet du var på ferie i da du ble syk" kan vi ha en feilmelding "Du må velge hvor du var på ferie da du ble syk".

Demo

Skjemavalidering
Visning
Tema
Tetthet
const Skjemavalideringseksempel = () => {
const { formState, handleSubmit, register } = useForm({
shouldFocusError: false,
});
/** Gjør klar props til oppsummeringen */
const { errors: hookFormErrors, isSubmitted, isValid } = formState;
const errors = Object.entries(hookFormErrors).flatMap(([, error]) =>
Array.isArray(error) ? error.map((e) => e.message) : [error.message]
);
/**
* Gjør klart skjemaet for scrolling til oppsummeringen av feil. Sørg for at
* skjemaet får en fornuftig scroll-padding-top slik at alt blir synlig med
* tilstrekkelig luft.
*
* https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-padding-top
*/
const scrollRef = React.useRef(null);
const [scrollToErrorSummary] = useScrollIntoView({
ref: scrollRef,
autoScroll: false,
});
const onError = () => {
scrollToErrorSummary();
scrollRef.current?.focus();
};
const onSubmit = (formData) => console.table(formData);
return (
<div className="jkl-spacing-40--bottom">
<form onSubmit={handleSubmit(onSubmit, onError)}>
<div
className="jkl-portal-scroll-anchor"
tabIndex={-1} // Negativ TabIndex trengs for å kunne flytte fokus til elementet, så neste Tab går til første skjemafelt
ref={scrollRef}
/>
<FormErrorMessageBox
className="jkl-portal-paragraph"
errors={errors}
isSubmitted={isSubmitted}
isValid={isValid}
/>
<p className="heading-4 jkl-spacing-16--bottom">
Hvem er eier av forsikringen?
</p>
<TextInput
{...register("fodselsnummer", {
required: "Du må fylle ut eierens fødselsnummer",
pattern: {
value: /^\d{11}$/,
message: "Fødselsnummeret må bestå av 11 siffer",
},
})}
className="jkl-spacing-24--bottom"
label="Fødselsnummer"
errorLabel={formState.errors.fodselsnummer?.message}
/>
<TextInput
{...register("fornavn", {
required: "Du må fylle ut eierens fornavn",
})}
className="jkl-spacing-24--bottom"
autoComplete="given-name"
label="Fornavn"
errorLabel={formState.errors.fornavn?.message}
/>
<TextInput
{...register("etternavn", {
required: "Du må fylle ut eierens etternavn",
})}
className="jkl-spacing-24--bottom"
autoComplete="family-name"
label="Etternavn"
errorLabel={formState.errors.etternavn?.message}
/>
<DatePicker
className="jkl-spacing-24--bottom"
disableAfterDate={formatInput(new Date())}
errorLabel={formState.errors.fodselsdato?.message}
label="Fødselsdato"
{...register("fodselsdato", {
required: "Du fylle ut fødselsdato",
validate: {
isCorrectFormat: (v) =>
isCorrectFormat(v) ||
`Datoen være skrevet i formen ${formatDate(
new Date()
)} eller kortformat`,
withinUpperBound: (v) =>
isWithinUpperBound(v, new Date()) ||
`Datoen være før ${formatDate(new Date())}`,
},
})}
/>
<Select
{...register("stilling", {
required: "Du må oppgi eierens stilling",
})}
className="jkl-spacing-40--bottom"
errorLabel={formState.errors.stilling?.message}
items={["Designer", "Utvikler", "Tester", "Leder", "Annet"]}
label="Stilling"
width="14rem"
/>
<RadioButtonGroup
className="jkl-spacing-24--bottom"
labelProps={{ variant: "small" }}
legend="Under 23"
errorLabel={formState.errors.u23?.message}
>
<RadioButton
{...register("u23", {
required: "Du må oppgi om eier er under 23 år gammel",
})}
label="Ja"
value="y"
/>
<RadioButton
{...register("u23", {
required: "Du må oppgi om eier er under 23 år gammel",
})}
label="Nei"
value="n"
/>
</RadioButtonGroup>
<FieldGroup
legend="Er klient"
className="jkl-spacing-40--bottom"
labelProps={{ variant: "small" }}
errorLabel={formState.errors.klient?.message}
>
<Checkbox {...register("klient")} value="ja">
Ja
</Checkbox>
</FieldGroup>
<PrimaryButton type="submit">Gå videre</PrimaryButton>
</form>
</div>
);
};
return <Skjemavalideringseksempel />;