Elementos de formulario
Resumen de los elementos estándar de los formularios.
addText(string $name, $label=null, ?int $cols=null, ?int $maxLength=null): TextInput
Añade un campo de texto de una sola línea (clase TextInput). Si el usuario no rellena el campo,
devuelve una cadena vacía '', o use setNullable() para que devuelva null en
su lugar.
$form->addText('name', 'Name:')
->setRequired()
->setNullable();
Valida automáticamente UTF-8, recorta los espacios en blanco iniciales y finales, y elimina los saltos de línea que podría enviar un atacante.
La longitud máxima se puede limitar con setMaxLength(). El método addFilter() permite modificar el valor introducido por el
usuario.
Con setHtmlType() puede cambiar el aspecto visual del campo de texto a tipos como search,
tel o url, tal como los define la especificación. Recuerde que cambiar el tipo es
puramente visual y no sustituye a la funcionalidad de validación. Para el tipo url conviene añadir una regla de validación de URL concreta.
Para otros tipos de entrada como number, range, email, date,
datetime-local, time y color, use los métodos especializados addInteger(), addFloat(), addEmail(), addDate(), addTime(), addDateTime() y addColor(), que proporcionan validación en el lado del servidor. Los tipos month y
week todavía no están plenamente soportados por todos los navegadores.
Al elemento se le puede asignar un „valor vacío“. Funciona algo parecido a un valor predeterminado, pero, si el usuario no
lo cambia, el elemento devuelve una cadena vacía o null.
$form->addText('phone', 'Phone:')
->setHtmlType('tel')
->setEmptyValue('+420');
addTextArea(string $name, $label=null): TextArea
Añade un campo de texto de varias líneas (clase TextArea). Si el usuario no rellena el campo,
devuelve una cadena vacía '', o use setNullable() para que devuelva null en
su lugar.
$form->addTextArea('note', 'Note:')
->addRule($form::MaxLength, 'Your note is way too long', 10000);
Valida automáticamente UTF-8 y normaliza los finales de línea a \n. A diferencia del campo de una sola línea,
aquí no se recortan los espacios en blanco.
La longitud máxima se puede limitar con setMaxLength(). El método addFilter() permite modificar el valor introducido por el usuario.
Se puede establecer un valor vacío con setEmptyValue().
addInteger(string $name, $label=null): TextInput
Añade un campo para introducir un número entero (clase TextInput). Devuelve un entero, o null
si el usuario no introduce nada.
$form->addInteger('year', 'Year:')
->addRule($form::Range, 'The year must be between %d and %d.', [1900, 2023]);
El elemento se renderiza como <input type="number">. Con el método setHtmlType() puede cambiar
el tipo a range para mostrarlo como un deslizador, o a text si prefiere un campo de texto normal sin el
comportamiento especial del tipo number.
addFloat(string $name, $label=null): TextInput
Añade un campo para introducir un número decimal (clase TextInput). Devuelve un float, o null
si el usuario no introduce nada.
$form->addFloat('level', 'Level:')
->setDefaultValue(0)
->addRule($form::Range, 'The level must be between %d and %d.', [0, 100]);
El elemento se renderiza como <input type="number">. Con el método setHtmlType() puede cambiar
el tipo a range para mostrarlo como un deslizador, o a text si prefiere un campo de texto normal sin el
comportamiento especial del tipo number.
Nette y el navegador Chrome aceptan como separador decimal tanto la coma como el punto. Para habilitar esta funcionalidad
también en Firefox, se recomienda establecer el atributo lang, ya sea en el elemento concreto o en toda la página,
por ejemplo <html lang="es">.
addEmail(string $name, $label=null, int $maxLength=255): TextInput
Añade un campo para introducir una dirección de correo electrónico (clase TextInput). Si el usuario no rellena el campo,
devuelve una cadena vacía '', o use setNullable() para que devuelva null en
su lugar.
$form->addEmail('email', 'E-mail:');
Valida que el valor sea una dirección de correo válida. No comprueba si el dominio existe realmente, solo verifica la sintaxis. Valida automáticamente UTF-8 y recorta los espacios en blanco iniciales y finales.
La longitud máxima se puede limitar con setMaxLength(). El método addFilter() permite modificar el valor introducido por el usuario.
Se puede establecer un valor vacío con setEmptyValue().
addPassword(string $name, $label=null, ?int $cols=null, ?int $maxLength=null): TextInput
Añade un campo para introducir una contraseña (clase TextInput).
$form->addPassword('password', 'Password:')
->setRequired()
->addRule($form::MinLength, 'Password must be at least %d characters long', 8)
->addRule($form::Pattern, 'Password must contain a number', '.*[0-9].*');
Al volver a mostrar el formulario, el campo estará vacío. Valida automáticamente UTF-8, recorta los espacios en blanco iniciales y finales, y elimina los saltos de línea que podría enviar un atacante.
addCheckbox(string $name, $caption=null): Checkbox
Añade una casilla de verificación (clase Checkbox). Devuelve true o
false, según esté marcada o no.
$form->addCheckbox('agree', 'I agree with terms')
->setRequired('You must agree with our terms');
addCheckboxList(string $name, $label=null, ?array $items=null): CheckboxList
Añade una lista de casillas de verificación para seleccionar varios elementos (clase CheckboxList). Devuelve un array con las claves
de los elementos seleccionados. El método getSelectedItems() devuelve los elementos seleccionados como pares
clave-valor.
$form->addCheckboxList('colors', 'Colors:', [
'r' => 'red',
'g' => 'green',
'b' => 'blue',
]);
El array de elementos ofrecidos se pasa como tercer parámetro o mediante el método setItems(). Si pasa
false como segundo argumento de setItems(), los valores se usan también como claves.
Use setDisabled(['r', 'g']) para deshabilitar elementos concretos.
El elemento comprueba automáticamente que no se haya producido ninguna falsificación y que los elementos seleccionados estén
realmente entre los ofrecidos y no estuvieran deshabilitados. El método getRawValue() permite obtener los elementos
enviados sin esta importante comprobación.
Al establecer los elementos seleccionados de forma predeterminada también comprueba que estén entre los ofrecidos; de lo
contrario lanza una excepción. Esta comprobación se puede desactivar con checkDefaultValue(false).
Si envía el formulario con el método GET, puede elegir una forma más compacta de transferir los datos que
ahorra tamaño en la cadena de consulta. Se activa estableciendo un atributo HTML en el formulario:
$form->setHtmlAttribute('data-nette-compact');
addRadioList(string $name, $label=null, ?array $items=null): RadioList
Añade botones de opción (clase RadioList).
Devuelve la clave del elemento seleccionado, o null si el usuario no seleccionó nada. El método
getSelectedItem() devuelve el valor en lugar de la clave.
$sex = [
'm' => 'male',
'f' => 'female',
'o' => 'other',
];
$form->addRadioList('gender', 'Gender:', $sex);
El array de elementos ofrecidos se pasa como tercer parámetro o mediante el método setItems().
Use setDisabled(['m']) para deshabilitar elementos concretos.
El elemento comprueba automáticamente que no se haya producido ninguna falsificación y que el elemento seleccionado esté
realmente entre los ofrecidos y no estuviera deshabilitado. El método getRawValue() permite obtener el elemento
enviado sin esta importante comprobación.
Al establecer el elemento seleccionado de forma predeterminada también comprueba que esté entre los ofrecidos; de lo
contrario lanza una excepción. Esta comprobación se puede desactivar con checkDefaultValue(false).
addSelect(string $name, $label=null, ?array $items=null, ?int $size=null): SelectBox
Añade una lista desplegable (clase SelectBox). Devuelve la clave del elemento
seleccionado, o null si el usuario no seleccionó nada. El método getSelectedItem() devuelve el valor
en lugar de la clave.
$countries = [
'CZ' => 'Czech Republic',
'SK' => 'Slovakia',
'GB' => 'United Kingdom',
];
$form->addSelect('country', 'Country:', $countries)
->setDefaultValue('SK');
El array de elementos ofrecidos se pasa como tercer parámetro o mediante el método setItems(). Los elementos
también pueden ser un array bidimensional (que representa optgroups):
$countries = [
'Europe' => [
'CZ' => 'Czech Republic',
'SK' => 'Slovakia',
'GB' => 'United Kingdom',
],
'CA' => 'Canada',
'US' => 'USA',
'?' => 'other',
];
En las listas desplegables, el primer elemento suele tener un significado especial y sirve de invitación a la acción. Use el
método setPrompt() para añadir un elemento así.
$form->addSelect('country', 'Country:', $countries)
->setPrompt('Choose a country');
Use setDisabled(['CZ', 'SK']) para deshabilitar elementos concretos.
El elemento comprueba automáticamente que no se haya producido ninguna falsificación y que el elemento seleccionado esté
realmente entre los ofrecidos y no estuviera deshabilitado. El método getRawValue() permite obtener el elemento
enviado sin esta importante comprobación.
Al establecer el elemento seleccionado de forma predeterminada también comprueba que esté entre los ofrecidos; de lo
contrario lanza una excepción. Esta comprobación se puede desactivar con checkDefaultValue(false).
addMultiSelect(string $name, $label=null, ?array $items=null, ?int $size=null): MultiSelectBox
Añade una lista desplegable para seleccionar varios elementos (clase MultiSelectBox). Devuelve un array con las
claves de los elementos seleccionados. El método getSelectedItems() devuelve los elementos seleccionados como pares
clave-valor.
$form->addMultiSelect('countries', 'Countries:', $countries);
El array de elementos ofrecidos se pasa como tercer parámetro o mediante el método setItems(). Los elementos
también pueden ser un array bidimensional.
Use setDisabled(['CZ', 'SK']) para deshabilitar elementos concretos.
El elemento comprueba automáticamente que no se haya producido ninguna falsificación y que los elementos seleccionados estén
realmente entre los ofrecidos y no estuvieran deshabilitados. El método getRawValue() permite obtener los elementos
enviados sin esta importante comprobación.
Al establecer los elementos seleccionados de forma predeterminada también comprueba que estén entre los ofrecidos; de lo
contrario lanza una excepción. Esta comprobación se puede desactivar con checkDefaultValue(false).
addUpload(string $name, $label=null): UploadControl
Añade un campo para subir un archivo (clase UploadControl). Devuelve un objeto FileUpload incluso si el usuario no subió ningún archivo, lo que se puede comprobar con el
método FileUpload::hasFile(). Con setNullable() puede hacer que el elemento devuelva null
en lugar de un objeto FileUpload cuando no se sube ningún archivo.
$form->addUpload('avatar', 'Avatar:')
->addRule($form::Image, 'Avatar must be JPEG, PNG, GIF, WebP or AVIF.')
->addRule($form::MaxFileSize, 'Maximum size is 1 MB.', 1024 * 1024);
Si el archivo no se sube correctamente, el formulario no se envía con éxito y se muestra un error. Es decir, tras un envío
correcto no hace falta comprobar el método FileUpload::isOk().
Nunca confíe en el nombre original del archivo que devuelve el método FileUpload::getName(); el cliente pudo
haber enviado un nombre de archivo malicioso con la intención de dañar o hackear su aplicación.
Las reglas MimeType e Image detectan el tipo requerido a partir de la firma del archivo y no
verifican su integridad. Que una imagen esté dañada se puede averiguar, por ejemplo, intentando cargarla.
addMultiUpload(string $name, $label=null): UploadControl
Añade un campo para subir varios archivos a la vez (clase UploadControl). Devuelve un array de objetos FileUpload. El método FileUpload::hasFile() devolverá true para
cada uno de ellos.
$form->addMultiUpload('files', 'Files:')
->addRule($form::MaxLength, 'Maximum of %d files can be uploaded.', 10);
Si alguno de los archivos no se sube correctamente, el formulario no se envía con éxito y se muestra un error. Es decir, tras
un envío correcto no hace falta comprobar el método FileUpload::isOk() para cada archivo.
Nunca confíe en los nombres originales de los archivos que devuelve el método FileUpload::getName(); el cliente
pudo haber enviado nombres de archivo maliciosos con la intención de dañar o hackear su aplicación.
Las reglas MimeType e Image detectan el tipo requerido a partir de la firma del archivo y no
verifican su integridad. Que una imagen esté dañada se puede averiguar, por ejemplo, intentando cargarla.
addDate(string $name, $label=null): DateTimeControl
Añade un campo que permite al usuario introducir cómodamente una fecha compuesta por año, mes y día (clase DateTimeControl).
Como valor predeterminado acepta objetos que implementan DateTimeInterface, una cadena con la hora o un número
que representa una marca de tiempo UNIX. Lo mismo vale para los argumentos de las reglas Min, Max o
Range, que definen la fecha mínima y máxima permitidas.
$form->addDate('date', 'Date:')
->setDefaultValue(new DateTime)
->addRule($form::Min, 'The date must be at least one month old.', new DateTime('-1 month'));
De forma predeterminada devuelve un objeto DateTimeImmutable. Con el método setFormat() puede
indicar un formato de texto
o una marca de tiempo:
$form->addDate('date', 'Date:')
->setFormat('Y-m-d');
addTime(string $name, $label=null, bool $withSeconds=false): DateTimeControl
Añade un campo que permite al usuario introducir cómodamente una hora compuesta por horas, minutos y, opcionalmente, segundos (clase DateTimeControl).
Como valor predeterminado acepta objetos que implementan DateTimeInterface, una cadena con la hora o un número
que representa una marca de tiempo UNIX. De estas entradas solo se usa la información de la hora; la fecha se ignora. Lo mismo
vale para los argumentos de las reglas Min, Max o Range, que definen la hora mínima y
máxima permitidas. Si el valor mínimo establecido es mayor que el máximo, se crea un rango horario que cruza la medianoche.
$form->addTime('time', 'Time:', withSeconds: true)
->addRule($form::Range, 'Time must be between %d and %d.', ['12:30', '13:30']);
De forma predeterminada devuelve un objeto DateTimeImmutable (con la fecha fijada al 1 de enero del año 1). Con
el método setFormat() puede indicar un formato de texto:
$form->addTime('time', 'Time:')
->setFormat('H:i');
addDateTime(string $name, $label=null, bool $withSeconds=false): DateTimeControl
Añade un campo que permite al usuario introducir cómodamente la fecha y la hora a la vez, compuestas por año, mes, día, horas, minutos y, opcionalmente, segundos (clase DateTimeControl).
Como valor predeterminado acepta objetos que implementan DateTimeInterface, una cadena con la hora o un número
que representa una marca de tiempo UNIX. Lo mismo vale para los argumentos de las reglas Min, Max o
Range, que definen la fecha y la hora mínimas y máximas permitidas.
$form->addDateTime('datetime', 'Date and Time:')
->setDefaultValue(new DateTime)
->addRule($form::Min, 'The date must be at least one month old.', new DateTime('-1 month'));
De forma predeterminada devuelve un objeto DateTimeImmutable. Con el método setFormat() puede
indicar un formato de texto
o una marca de tiempo:
$form->addDateTime('datetime')
->setFormat(DateTimeControl::FormatTimestamp);
addColor(string $name, $label=null): ColorPicker
Añade un campo para elegir un color (clase ColorPicker). El color se devuelve como una
cadena con el formato #rrggbb. Si el usuario no elige nada, devuelve el negro #000000.
$form->addColor('color', 'Color:')
->setDefaultValue('#3C8ED7');
addHidden(string $name, mixed $default=null): HiddenField
Añade un campo oculto (clase HiddenField).
$form->addHidden('userid');
Use setNullable() para que devuelva null en lugar de una cadena vacía. El método addFilter() permite modificar el valor enviado.
Aunque el elemento esté oculto, es importante darse cuenta de que un atacante puede modificar o falsificar su valor. Verifique y valide siempre a fondo todos los valores recibidos en el lado del servidor para evitar los riesgos de seguridad asociados a la manipulación de datos.
addSubmit(string $name, $caption=null): SubmitButton
Añade un botón de envío (clase SubmitButton).
$form->addSubmit('submit', 'Submit');
El manejador se puede pasar directamente al botón como tercer parámetro $onSubmit en lugar
de engancharlo al evento onClick:
$form->addSubmit('submit', 'Submit', function (SubmitButton $button, $data): void {
// ...
});
En un formulario puede haber más de un botón de envío:
$form->addSubmit('register', 'Register');
$form->addSubmit('cancel', 'Cancel');
Para averiguar cuál se pulsó, use:
if ($form['register']->isSubmittedBy()) {
// ...
}
Si no quiere validar todo el formulario al pulsar un botón (por ejemplo, en los botones Cancelar o Vista previa), use setValidationScope().
addButton(string $name, $caption=null): Button
Añade un botón (clase Button) que no tiene función de envío. Por tanto se puede usar para otras funciones, p. ej. para llamar a una función de JavaScript al pulsarlo.
$form->addButton('raise', 'Raise salary')
->setHtmlAttribute('onclick', 'raiseSalary()');
addImageButton(string $name, ?string $src=null, ?string $alt=null): ImageButton
Añade un botón de envío en forma de imagen (clase ImageButton).
$form->addImageButton('submit', '/path/to/image.png', 'Submit');
Cuando use varios botones de envío, puede averiguar cuál se pulsó con $form['submit']->isSubmittedBy().
addContainer(string|int $name): Container
Añade un subformulario (clase Container),
o contenedor, al que se pueden añadir otros elementos igual que se añaden al formulario. También funcionan métodos como
setDefaults() o getValues().
$sub1 = $form->addContainer('first');
$sub1->addText('name', 'Your name:');
$sub1->addEmail('email', 'Email:');
$sub2 = $form->addContainer('second');
$sub2->addText('name', 'Your name:');
$sub2->addEmail('email', 'Email:');
Los datos enviados se devuelven después como una estructura multidimensional:
[
'first' => [
'name' => /* ... */,
'email' => /* ... */,
],
'second' => [
'name' => /* ... */,
'email' => /* ... */,
],
]
Resumen de la configuración
En todos los elementos podemos llamar a los siguientes métodos (vea la documentación de la API para un resumen completo):
setDefaultValue($value) |
establece el valor predeterminado |
getValue() |
obtiene el valor actual |
setOmitted() |
Valores omitidos |
setDisabled() |
Deshabilitar elementos |
Renderizado:
setCaption($caption) |
cambia la etiqueta del elemento |
setTranslator($translator) |
establece el traductor |
setHtmlAttribute($name, $value) |
establece un atributo HTML del elemento |
setHtmlId($id) |
establece el atributo HTML id |
setOption($key, $value) |
establece opciones de renderizado |
Validación:
setRequired() |
marca el elemento como obligatorio |
addRule() |
añade una regla de validación |
addCondition(), addConditionOn() |
establece una condición de validación |
addError($message) |
añade un mensaje de error |
En los elementos addText(), addPassword(), addTextArea(), addEmail(),
addInteger(), addFloat() se pueden llamar los siguientes métodos:
setNullable() |
establece si getValue() devuelve null en lugar de una cadena vacía |
setEmptyValue($value) |
establece un valor especial que se considera una cadena vacía |
setMaxLength($length) |
establece el número máximo de caracteres permitido |
addFilter($filter) |
modifica la entrada |
Valores omitidos
Si el valor que rellena el usuario no nos interesa, podemos usar setOmitted() para excluirlo del resultado del
método $form->getValues() o de los datos que se pasan a los manejadores. Es útil para los distintos campos de
confirmación de contraseña, elementos antispam, etc.
$form->addPassword('passwordVerify', 'Password again:')
->setRequired('Fill your password again to check for typo')
->addRule($form::Equal, 'Passwords do not match', $form['password'])
->setOmitted();
Deshabilitar elementos
Los elementos se pueden deshabilitar con setDisabled(). Un elemento deshabilitado no puede ser editado por el
usuario.
$form->addText('username', 'User name:')
->setDisabled();
Los elementos deshabilitados no los envía el navegador al servidor en absoluto, así que no los encontrará en los datos que
devuelve la función $form->getValues(). Pero, si establece setOmitted(false), Nette incluirá su
valor predeterminado en esos datos.
Al llamar a setDisabled(), el valor del elemento se borra por motivos de seguridad. Si está estableciendo
un valor predeterminado, hay que hacerlo después de deshabilitarlo:
$form->addText('username', 'User name:')
->setDisabled()
->setDefaultValue($userName);
Una alternativa a los elementos deshabilitados son los elementos con el atributo HTML readonly, que el navegador
sí envía al servidor. Aunque el elemento sea de solo lectura, es importante darse cuenta de que un atacante puede
modificar o falsificar su valor.
Elementos personalizados
Además de la amplia oferta de elementos de formulario integrados, puede añadir al formulario elementos propios:
$form->addComponent(new DateInput('Date:'), 'date');
// sintaxis alternativa: $form['date'] = new DateInput('Date:');
Cómo escribir un elemento así, incluyendo la lectura de los datos enviados, la validación y el renderizado, se describe en
un capítulo aparte. Allí conocerá también los métodos de extensión, que le permiten crear
su propio método de adición como $form->addZip().
Elementos de bajo nivel
También es posible usar elementos que solo se escriben en la plantilla y no se añaden al formulario con ninguno de los
métodos $form->addXyz(). Por ejemplo, cuando listamos registros de la base de datos y no sabemos de antemano
cuántos habrá ni cuáles serán sus ID, y queremos mostrar una casilla de verificación o un botón de opción por cada fila,
basta con escribirlo en la plantilla:
{foreach $items as $item}
<p><input type=checkbox name="sel[]" value={$item->id}> {$item->name}</p>
{/foreach}
Y tras el envío obtenemos el valor:
$data = $form->getHttpData($form::DataText, 'sel[]');
$data = $form->getHttpData($form::DataText | $form::DataKeys, 'sel[]');
donde el primer parámetro es el tipo de elemento (DataFile para type=file, DataLine
para las entradas de una sola línea como text, password, email, etc., y
DataText para todas las demás) y el segundo parámetro sel[] corresponde al atributo HTML name. Podemos
combinar el tipo de elemento con el valor DataKeys, que conserva las claves de los elementos. Eso resulta
especialmente útil para select, radioList y checkboxList.
Lo esencial es que getHttpData() devuelve un valor saneado. En este caso siempre será un array de cadenas
UTF-8 válidas, independientemente de lo que un atacante intente enviar al servidor. Es análogo a trabajar directamente con
$_POST o $_GET, pero con la diferencia sustancial de que siempre devuelve datos limpios, tal como está
acostumbrado con los elementos de formulario estándar de Nette.