leestijd
4 min

Fouttags animeren in Phoenix LiveView

Het probleem

Functies buiten de belangrijkste gebruikersroute vergeten we vaak, of we kiezen voor een heel eenvoudige implementatie. Zulke subtiele interacties en uitzonderingssituaties maken een product merkbaar prettiger, maar kosten vaak te veel tijd om te bouwen. Toch weten we allemaal dat details ertoe doen.

De oplossing

Hiervoor moeten we binnen een Phoenix LiveView-project een formulier en de bijbehorende changeset opzetten en de gegevens valideren. We zijn ook dol op Tailwind, dus ik heb een voorbeeldproject voorbereid waarin alles samenkomt. Geen zorgen: we nemen het ook stap voor stap door.

We beginnen met de HTML-template (heex):

lib/errortags_web/live/index.html.heex
↳ lib/errortags_web/live/index.html.heex

We gebruiken de standaardfunctiecomponent voor formulieren van Phoenix en plaatsen die in een fraai vormgegeven div. Het formulier bevat twee eigen functiecomponenten: <.input /> en <.button />. Ieder invoerelement krijgt een eigen container voor foutmeldingen, die we dus in de definitie moeten vastleggen.

lib/errortags_web/live/index.ex
↳ lib/errortags_web/live/index.ex

De code hierboven rendert simpelweg een fraai invoerelement dat aan de functiecomponent van het formulier wordt gekoppeld. Als je met de CLI een Phoenix-project maakt, wordt een module met de naam ErrorHelpers gegenereerd. Die gebruik je vervolgens in een formulier met <%= error_tag @f, @name %>. Je vindt dit bestand in lib/errortags_web/views/error_helpers.ex. We maken er een functiecomponent voor onze LiveView-opzet van (regel 6):

~use Phoenix.HTML~
use Phoenix.LiveComponent

Daarna passen we de definitie van error_tag aan om onze fraaie foutmelding te tonen, inclusief animatie:

lib/errortags_web/views/error_helpers.ex
↳ lib/errortags_web/views/error_helpers.ex

Nu kunnen we de foutcomponent boven onze <%= text_input ... %> plaatsen. Deze is alleen zichtbaar als je changeset een fout bevat.

<.error_tag f={@f} name={@name} />

Dit is het resultaat tot nu toe:

but we’re missing the red border around the input element!

Communiceren tussen functiecomponenten

Om vast te stellen of het formulier een fout bevat, moet onze input-functiecomponent weten dat er een fout is. Die logica staat alleen in de functiecomponent error_tag, niet in de input-functiecomponent. We willen voorkomen dat we op meerdere plekken dezelfde code schrijven om fouten uit het formulier op te halen, zeker als we dit systeem ook op andere input-functiecomponenten willen toepassen, bijvoorbeeld een checkbox-component.

Gelukkig bieden Phoenix slots uitkomst. Daarvoor moeten we wel een deel van onze code herschrijven.

lib/errortags_web/views/error_helpers.ex
↳ lib/errortags_web/views/error_helpers.ex

We voegen een slot has_error? toe aan onze input-functiecomponent en plaatsen die in de functiecomponent error_tag, zodat we gegevens kunnen doorgeven. Zoals je hierboven ziet, wordt deze om de component heen geplaatst en gebruikt als form_tag. De HTML voor de fout blijft hetzelfde, maar eindigt met <%= render_slot(...) %>. Daar wordt de input-functiecomponent gerenderd, met als tweede parameter een boolean. Zo blijft error_tag verantwoordelijk voor het vaststellen van een fout, terwijl onze input-functiecomponent daarop wordt aangepast:

lib/errortags_web/live/index.ex
↳ lib/errortags_web/live/index.ex

Hier plaatsen we het invoerelement in de slot. Ook hebben we de class van text_input aangepast, zodat er bij een fout een duidelijke rand omheen verschijnt.

Yep, hetzelfde als de afbeelding bovenaan dit artikel
↳ Yep, hetzelfde als de afbeelding bovenaan dit artikel

Dit kan ook op andere manieren, maar we houden de implementatie voor het renderen van een invoerveld graag zo eenvoudig mogelijk. Dat is gelukt: gebruik onderstaande code en je krijgt de fraaie foutmelding er automatisch bij.

<.input f={f} name={:email} />

Wil je het zelf proberen? Je vindt de voorbeeldcode op GitHub.

Gepubliceerd op 15 april 2022
werkt met
Ontwikkelaar?
Onze documentatie begeleidt je bij het embedden van video: van eenvoudige eerste stappen tot handmatige configuraties voor ervaren gebruikers. Je vindt er meerdere hostingopties, waaronder ons standaard-CDN, en uitleg over populaire webframeworks.
script
react
vue
1
2
3
4
5
🍪 Klik op ‘Accepteren’ om te bevestigen dat je het ermee eens bent dat we geen cookies gebruiken. Ja, deze banner is puur voor de show!
Accepteren