Los formularios y controles, como <input>, tienen muchos eventos y propiedades especiales.
Trabajar con formularios será mucho más conveniente cuando los aprendamos.
Navegación: Formularios y elementos
Los formularios del documento son miembros de la colección especial document.forms.
Esa es la llamada âColección nombradaâ: es ambas cosas, nombrada y ordenada. Podemos usar el nombre o el número en el documento para conseguir el formulario.
document.forms.my; // el formulario con name="my"
document.forms[0]; // el primer formulario en el documento
Cuando tenemos un formulario, cualquier elemento se encuentra disponible en la colección nombrada form.elements.
Por ejemplo:
<form name="my">
<input name="one" value="1">
<input name="two" value="2">
</form>
<script>
// obtención del formulario
let form = document.forms.my; // elemento <form name="my">
// get the element
let elem = form.elements.one; // elemento <input name="one">
alert(elem.value); // 1
</script>
Puede haber múltiples elementos con el mismo nombre. Esto es tÃpico en el caso de los botones de radio y checkboxes.
En ese caso form.elements[name] es una colección. Por ejemplo:
<form>
<input type="radio" name="age" value="10">
<input type="radio" name="age" value="20">
</form>
<script>
let form = document.forms[0];
let ageElems = form.elements.age;
alert(ageElems[0]); // [object HTMLInputElement]
</script>
Estas propiedades de navegación no dependen de la estructura de las etiquetas. Todos los controles, sin importar qué tan profundos se encuentren en el formulario, están disponibles en form.elements.
Un formulario puede tener uno o varios elementos <fieldset> dentro. Estos también tienen la propiedad elements que lista los controles del formulario dentro de ellos.
Por ejemplo:
<body>
<form id="form">
<fieldset name="userFields">
<legend>info</legend>
<input name="login" type="text">
</fieldset>
</form>
<script>
alert(form.elements.login); // <input name="login">
let fieldset = form.elements.userFields;
alert(fieldset); // HTMLFieldSetElement
// podemos obtener el input por su nombre tanto desde el formulario como desde el fieldset
alert(fieldset.elements.login == form.elements.login); // true
</script>
</body>
form.nameHay una notación corta: podemos acceder el elemento como form[index/name].
En otras palabras, en lugar de form.elements.login podemos escribir form.login.
Esto también funciona, pero tiene un error menor: si accedemos un elemento, y cambiamos su name, se mantendrá disponible mediante el nombre anterior (asà como mediante el nuevo).
Esto es fácil de ver en un ejemplo:
<form id="form">
<input name="login">
</form>
<script>
alert(form.elements.login == form.login); // true, el mismo <input>
form.login.name = "username"; // cambiamos el nombre el <input>
// form.elements actualiza el nombre:
alert(form.elements.login); // undefined
alert(form.elements.username); // input
// form permite ambos nombres: el nuevo y el viejo
alert(form.username == form.login); // true
</script>
Esto usualmente no es un problema, porque raramente se cambian los nombres de los elementos de un formulario.
Referencia inversa: element.form
Para cualquier elemento, el formulario está disponible como element.form. Asà que un formulario referencia todos los elementos, y los elementos referencian el formulario.
Aquà la imagen:
Por ejemplo:
<form id="form">
<input type="text" name="login">
</form>
<script>
// form -> element
let login = form.login;
// element -> form
alert(login.form); // HTMLFormElement
</script>
Elementos del formulario
Hablemos de los controles de los formularios.
input y textarea
Podemos acceder sus valores como input.value (cadena) o input.checked (booleano) para casillas de verificación (checkboxes) y botones de opción (radio buttons).
De esta manera:
input.value = "New value";
textarea.value = "New text";
input.checked = true; // para checkboxes o radios
textarea.value, no textarea.innerHTMLObserva que incluso aunque <textarea>...</textarea> contenga su valor como HTML anidado, nunca deberÃamos usar textarea.innerHTML para acceder a él.
Esto solo guarda el HTML que habÃa inicialmente en la página, no su valor actual.
select y option
Un elemento <select> tiene 3 propiedades importantes:
select.optionsâ la colección de subelementos<option>,select.valueâ el valor del<option>seleccionado actualmente, yselect.selectedIndexâ el número del<option>seleccionado actualmente.
Ellas proveen tres formas diferentes de asignar un valor para un elemento <select>:
- Encontrar el elemento
<option>correspondiente (por ejemplo entreselect.options) y asignar a suoption.selecteduntrue. - Si conocemos un nuevo valor: Asignar tal valor a
select.value. - Si conocemos el nuevo número de opción: Asignar tal número a
select.selectedIndex.
Aquà hay un ejemplo de los tres métodos:
<select id="select">
<option value="apple">Apple</option>
<option value="pear">Pear</option>
<option value="banana">Banana</option>
</select>
<script>
// las tres lÃneas hacen lo mismo
select.options[2].selected = true;
select.selectedIndex = 2;
select.value = 'banana';
// Recuerda que las opciones comienzan en cero, asà que index 2 significa la tercera opción.
</script>
A diferencia de la mayorÃa de controles, <select> permite seleccionar múltiples opciones a la vez si tiene el atributo multiple. Esta caracterÃstica es raramente utilizada.
En ese caso, necesitamos usar la primera forma: Añade/elimina la propiedad selected de los subelementos <option>.
Podemos obtener su colección como select.options, por ejemplo:
<select id="select" multiple>
<option value="blues" selected>Blues</option>
<option value="rock" selected>Rock</option>
<option value="classic">Classic</option>
</select>
<script>
// obtener todos los valores seleccionados del multi-select
let selected = Array.from(select.options)
.filter(option => option.selected)
.map(option => option.value);
alert(selected); // blues,rock
</script>
La especificación completa del elemento <select> está disponible en la especificación https://html.spec.whatwg.org/multipage/forms.html#the-select-element.
new Option
En la especificación hay una sintaxis muy corta para crear elementos <option>:
option = new Option(text, value, defaultSelected, selected);
Esta sintaxis es opcional. Podemos usar document.createElement('option') y asignar atributos manualmente. Aún puede ser más corta, aquà los parámetros:
textâ el texto dentro del option,valueâ el valor del option,defaultSelectedâ si estrue, entonces se le crea el atributo HTMLselected,selectedâ si estrue, el option se selecciona.
La diferencia entre defaultSelected y selected es que defaultSelected define si el atributo HTML (el que obtenemos con option.getAttribute('selected')), mientras que selected define si el option está seleccionado o no en el DOM.
En la práctica, uno deberÃa usualmente establecer ambos valores en true o false. O simplemente omitirlos, quedarán con el predeterminado false.
Por ejemplo, aquà creamos un nuevo Option âunselectedâ:
let option = new Option("Text", "value");
// crea <option value="value">Text</option>
El mismo elemento, pero seleccionado:
let option = new Option("Text", "value", true, true);
Los elementos Option tienen propiedades:
option.selected- Es el option seleccionado.
option.index- El número del option respecto a los demás en su
<select>. option.text- El contenido del option (visto por el visitante).
Referencias
- Especificación: https://html.spec.whatwg.org/multipage/forms.html.
Resumen
Navegación de formularios:
document.forms- Un formulario está disponible como
document.forms[name/index]. form.elements- Los elementos del formulario están disponibles como
form.elements[name/index], o puedes usar soloform[name/index]. La propiedadelementstambién funciona para los<fieldset>. element.form- Los elementos referencian a su formulario en la propiedad
form.
El valor está disponible con input.value, textarea.value, select.value etc. Para checkboxes y radios, usa input.checked para determinar si el valor está seleccionado.
Para <select> también podemos obtener el valor con el Ãndice select.selectedIndex o a través de la colección de opciones select.options.
Esto es lo básico para empezar a trabajar con formularios. Conoceremos muchos ejemplos más adelante en el tutorial.
En el siguiente capÃtulo vamos a hablar sobre los eventos focus y blur que pueden ocurrir en cualquier elemento, pero son manejados mayormente en formularios.
Comentarios
<code>, para varias lÃneas â envolverlas en la etiqueta<pre>, para más de 10 lÃneas â utilice una entorno controlado (sandbox) (plnkr, jsbin, codepenâ¦)