Un formulario en el sitio de un equipo es HTML normal escrito en una página. No hay un constructor de formularios: el sitio lee el formulario de la propia página, valida lo que llega contra los atributos del formulario, lo guarda como registro y, si se pide, lo envía por correo. Esta guía cubre cómo escribir el formulario, cómo se valida cada campo y dónde se leen los registros.
Encender los formularios
Cada equipo enciende los formularios en Características dentro de su pantalla Configuración. Desde ese momento la pantalla Formularios del equipo queda abierta para los miembros con el permiso Formulario: Ver. El interruptor solo abre esa pantalla: un formulario escrito en una página se acepta y se guarda de todos modos.
Escribir el formulario
Envía el formulario a /form/{slug} en el sitio, con method="POST":
<form action="/form/{{ $slug }}" method="POST">
<x-recaptcha />
<label for="name">Name</label>
<input id="name" type="text" name="name" required minlength="2" maxlength="50" value="{{ old('name') }}">
<label for="email">Email</label>
<input id="email" type="email" name="email" required value="{{ old('email') }}">
<label for="topic">Topic</label>
<select id="topic" name="topic">
<option value="quote">A quote</option>
<option value="support">Support</option>
</select>
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>
No hace falta un token CSRF. La acción puede ser una ruta que empiece con / o una dirección completa como https://example.com/form/contact: solo se lee su ruta, así que el dominio que lleve no importa. Una dirección con www., como https://www.example.com/form/contact, se reenvía a la misma dirección sin www., y el envío conserva sus campos, se guarda y devuelve al visitante a la página desde la que lo envió. El formulario puede estar en el código de la página, en su bloque de encabezado o de pie, o en su layout.
El slug liga el formulario con sus registros. Si el equipo ya creó un formulario con ese slug en la pantalla Formularios, sus registros llegan ahí. Si no, el primer envío válido crea el formulario, lo nombra Formulario - seguido del título de la página y le da el slug escrito en la acción. Se crea una sola vez: cada envío posterior a esa dirección llega al mismo formulario. {{ $slug }} en la acción, como arriba y como hace la página de contacto del tema por defecto, usa el slug de la página; cualquier otro slug funciona igual, sin necesidad de crear antes el formulario.
Un envío solo se acepta desde una página del sitio, abierta en el navegador del visitante: el sitio encuentra el formulario leyendo la página de la que viene el visitante. Toma esa dirección primero de la cabecera Referer del navegador y después de la dirección anterior guardada en la sesión del visitante, y busca la página cuyo slug es exactamente esa ruta (la página con la plantilla Home para /). Un envío mandado desde cualquier otro lugar se rechaza con un error 419. Una página cuyo slug tiene un patrón, como products/{slug} o categories/products/{?slug}, nunca coincide, así que un formulario puesto en ella se rechaza de la misma forma.
Cómo se valida cada campo
Las reglas se leen del HTML del formulario, campo por campo, así que no hay nada que mantener sincronizado. Cada input, select y textarea con name es un campo.
| En el HTML | Regla que se aplica |
|---|---|
required |
Obligatorio. Sin él, el campo puede ir vacío. |
minlength o min |
Al menos esa longitud, o ese valor. Solo cuenta un número entero mayor que cero: min="0" y los valores negativos no agregan regla, y 2.5 se lee como 2. |
maxlength o max |
Como máximo esa longitud, o ese valor, con la misma lectura. |
pattern |
El valor completo coincide con el patrón, como lo revisa el navegador. |
type="email" |
Un correo válido. |
type="url" |
Una URL válida. |
type="number", type="range" |
Un número, como 42 o 3.5. Con min o max, el número se compara con ellos. |
type="date", datetime-local |
Una fecha. |
type="tel" |
Un número de teléfono, opcionalmente con código de país. |
type="color" |
Un color hexadecimal. |
type="file" |
Un archivo. |
type="radio" |
Uno de los valores de los radios con ese nombre. |
<select> |
Una de sus opciones que no esté deshabilitada. |
type="checkbox", type="hidden" |
Ninguna regla aparte de required y las longitudes. |
<textarea> |
Ninguna regla aparte de required y las longitudes. |
En un <select> o un grupo de radios, una opción cuyo valor está vacío no está entre los valores aceptados. Una opción con el valor 0 se acepta como cualquier otra.
Para escribir las reglas tú mismo, agrega data-validation con reglas de Laravel separadas por |. Reemplazan las que se leen del campo; pon inherit en cualquier lugar de la lista para sumar las tuyas a las leídas:
<input type="text" name="code" data-validation="required|alpha_num|size:6">
<input type="email" name="email" required data-validation="inherit|ends_with:@example.com">
Cuando un campo falla, el visitante vuelve a la página con los errores, y old() devuelve lo que escribió. En un formulario con reCAPTCHA, la validación se detiene en el primer campo que falla, así que solo vuelven los errores de ese campo. Cuando todos los campos pasan, vuelve con un mensaje de éxito.
Archivos y reCAPTCHA
Un campo de archivo guarda el archivo en la biblioteca del equipo, en una carpeta propia de cada formulario, Forms/{form id} dentro de su carpeta raíz, y su tamaño se suma al espacio que usa el equipo. Cuando al equipo ya no le queda espacio para el archivo, se rechaza todo el envío: no se guarda nada, no se manda el correo, y el visitante vuelve a la página con lo que escribió y, en la ventana de error del sitio, el error «Este sitio no puede recibir archivos en este momento. Intenta más tarde o comunícate con el sitio.» Consulta Team files and space en el sitio de Teams.
El cargador del sitio, <x-site-uploader name="…">, funciona como un campo del formulario: los archivos que un visitante sube con él se conservan con el registro, un campo de archivo por cada uno, en la carpeta que nombra el cargador. Su espacio se revisó cuando se subieron, así que un equipo sin espacio nunca rechaza el envío por ellos. Consulta Páginas y layouts.
Pon <x-recaptcha /> dentro del formulario y un envío que lleva un token de reCAPTCHA inválido se rechaza, y no se guarda nada. El token no es obligatorio: un envío sin él se acepta. Las claves son las del propio equipo, guardadas en sus ajustes; mientras el equipo no las guarde, <x-recaptcha /> no agrega el script que pone el token en el formulario, así que sus envíos llegan sin él y se aceptan. Consulta Configuración del sitio y visitantes.
Los ajustes del formulario
Abre un formulario en la pantalla Formularios para cambiar:
| Campo | Qué hace |
|---|---|
| Nombre | Cómo se llama el formulario en el espacio de trabajo y en el correo. |
| Slug | El {slug} de la acción. Letras minúsculas, números, -, /, { y }, hasta 100 caracteres, único dentro del equipo. Un slug con / se guarda, pero un envío a él nunca llega al formulario: /form/{slug} admite un solo segmento. |
| Acción | La ruta a la que se envía, mostrada para que la copies. |
| A correo electrónico | A dónde se envía cada registro por correo. Vacío, no se envía nada. |
| Campo de correo electrónico del remitente | El name del campo que contiene el correo del visitante, como email. Cuando contiene una dirección válida, responder al correo le contesta al visitante (Reply-To). Sin una dirección válida, la respuesta va al remitente del sitio. |
El correo siempre sale de la dirección de envío del propio sitio, nunca de la del visitante, así que los servidores de correo no lo rechazan ni lo marcan como spam. Enlista cada campo y su valor bajo el nombre del formulario, y cada archivo como su dirección en la biblioteca. El token de reCAPTCHA se deja fuera.
Leer los registros
La página de un formulario lista sus registros. Cada registro muestra cuándo llegó, la página desde la que se envió, las direcciones a las que y desde las que se envió por correo, cada campo con su valor, y las reglas que se le aplicaron. Los registros no se pueden crear ni editar desde el espacio de trabajo, solo leer y, con el permiso Entrada de formulario: Eliminar, borrar. El tipo de un campo se ve al abrir ese campo.
Las pantallas de registros y de campos no están en el menú: se llega a ellas desde un formulario.
- Abre Formularios y pulsa un formulario.
- En Entradas, abre un registro. Leer registros pide Entrada de formulario: Ver.
- En Inputs, abre un campo para ver su tipo. Leer campos pide el Ver de la fila de los campos de un registro, y un campo no se puede borrar.
Estas pantallas no miran el interruptor Formularios. Con él apagado, la pantalla de formularios rechaza todas las acciones, pero la dirección de un registro sigue abriendo para un miembro con esos permisos.

