Procesar formulario con Ajax y PHP con validación

  • Por
  • Ajax
Complicamos un poco el envío y procesamiento de un formulario con Ajax y PHP, para realizar validaciones en el servidor y mostrar mensajes de error si la validación falló.
Estuvimos haciendo en un artículo anterior una página que envía un formulario con PHP y Ajax y lo procesa, devolviendo los resultados sin que se tenga que recargar la página. Ahora vamos a complicar ese ejemplo, creando un formulario que tiene distintas validaciones en el servidor. El formulario no se procesa hasta que no se valide correctamente la información y se muestran los posibles errores dentro de la propia página.

Hay un artículo publicado anteriormente que habría que leer para poder entender este nuevo ejemplo: Recibir y procesar formulario con Ajax y PHP.

Veamos antes, si se desea, el resultado buscado en este ejemplo.

El formulario y la zona de mensajes

El formulario que hemos utilizado es muy parecido al anterior. Sólo le hemos añadido un campo más, de tipo checkbox, para realizar una validación un poco más compleja. Además, hemos incorporado una capa más para mostrar mensajes.

<div id="mensaje">
Rellena los datos de este formulario y pulsa "Enviar"
</div>
<br />
<div id="capaformulario">
<form id="formulario">
Nombre: <input type="text" name="nombre" />
<br />
Apellidos: <input type="text" name="apellidos" />
<br />
<input type="checkbox" name="acepto" value="1" /> Acepto los términos y condiciones ;)
<br />
<input type="button" value="Enviar" onclick="xajax_procesar_formulario(xajax.getFormValues('formulario'))" />
</form>
</div>


La capa de mensajes nos servirá para mostrar textos, como errores de validación, cuando se produzcan. El formulario está en una capa independiente, que sólo actualizaremos si finalmente se realiza el procesamiento de sus datos.

Ahora veamos la función PHP que realizará la validación. Si se produjeron errores en la validación actualizará la capa "mensaje" para mostrar el error. Si todo es correcto, procesará el formulario, mostrará un mensaje de confirmación en la capa "mensaje" y el resultado de procesar el formulario en la capa "capaformulario". Es una función un poco larga:

function procesar_formulario($form_entrada){
   //creo el xajaxResponse para generar una salida
   $respuesta = new xajaxResponse('ISO-8859-1');

   //validación
   $error_form = "";
   if ($form_entrada["nombre"] == "")
      $error_form = "Debes escribir tu nombre";
   elseif ($form_entrada["apellidos"] == "")
      $error_form = "Debes escribir tus apellidos";
   elseif (!isset($form_entrada["acepto"]))
      $error_form = "Debes aceptar los términos y condiciones";
      
   //compruebo resultado de la validación
   if ($error_form != ""){
      //Hubo un error en el formulario
      //en la capa donde se muestran mensajes, muestro el error
      $respuesta->addAssign("mensaje","innerHTML","<span style='color:red;'>$error_form</span>");
   }else{
      //es que no hubo error en el formulario
      $salida = "Hemos procesado esto:<p>";
      $salida .= "Nombre: " . $form_entrada["nombre"];
      $salida .= "<br>Apellidos: " . $form_entrada["apellidos"];
      
      //mostramos en capa mensaje el texto que está todo correcto
      $respuesta->addAssign("mensaje","innerHTML","<span style='color:blue;'>Todo correcto... Muchas gracias!</span>");
      //escribimos en la capa con id="capaformulario" el texto que aparece en $salida
      $respuesta->addAssign("capaformulario","innerHTML",$salida);
      
      //tenemos que devolver la instanciación del objeto xajaxResponse
   }
   return $respuesta;
}

La función está comentada, por lo que se podrá entender. Lo importante es fijarse en cómo se instancia el objeto de la clase xajaxResponse y cómo se invocan los distintos métodos para actualizar el contenido de las capas "mensaje" y "capaformulario".

Luego está el tema de las validaciones y la comprobación para saber si hubo un error o no en los datos. Este podría servir de esquema general, pero tema de las validaciones cada persona lo tendrá que implementar según sus necesidades.

Solución para los acentos en xajax

También vamos a ver un par de detalles acerca de los acentos en Ajax, que nos resolverán más de un dolor de cabeza. Posiblemente hayamos podido comprobar en este ejemplo, o en otros anteriores de Ajax, que los acentos muchas veces se ven mal, convertidos en algún carácter raro. Esto lo podemos solucionar de varias maneras con xajax, y nosotros hemos implementado una de ellas en este ejemplo.

Primero, cuando se crea la instancia del objeto xajax, podemos decirle con qué juego de caracteres queremos trabajar. Y además, podemos decirle que cualquier cadena que nos envíen por POST o GET se convierta automáticamente al juego de caracteres que estamos usando.

//instanciamos el objeto de la clase xajax
$xajax = new xajax();
$xajax->setCharEncoding('ISO-8859-1');
$xajax->decodeUTF8InputOn()

Luego, cuando hacemos las instancias del objeto de la clase xajaxResponse para generar la salida, también tenemos que indicar en qué juego de caracteres estamos trabajando, si no podría dar problemas.

$respuesta = new xajaxResponse('ISO-8859-1');

Esto se hace en la función PHP que procesa los datos y genera la salida. Ya habíamos visto anteriormente el código de esta función.

Así quedaría el código completo de este ejemplo:

<?
//incluímos la clase ajax
require ('xajax/xajax.inc.php');

//instanciamos el objeto de la clase xajax
$xajax = new xajax();
$xajax->setCharEncoding('ISO-8859-1');
$xajax->decodeUTF8InputOn();

function procesar_formulario($form_entrada){
   //creo el xajaxResponse para generar una salida
   $respuesta = new xajaxResponse('ISO-8859-1');

   //validación
   $error_form = "";
   if ($form_entrada["nombre"] == "")
      $error_form = "Debes escribir tu nombre";
   elseif ($form_entrada["apellidos"] == "")
      $error_form = "Debes escribir tus apellidos";
   elseif (!isset($form_entrada["acepto"]))
      $error_form = "Debes aceptar los términos y condiciones";
      
   //compruebo resultado de la validación
   if ($error_form != ""){
      //Hubo un error en el formulario
      //en la capa donde se muestran mensajes, muestro el error
      $respuesta->addAssign("mensaje","innerHTML","<span style='color:red;'>$error_form</span>");
   }else{
      //es que no hubo error en el formulario
      $salida = "Hemos procesado esto:<p>";
      $salida .= "Nombre: " . $form_entrada["nombre"];
      $salida .= "<br>Apellidos: " . $form_entrada["apellidos"];
      
      //mostramos en capa mensaje el texto que está todo correcto
      $respuesta->addAssign("mensaje","innerHTML","<span style='color:blue;'>Todo correcto... Muchas gracias!</span>");
      //escribimos en la capa con id="capaformulario" el texto que aparece en $salida
      $respuesta->addAssign("capaformulario","innerHTML",$salida);
      
      //tenemos que devolver la instanciación del objeto xajaxResponse
   }
   return $respuesta;
}
//registramos la función creada anteriormente al objeto xajax
$xajax->registerFunction("procesar_formulario");

//El objeto xajax tiene que procesar cualquier petición
$xajax->processRequests();
?>
<html>
<head>

   <title>Enviar y procesar un formulario con Ajax y PHP</title>
   <?
   //En el <head> indicamos al objeto xajax se encargue de generar el javascript necesario
   $xajax->printJavascript("xajax/");
   ?>
</head>

<body>
<h1>Recibir y procesar formulario con Ajax y PHP</h1>
<div id="mensaje">
Rellena los datos de este formulario y pulsa "Enviar"
</div>
<br />
<div id="capaformulario">
<form id="formulario">
Nombre: <input type="text" name="nombre" />
<br />
Apellidos: <input type="text" name="apellidos" />
<br />
<input type="checkbox" name="acepto" value="1" /> Acepto los términos y condiciones ;)
<br />
<input type="button" value="Enviar" onclick="xajax_procesar_formulario(xajax.getFormValues('formulario'))" />
</form>
</div>

</body>
</html>


Podemos ver el resultado final de este ejercicio.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

jatuma

07/6/2007
A mi no me ha ido bien hasta que he corregido 1 error de la librería xajax 0.2.5, que es la que se puede descargar actualmente(06.06.2007) y es concretamente en la línea 747:
"if (is_string($sResponse)) {"
debería poner:
"if (is_string($oResponse)) {"
corrigiendo esto, va perfectamente.

webmastertgp

11/6/2007
Utilizar ajax es muy bueno por que evita estar recargando la pagina, lo que no he encontrado es como regresar a la parte inicial antes de ejecutarse el ajax.
Por ejemplo en el ejercio del procesamiento del formulario, como regresar al formulario con el boton regresar o con un click del mouse sin recargar toda la pagina.

lygala

23/7/2007
Hola!!
Tengo la siguiente pregunta cuando escribo la siguiente linea para el tratamiento de los acentos :$xajax->decodeUTF8InputOn(); me sale el siguiente error:

Fatal error: Call to undefined function: decodeutf8inputon() in ....ejemplos ildes.php on line 10

Solo realice un copy+paste del ejemplo y cuando coloco la linea en comentarios /* $xajax->decodeUTF8InputOn();*/funciona el ejemplo pero continua el problema de los acentos pues aparecen simbolos raros

Gracias

rodrigo solorzano pardo

18/1/2008

OJO IMPORTANTE APORTE!! PARA EVITAR DOLORES DE CABEZA

Excelente! funciona para XAJAX VERSION 0.2!! pero.........

En la version XAJAX 0.5 BETA 4 saca errores!, por lo tanto hay que hacer unas pequeñas modificaciones!!

Ej:
En vez de:
$xajax->decodeUTF8InputOn();

Se deb colocar:
$xajax->configure('decodeUTF8Input',true)

Para los demas bugs ve a la siguiente direccion:

Upgrading from xajax 0.2 to xajax 0.5
http://xajaxproject.org/wiki/Upgrading_from_xajax_0.2_to_xajax_0.5

EXCELENTE APORTE ¿NO? jeje!! Hecho!! Exitos!

RODRIGO SOLORZANO PARDO
gerencia@apoloweb.com

Litzer

04/2/2008
Estoy probando bajo la version 0.5 4b y aparte de tener que modificar las lineas anteriormente citadas en los comentarios de este manual y de sus antecesores, también me encontré con un error en la linea de xajaxResponse, por lo que he eliminado la definición del juego de caracteres dejandolo así:

$respuesta = new xajaxResponse();

de este modo el codigo corre y lo hace correctamente y a mi parecer trata los accentos.

susana

20/2/2008
hola,
para poner por defecto el juego de caracteres iso-8859-1 tambien se puede modificar las siguientes entradas en el xajax.inc.php
cambiar utf-8 por iso-8859-1 en la linea : define ('XAJAX_DEFAULT_CHAR_ENCODING', 'utf-8')
y en la funcion ajax cambiar 'decodeUTF8Input' a true.
con esto evitamos tener que definir el codigo de caracteres cada vez que instanciamos la clase.
Saludos.

guarus

20/10/2008
Saludos, tambien me aparece el mismo error comentado anteriormente y lo sulucione comentandolo de igual forma.

Ademas, al ejecutar el codigo e incluir todos los campos requeridos, solo me muestra el mensaje que se encuentra dentro del div "mensaje" mas no el del div "capaformulario", siempre y cuando comente esta linea

$respuesta->assign("capaformulario", "innerHTML", $salida);

de lo contrario no muestra nada. si saben la respuesta les agradeceria. de todas formas les dejo el codigo completo.


<?php
require ('./xajax/xajax_core/xajax.inc.php');

$xajax = new xajax();
/*$xajax->setCharEncoding('ISO-8859-1');
$xajax->decodeUTF8Input();*/

function procesar_formulario ($form_entrada)
{

$respuesta = new xajaxResponse();

$error_form = "";
if ($form_entrada["nombre"]=="")
{ $error_form = "Debes escribir un nombre"; }
elseif ($form_entrada["telf"]=="")
{ $error_form = "Debes escribir el apellido"; }

if ($error_form != "")
{ $respuesta->assign("mensaje", "innerHTML", "<span style='color:red;'>$error_form</span>"); }
else
{ $salida = "Hemos procesado los siguientes datos: <p>";
$salida .= "Nombre: " .$form_entrada["nombre"];
$salida .= "<br>Teléfono: " .$form_entrada["telf"];

$respuesta->assign("mensaje", "innerHTML", "<span style='color:blue;'>Todo Correcto. Muchas Gracias!</span>");

$respuesta->assign("capaformulario", "innerHTML", $salida);

}

return $respuesta;
}

$xajax->registerFunction("procesar_formulario");
$xajax->processRequest();

?>

<html>

<head>
<title>Recibir y procesar un formulario con xajax Grabando en BD</title>
<?php $xajax->printJavascript("./xajax/"); ?>
</head>

<body>
<h1 align="center">Recibir y procesar un formulario con xajax Grabando en BD</h1>
<div id="mensaje">
Rellena todos los datos de este formulario y pulsa "Grabar"
</div><br>
<div id="capaformulario">
<form id="formulario">
Nombre: <input type="text" name="nombre"><br>
Tel&eacute;fono: <input type="text" name="telf"><br>
<input type="button" value="Grabar" onclick="xajax_procesar_formulario(xajax.getFormValues('formulario'))">
</form>
</div>
</body>

</html>

Victor

05/5/2009
El codigo que me funciona
Hice pequeños cambios en el codigo de arriba para que funcione con el juego de caracteres ISO, ahi va el codigo:

<?
//incluímos la clase ajax
require ('xajax/xajax_core/xajax.inc.php');

//instanciamos el objeto de la clase xajax
$xajax = new xajax();
$xajax->setCharEncoding('ISO-8859-1');
$xajax->configure('decodeUTF8Input',true);

function procesar_formulario($form_entrada){
//creo el xajaxResponse para generar una salida
$respuesta = new xajaxResponse();
$respuesta->setCharacterEncoding('ISO-8859-1');

//validación
$error_form = "";
if ($form_entrada["nombre"] == "")
$error_form = "Debes escribir tu nombre";
elseif ($form_entrada["apellidos"] == "")
$error_form = "Debes escribir tus apellidos";
elseif (!isset($form_entrada["acepto"]))
$error_form = "Debes aceptar los términos y condiciones";

//compruebo resultado de la validación
if ($error_form != ""){
//Hubo un error en el formulario
//en la capa donde se muestran mensajes, muestro el error
$respuesta->Assign("mensaje","innerHTML","<span style='color:red;'>$error_form</span>");
}else{
//es que no hubo error en el formulario
$salida = "Hemos procesado esto:<p>";
$salida .= "Nombre: " . $form_entrada["nombre"];
$salida .= "<br>Apellidos: " . $form_entrada["apellidos"];

//mostramos en capa mensaje el texto que está todo correcto
$respuesta->Assign("mensaje","innerHTML","<span style='color:blue;'>Todo correcto... Muchas gracias!</span>");
//escribimos en la capa con id="capaformulario" el texto que aparece en $salida
$respuesta->Assign("capaformulario","innerHTML",$salida);

//tenemos que devolver la instanciación del objeto xajaxResponse
}
return $respuesta;
}
//registramos la función creada anteriormente al objeto xajax
$xajax->register(XAJAX_FUNCTION, 'procesar_formulario');

//El objeto xajax tiene que procesar cualquier petición
$xajax->processRequest();
?>
<html>
<head>

<title>Enviar y procesar un formulario con Ajax y PHP</title>
<?
//En el <head> indicamos al objeto xajax se encargue de generar el javascript necesario
$xajax->printJavascript("xajax/");
?>
</head>

<body>
<h1>Recibir y procesar formulario con Ajax y PHP</h1>
<div id="mensaje">
Rellena los datos de este formulario y pulsa "Enviar"
</div>
<br />
<div id="capaformulario">
<form id="formulario">
Nombre: <input type="text" name="nombre" />
<br />
Apellidos: <input type="text" name="apellidos" />
<br />
<input type="checkbox" name="acepto" value="1" /> Acepto los términos y condiciones ;)
<br />
<input type="button" value="Enviar" onclick="xajax_procesar_formulario(xajax.getFormValues('formulario'))">
</form>
</div>

</body>
</html>

skifree

23/11/2009
Ayudaaaa!!!! Pro favor.......
que tal. he querido hacer esto en mi pagina no tengo mucho que empeze en el entorno de php etc....por favor ayudenme.. .. necesito saber esto.o sime pueden enviar ejemplo para poder modificar o cosas por el estilo... por favor!!!!!!!!!

mi cuestion es la siguiente..!!!

quisiera hacer esto en mi pagina. nada mas la validacion.. si existe el usuario , y no hay anda escrito..etc.. en el mismo div.. q tengo... y una vez si esta todo bien.. desaparecer el formulario y q nada mas aparesca un mensaje... de bienvenida o algo asi... en el mismo div..... ok.. yo lo hago pero lo mando a otra pagina y procesar_logeo.php, digamos que lo que hace ese archivo lo muestre en el mismo div....


mi formulario es este..
____________________________________________________________
index.php
_________________________________________________________
<div id="wrapper">
<div id="navigation">
<div class="navigation">

<form name="inicio" action="procesar_logeo.php" idi="formulario" method="post">
codigo:Usuario: <input type="text" name="usuario"><br>
Clave:Password: <input type="text" name="password">
<input type="submit" value="Enviar" >
</form>
</div>
</div>

<div id="header">

</div>
_________________________________________________________________
procesar_logeo.php
_______________________________________________________________
<?php
$link=Conectarse(); //Conectarse a la BD

recuperadas)
$usuario=$_POST['usuario'];
$password=$_POST['password'];


$result=mysql_query("select usuario, password,tipo from usuario where usuario = '$usuario' ",$link);
if ($row=mysql_fetch_array($result)){
if ($row["password"]==$password){ //El usuario encontrado, entonces comparamos la clave!
if ($row["tipo"]==administrador){
echo "Bienvenido ADMINISTRADOR";
}else{
echo "Bienvenido usuario!!!!"; }
}else{
echo "Clave INCORRECTA";
}
}else{
echo "No existe el usuario -------Verifique sus datos!!!!!!!";
}
mysql_close($link);


function Conectarse() {
if (!($link=mysql_connect("localhost","root","280988DMBbdx")))
{
echo "Error conectando a la base de datos.";
exit(); //salir de la funcion
}

if (!mysql_select_db("jugueteria",$link))
{
echo "Error seleccionando la base de datos.";
exit();
}
return $link;
}
?>

atoleon

17/12/2009
Devolver dos valores en la misma función
Me ha parecido interesantísimo este artículo además de que me fue muy útil para mi página web.
¿Pero me pregunto si es posible, y como se haría para poder devolver, o escribir, dos valores desde la misma función?
Gracias, un saludos a todos

Goku

28/1/2010
Esto es una maravilla
sin duda que esto es pan comido seniores!!! se los recomiendo

Juani

09/2/2010
duda!
Hola! Pude aplicar el ejemplo en un formulario mio perfectamente. Ahora tengo una duda.
Si detecta que no hay errores, en vez de dar un mensaje de "Todo perfecto", se pueden cargar los datos a la base de datos directamente?
gracias...