Sådan opbygges og valideres smukke formularer med Vanilla HTML, CSS og JS

Formularer er hårde.  

At vide, hvordan man korrekt indsamler og validerer brugerdata, er en af ​​de vigtigste færdigheder, som en frontend-udvikler skal have. Men det er svært, fordi kant tilfælde er overflod.

Du skal overveje alle de måder, som en bruger kan bryde din smukke lille form på, samtidig med at den giver en fremragende brugeroplevelse.

UX-stykket er vigtigt, fordi formularer er portvagterne for konverteringer til produkter og tjenester. Hvis du, som en frontend-udvikler, får det forkert, kan der have betydelige økonomiske konsekvenser.

Dette er grunden til, at der er tusinder (let overdrivelse) af formbiblioteker derude, der implementerer branchens bedste praksis.  

Der er ikke noget galt med at bruge disse biblioteker. Problemet opstår, når devs bruger dem uden at forstå, hvordan former faktisk fungerer, og hvorfor visse mønstre betragtes som standarder .

Jeg vil vise dig, hvordan jeg ville oprette en tilmeldingsformular fra bunden ved kun at bruge HTML, CSS og JavaScript.

Ok, uden videre, lad os dykke ind.

Den enkelte (standard) tilstandsfælde

Desktop

Mobil

Når du får et design som dette, skal dit første spørgsmål være, hvor mange stater er ikke repræsenteret her?

Eksemplerne ovenfor repræsenterer en tilstand (når en bruger besøger login-siden, er det, hvad de vil se på desktop og mobil).

Andre stater vil omfatte:

  • Fejltilstand
    • Hvad sker der, hvis jeg indtaster en e-mail, der allerede findes?
  • Indlæsningsstat
    • Hvad sker der, når jeg sender formularen?

Når du planlægger dit arbejde, skal du sørge for at overveje, hvad der ikke er i designet, der skal redegøres for. Du skal nøje gennemgå funktionskravene og stille spørgsmål, hvis du mener, at noget mangler.

Funktionskrav

Taler om krav ...

Som udvikler får du ofte et PRD (Product Requirements Document) fra en produktchef, designer eller projektleder.

Disse dokumenter opdeles normalt yderligere i individuelle brugerhistorier, som du udfører under en sprint.

Når jeg sætter min produktmanager-hat på, er her funktionskravene til vores formular:

  • Brugeren skal angive en e-mail-adresse
  • Adgangskoden skal være mindst 10 tegn lang og indeholde mindst et stort bogstav, tal og specialtegn.
  • Vi skal vise fejlmeddelelser til brugeren, når de ikke opfylder kravene

Markup

Den første kode, vi skriver, er HTML med et strejf af CSS.  

Ser ikke ud som meget endnu, men der er noget godt arbejde her. Lad os dykke lidt ind.

  • Vi har opsætningsside og hovedelementer sammen med vores form
  • Jeg bruger BEM som en guide til oprettelse af klassenavne og semantiske HTML-elementer for læsbarhed.
  • Vores tilmeldingsside tager en mobil første tilgang, hvilket betyder, at vi først skriver mobile stilarter og tilføjer breakpoints til desktop-stilarter.
  • Jeg udnytter CSS-gitter til det overordnede layout og Flexbox til positionselementer i hovedsektionen.
  • Jeg har tilføjet en indsend begivenhedslytter til formularen sammen med en begivenhedshåndteringsfunktion, der blot logger begivenhedsobjektet for nu.

Validering

Lad os udnytte nogle indbyggede valideringslogik ved at vælge vores inputtyper klogt. Vi bruger følgende:

  • E-mail-indtastningstype
  • Adgangskodeindtastningstype

E-mail-inputtypen giver os et par gode valideringer gratis.

  1. Det kontrollerer for at sikre, at @symbolet bruges
  2. Det kontrollerer også, at der er tekst efter symbolet

Da både e-mail og adgangskode er påkrævet, skal vi tilføje requiredattributten til begge elementer. Vi tilføjer også en minlengthattribut til adgangskodeindtastningen.

 Sign up with Github   Twitter Or sign in with email and password Sign Up 

Den type=emailattribut fortæller browseren, at den skal validere inputtet som en e-mail.

Den minlengthattribut på indtastning af password giver os denne nyttige fejlmeddelelse:

Nu i vores handleSignupFormSubmit-funktion kan vi bruge FormData API til at få værdierne fra vores formular og til sidst sende dem til en API.

function handleSignupFormSubmit(e) { // prevent default browser behaviour e.preventDefault(); const formDataEntries = new FormData(signupForm).entries(); const { email, password } = Object.fromEntries(formDataEntries); // submit email and password to an API }

Fejlmeddelelser

The error messages that are rendered by the browser are helpful to start, but what if you want these messages to render below their respective form input?  What if you want to control how they look?

Sadly, the browser doesn't give us any control over how the default error message are rendered. So this is where our dkh-form-field__messages div elements come into play. We can render our custom error messages inside these elements.

Let's write a couple custom validation functions to check that our user's password and email values meet the requirements.

 function validatePassword(password, minlength) { if (!password) return 'Password is required'; if (password.length < minlength) { return `Please enter a password that's at least ${minlength} characters long`; } const hasCapitalLetter = /[A-Z]/g; if (!hasCapitalLetter.test(password)) { return 'Please use at least one capital letter.'; } const hasNumber = /\d/g; if (!hasNumber.test(password)) { return 'Please use at least one number.'; } return ''; }
function validateEmail(email) { if (!email) return 'Email is required'; const isValidEmail = /^\[email protected]\S+$/g if (!isValidEmail.test(email)) { return 'Please enter a valid email'; } return ''; }

The regex /^\\[email protected]\\S+$/g is far from bullet proof, but it at least checks to make sure there are characters before and after the @ symbol.  

The best way to validate an email is to send a confirmation email to any user that signs up. The user would then have to open that email and click a link to confirm that their email address is valid.

If you'd like to dig deeper into client side email validation, this is a great thread.

Now, let's figure out how to render the error messages to the page.

function handleSignupFormSubmit(e) { // prevent default browser behaviour e.preventDefault(); const formDataEntries = new FormData(signupForm).entries(); const { email, password } = Object.fromEntries(formDataEntries); const emailErrorMessage = validateEmail(email); const passowrdErrorMessage = validatePassword(password); if (!emailErrorMessage) { // select the email form field message element const emailErrorMessageElement = document.querySelector('.email .dkh-form-field__messages'); // show email error message to user emailErrorMessageElement.innerText = emailErrorMessage; } if (passowrdErrorMessage) { // select the email form field message element const passwordErrorMessageElement = document.querySelector('.password .dkh-form-field__messages'); // show password error message to user passwordErrorMessageElement.innerText = passowrdErrorMessage; } }

One additional thing I'll call out: in order for these messages to show up, we need to remove the required attributes from both the email and password inputs.

We need to change the type attribute value for the email input.

We also need to remove the minlength attribute from the password input.

Updating these attributes removes the browser-based validation in favor of our own validation logic. Here's how our custom error messages will render:

Styles

I leave CSS until the end because, in my personal experience, it's a little harder to focus on logic when the visual design is complete.  

When a component or page "looks" done to the eye it can create a false sense that it is actually done. I don't have any research to back this up, just my personal opinion.

Here's the state of our code after adding quite a bit of CSS.

Desktop

Mobile

Error State

I included font awesome icons for the Github and Twitter Buttons.

 Sign up with  Github    Twitter 

Summary

We have created the building blocks to build sign up and log in forms without 3rd party libraries. You can check out the final source code here.

If you're using a framework like React or Vue, there are a ton of awesome form and validation libraries. You can lean on them to get the job done quickly.

Men hvis du er ny inden for softwareudvikling, vil jeg opfordre dig til først at fokusere på det grundlæggende, inden du bruger disse værktøjer.

Jeg fik mit første job som udvikler for fem år siden, og min rejse til tech har for altid ændret mit liv til det bedre. Jeg tror, ​​at det er vigtigt at fokusere på og mestre det grundlæggende, så du lettere kan forstå værktøjer som React og Vue.

Et af de problemer, jeg bemærkede, da jeg selv kørte et møde i årevis, var at folk, der var nye med kodning, nåede for hurtigt til biblioteker og rammer. Dette endte med at skade dem, og mange kæmpede under interviews.

Hvis du lærer at kode og kunne bruge lidt hjælp, er du velkommen til at kontakte mig på twitter. Ser frem til at hjælpe, men jeg kan.