Un formulari pemet recollir dades de l'usuari i enviar-les a un servidor
Introducció
Un formulari és un document que té espais per recollir informació.
A diferència d'un formulari en paper, un formulari HTML té un botó que envia les dades a un servidor.
Entorn de treball
A continuació executarem un servidor TypeScript en entorn local per tal de poder provar que els nostres formularis funcinonen correctament.
Instal.la node
amb Scoop:
> scoop install nodejs
Baixa el projecte https://gitlab.com/xtec/web/form:
> git clone https://gitlab.com/xtec/web/form
> cd form
Instal.la les dependències de l'aplicació:
> npm install
added 65 packages, and audited 66 packages in 1s
13 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Arrenca el servidor web:
> npm run dev
Listening on http://localhost
Obre el navegador a http://localhost
A la pàgina "home" hi ha un formulari.
Omple les dades del formulari i apreta el botó enviar:
El navegador enviar les dades a la URL /form
.
El servidor executa aquesta secció de codi del fitxer src/main.ts
:
app.get('/form', (req: Request, res: Response) => {
res.render("form", { title: "GET", params: req.query })
})
El servidor crea un document web amb una taula on estan totes les dades que ha rebut, que estan en la propietat req.query
, i retona un document HTML:
Formulari
Obre el projecte amb VS Code.
A la carpeta public
es on està el document index.html
amb el formulari de la pàgina /
o "home".
Un formulari es declara amb l'element <form>
:
<form action="/form">
</form>
Action
L'atribut action
de l'element form
indica la URL a la que s'ha d'enviar el formulari.
Si no declares l'atribut, el formulari s'envia amb el mètode HTTP GET
, i les dades s'afegeixen al final de la URL a continuació de ?
.
Si et fixes en la URL, pots veure les dades del formulari que has omplert:
Com has vist abans, aquesta sol.licitut la processa el mètode app.get('/form',...)
del fitxer src/main.ts
.
Normalment el mètode GET
es fa servir en formularis petits, o quan vols que el servidor t'envii dades.
En tots els altres casos, com es pujar un fitxer, dades sensibles, etc., és millor utilitzar el mètode POST
que incorpora les dades en el camp body
de la sol.licitut.
Modifica el fitxer index.html
i indica que el mètode és POST
:
<form action="/form" method="POST">
</form>
Ara la sol.licitut la processa el mètode app.post('/form',...)
del fitxer src/main.ts
.
Input
Un formulari està format per un o més camps, on cada camp té un name
que identifica la dada, i un botó per fer clic i enviar les dades al servidor :
<form action="/form" method="POST">
<input type="text" name="nom"/>
<button type="submit">Envia</button>
</form>
Modifica el fitxer index.html
i afegeix el camp cognom
i telefon
:
<form action="/form" method="POST">
<input type="text" name="nom"/>
<input type="text" name="cognom"/>
<input type="text" name="telefon"/>
<button type="submit">Envia</button>
</form>
Omple el formulari i envia les dades al servidor:
Però potser l'usuari vol saber que ha de posar en cada camp ...
Doncs posa un element <label>
al costat d'un element <input>
:
<form action="/form" method="POST">
<label>Nom</label>
<input type="text" name="nom"/>
<button type="submit">Envia</button>
</form>
Però millor si associes el <label>
amb l'<input>
: afegeix un atribut id
a l'element <input>
, i un atribut for
a l'element <label>
amb la id
de l'element <input>
.
<form action="/form" method="POST">
<label for="nom">Nom</label>
<input type="text" id="nom" name="nom"/>
<button type="submit">Envia</button>
</form>
D'aquesta manera, si fas clic a l'etiqueta, l'input agafa el focus de l'entrada de text.
Però si vols estilitzar un formulari, has d'afegir classes de Bootstrap:
<form action="/form" methos="post">
<div class="mb-3">
<label for="nom" class="form-label">Nom</label>
<input type="text" class="form-control" id="nom" name="nom">
</div>
<div class="mb-3">
<label for="cognom" class="form-label">Cognom</label>
<input type="text" class="form-control" id="cognom" name="cognom">
</div>
<div class="mb-3">
<label for="telefon" class="form-label">Telefon</label>
<input type="text" class="form-control" id="telefon" name="telefon">
</div>
<button type="submit" class="btn btn-primary">Envia</button>
</form>
Input
L'element <input>
és fa servir per recollir una dada simple que pot ser de tipus diferents.
L'atribut type
indica quin tipus de dada s'espera i el navegador visualitza l'element de manera diferent i valida la dada que l'usuari entra.
Fins ara has utlitzat el tipus neutre text
:
<form action="/form" method="POST">
<label>Nom</label>
<input type="text" name="nom"/>
<button type="submit">Envia</button>
</form>
Per exemple, pots utilizar el tipus email
o password
tal com es mostra a continuació:
Pots veure que:
- Si no introdueixes un email en format correcte no et deixa enviarel formulari.
- La contrassenya no es visualitza.
<form action="/form" method="post">
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" name="email">
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<button type="submit">Envia</button>
</form>
Altres tipus són: color
, date
, month
, number
, range
, tel
, time
, url
o week
.
Text Area
L'element <textarea>
s'utilitza per crear una entrada de text de diverses línies, i ha de tenir una etiqueta d'obertura i una de tancament.
<form action="/form" method="post" class="m-3">
<textarea class="form-control" name="text" rows=5>Cowards die many times before their deaths; the valiant never taste of death but once</textarea>
<button type="submit" class="btn btn-primary mt-3">Envia</button>
</form>
Qualsevol text que apareix entre les etiquetes d'obertura <textarea>
, i de tancament </textarea>
, apareix al quadre de text quan es carregua la pàgina.
L'atribut rows
indica quantes files s'han de visualitzar, que equival a dir quin espai vertical ha d'ocupar l'element <textarea>
.
Opcions
Alguns cops l'usuari ha d'escollir entre vàries opcions.
Radio Button
Si l'usuari només pot escollir una opció, es fa servir un conjunt d'elements <input>
de tipus radio
.
Si fas clic a un botó, aquest queda seleccionat, però si fas clic a un altre botó aquest queda selecciont i l'altre deixar d'estar seleccionat, tal com passava en les radios dels cotxes antics:
El navegador sap que tots aquests elements <input>
de tipus radio
estan relacionats perqué el valor de l'atribut name
és el mateix:
<form action="/form" method="post" class="m-3">
<div class="form-check">
<input class="form-check-input" type="radio" name="music" value="rock" id="music-rock">
<label class="form-check-label" for="music-rock">Rock</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="music" value="pop" id="music-pop" checked>
<label class="form-check-label" for="music-pop">Pop</label>
</div>
<button type="submit" class="btn btn-primary mt-2">Envia</button>
</form>
I com que l'usuari no ha d'introduïr cap dada, tots els elements <input>
tenen l'atribut value
que és el que s'envia al servidor.
Si vols que sempre hi hagi un valor seleccionat per defecte, un dels elements <input>
ha de tenir l'atribut checked
.
Per saber més: https://uxplanet.org/radio-buttons-ux-design-588e5c0a50dc
Checkbox
Un "checkbox" es fa servir quan l'usuari ha de poder seleccionar més d'un element:
En aquest cas, l'<input>
és de tipus checkbox
i, igual que amb el elements de tipus radio
, han de tenir el mateix valor per l'atribut name
.
<form action="form" method="post">
<p>Please select your favorite music service(s):</p>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="service" value="itunes" id="service-itunes">
<label class="form-check-label" for="service-itunes">iTunes</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="service" value="spotify" id="service-spotify">
<label class="form-check-label" for="service-spotify">Spotify</label>
</div>
<button type="submit" class="btn btn-primary mt-3">Envia</button>
</form>
select
Enlloc d'utlitzar els elements <input>
de "type" radio
i checkbox
, pots utilitzar l'element <select>
, que mostra les diferents opcions en una llista que es desplega, i és molt útil quan hi ha moltes opcions disponibles i vols que ocupi el mínimm espai.
L'element <select>
té l'atriburt name
, i està format per un conjunt d'elements <option>
que tenen l'atribut value
corresponent.
<form action="/form" method="post">
<label for="select-cars">Escull un cotxe:</label>
<select id="select-cars" class="form-select mt-3" name="car">
<option selected value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<button type="submit" class="btn btn-primary mt-3">Submit</button>
</form>
Amb l'atribut selected
pots seleccionar quina opció s'utlitza per defecte.
Si no indiques cap, els navegadors envien la primera de la llista.
Selecció multiple
Si vols permetre que l'usuari seleccioni més d'una opció, has d'utlitzar l'atribut mutltiple
en l'element select
.
Has de mantenir la tecla Ctrl
apretada per seleccionar més d'un valor:
<form action="/form" method="post">
<label for="select-languages">Quins idiomes parles:</label>
<select id="select-languages" class="form-select" name="languages" multiple>
<option value="english">Anglès</option>
<option value="arabic">Àrab</option>
<option value="castellà">Castellà</option>
<option value="catalan">Català</option>
<option value="french">Francés</option>
</select>
<button type="submit" class="btn btn-primary mt-3">Envia</button>
</form>
Fitxer
<form action="/form" method="post">
<label for="file-song" class="form-check-label">Puja una cançó:</label>
<input type="file" id="file-song" class="form-control mt-3" name="song" />
<button type="submit" class="btn btn-primary mt-3">Upload</button>
</form>
Si voleu permetre que els usuaris pugin un fitxer (per exemple, una imatge, un vídeo, un mp3 o un PDF), haureu d'utilitzar un quadre d'entrada de fitxer.
Activitats
1.- La millor manera d'apendre un cop ja saps els fonament, es mirar, seleccionar, copiar i adaptar.
En aquests document tens uns quants exemples: Boostrap 5 forms.
2.- Escriu aquest formulari
Fulla de l'aventurer
<div class="container p-3">
<h1 class="fs-3 text-center text-success">Fulla de l'aventurer</h1>
<form action="/form" class="border border-3 rounded p-2">
<div class="border border-2 rounded p-2 bg-primary">
<p class="fw-bold text-white">Informació</p>
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Nom</span>
<input type="text" class="form-control" />
</div>
<div class="input-group mb-3">
<span class="input-group-text">Raça</span>
<select class="form-select">
<option selected value="1">Elf</option>
<option value="2">Nan</option>
<option value="3">Home</option>
</select>
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Altura</span>
<input type="number" class="form-control" placeholder="en cms" />
</div>
<div class="mb-3">
<label class="form-label">Equipament:</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"
placeholder="Armes, motxilles i altres possesions"></textarea>
</div>
</div>
<div class="border border-2 rounded p-2 bg-info mt-3">
<p class="fw-bold text-white">Característiques</p>
<div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1"
value="option1" />
<label class="form-check-label" for="inlineRadio1">Destreça</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio2"
value="option2" />
<label class="form-check-label" for="inlineRadio2">Força</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio3"
value="option3" />
<label class="form-check-label" for="inlineRadio3">Intell.ligència</label>
</div>
</div>
<div class="input-group mt-3">
<span class="input-group-text">Nivell</span>
<select class="form-select">
<option selected value="1">Obligatori</option>
<option value="2">Opcional</option>
</select>
</div>
</div>
<div class="border border-2 rounded p-2 bg-info mt-3">
<p class="fw-bold text-white">Habilitats</p>
<div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" name="habilitats" value="agilitat" />
<label class="form-check-label">Agilitat</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" name="habilitats" value="coneixement" />
<label class="form-check-label">Coneixement</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" name="habilitats" value="manipulació" />
<label class="form-check-label">Manipulació</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" name="habilitats" value="percepció" />
<label class="form-check-label">Percepció</label>
</div>
</div>
</div>
<div class="d-grid gap-2 d-md-block mt-3 ">
<button type="submit" class="btn btn-primary">Jugar</button>
<button type="submit" class="btn btn-danger">Cancelar</button>
</div>
</form>
</div>