En Firefox y Chrome, no se envían los campos de formulario creados dinámicamente con AJAX

A lo largo de su vida, un desarrollador se encuentra a veces con problemas muy poco comunes y, normalmente, encontrar la solución se convierte en un largo y tortuoso camino.

El problema que trata este post es de uno de esos casos de comportamientos “raros” entre distintos navegadores. El escenario sería el siguiente:

Tenemos una página PHP en la que tenemos un formulario HTML, cuyos campos son creados dinámicamente utilizando una función AJAX. El HTML resultante tendría un aspecto similar a este:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />
<title>Test</title>
</head>

<body>
<table>
<form action=”test.html”>
<tr>
<td>
<fieldset>
<input type=”text” name=”nombre1″ id=”id1″ />
<input type=”text” name=”nombre2″ id=”id2″ />
</fieldset>
</td>
</tr>
</form>
</table>
</body>

</html>

Donde los elementos input son creados por AJAX. Hasta ahí todo perfecto, pero si hacemos un submit del formulario vemos que sólo en Internet Explorer se pasan los valores. En Chrome y en Firefox es como si esos “inputs” no existieran.

Después de mucho comprobar el funcionamiento de nuestra función AJAX o del PHP, observaríamos que todo está correcto, pero seguimos sin poder recuperar los valores tras enviar el formulario.

Sin embargo… el problema se encuentra en el HTML, concretamente en el orden de las etiquetas. Dependiendo del doctype que tengáis definido en vuestro documento, se ha de formar un HTML que sea estándar para ese doctype.

Para comprobar si nuestro HTML cumple los estándares, podemos utilizar la herramienta de validación online que nos proporciona w3.org. Por el contrario, si aún no tenemos nuestra página online, podemos usar alguna de las extensiones que tenemos disponibles para Firefox o Chrome. Por ejemplo, la validación en local es una de las herramientas que ofrece la extensión Web Developer para Firefox.

Si usamos alguna de estas herramientas para validar nuestro código obtenemos el siguiente error:

Line 10, Column 33: document type does not allow element “form” here

Lo que significa que según los estándares no podemos colocar la etiqueta form donde la tenemos puesta. Si simplemente cambiamos el HTML y hacemos que el formulario englobe a la tabla, nos queda algo como esto:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />
<title>Test</title>
</head>

<body>
<form action=”test.html”>
<table>
<tr>
<td>
<fieldset>
<input type=”text” name=”nombre1″ id=”id1″ />
<input type=”text” name=”nombre2″ id=”id2″ />
</fieldset>
</td>
</tr>
</table>
</form>
</body>

</html>

Si ahora pasamos el validador, obtendremos el feliz mensaje de:

This document was successfully checked as XHTML 1.0 Strict!

Lo cual quiere decir que nuestro HTML sigue los estándares. Pero no sólo hemos logrado que sea estándar, si no que si ahora mandamos el formulario… ¡sorpresa! en Firefox y en Chrome ahora sí que se envían los datos. Por tanto, el problema no estaba en la parte compleja (AJAX o PHP) de nuestro desarrollo, si no en lo que, aparentemente, es más sencillo y teníamos totalmente controlado: el HTML.

En conclusión, seguir unos patrones y mantener nuestro código estándar nos puede ahorrar más de un disgusto y horas de búsqueda y desesperación. Este tipo de errores “raros” son los peores, porque parece que no hay sentido para que se produzcan.

Lo que, en principio, parecía un complejo problema de AJAX, ha resultado ser un sencillo problema de estándares HTML, y, en este caso,  seguirlos ha sido suficiente para solucionarlo. Quizá no siempre sea posible cumplirlos a rajatabla, pero lo mejor es hacerlo siempre que esté en nuestra mano.

Esperamos que con esta entrada podáis tachar este error de vuestra lista de errores “raros” con distintos navegadores.