Enviar formulario por AJAX en CodeIgniter

Publicado: 28/03/2010 en AJAX, CodeIgniter, desarrollo, Formulario, JavaScript, jQuery, php, Programación
Etiquetas:, , , , , , ,

You can read the English version of this post in http://phpsblog.agustinvillalba.com/sending-forms-ajax-codeigniter/

Hoy vamos a explicar cómo podemos enviar un formulario por AJAX utilizando jQuery en CodeIgniter, de tal forma que evitamos que se recargue toda la página, dando un aspecto de aplicación de escritorio a nuestra aplicación web, pudiendo realizar determinadas acciones sin necesidad de recargar toda la vista del usuario.

Creando el formulario

Lo primero que necesitamos es crear nuestro formulario. En este caso vamos a crear un formulario genérico, en el que intentaremos añadir diversos tipos de campos para hacer el ejemplo más completo, pero funcionalmente no es muy útil, todo sea por la didáctica… Así que en nuestro archivo de vista de CodeIgniter añadimos el siguiente código:

$attr = 'id="mi_form"'; //Le damos el id mi_form al formulario echo form_open('mi_controller/procesa_form',$attr);
 //Creamos un campo de tipo texto
 echo form_label('Campo1: ','campo1');
 $data = array(
 'name'        => 'campo1',
 'id'          => 'campo1',
 'value'       => ''
 );
 echo form_input($data);
 //Creamos una serie de checkboxes
 $data = array(
 'name'        => 'campo2',
 'id'          => 'campo2',
 'value'       => '2',
 'checked'     => false
 );
 echo form_checkbox($data);
 $data = array(
 'name'        => 'campo3',
 'id'          => 'campo3',
 'value'       => '3',
 'checked'     => false
 );
 echo form_checkbox($data);
 //Creamos unos radio
 $data = array(
 'name'        => 'radio',
 'id'          => 'radio1',
 'value'       => 'radio1',
 'checked'     => false
 );
 echo form_radio($data);
 $data = array(
 'name'        => 'radio',
 'id'          => 'radio2',
 'value'       => 'radio2',
 'checked'     => false
 );
 echo form_radio($data);
 //Un textarea
 echo form_label('Textarea: ','textarea');
 $data = array(
 'name'        => 'textarea',
 'id'          => 'textarea',
 'value'       => '',
 'rows'        => '2',
 'cols'        => '50' );
 echo form_textarea($data);
echo form_close();

Nuestro controlador

Aquí es dónde viene la parte más importante y, para mí, más interesante de todo el proceso. En nuestro controlador vamos a identificar si el formulario nos lo han enviado por AJAX o por la forma tradicional (recargando página). De esta forma podremos cargar unas vistas u otras sin necesidad de tener dos funciones en nuestro controlador para realizar el mismo trabajo. Lo importante está en examinar la constante del sistema PHP llamada “HTTP_X_REQUESTED_WITH“, la cual nos indica si la petición se realizó por AJAX o mediante una petición HTTP estándar. De forma que el código de nuestro controlador sería el siguiente:

<?php

//Almacenamos en la constante IS_AJAX si la petición es por AJAX o no
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
class Mi_controller()
{
public function procesa_form()
{

//Cargamos la librería de validación de formulario
$this->load->library('form_validation');

//Establecemos algunas reglas de validación (si fuera necesario)
$this->form_validation->set_rules('Campo1','required|xss_clean');
$this->form->validation->set_rules('Textarea','required|xss_clean');

if($this->form_validation->run())
{
//realizamos las tareas que sean necesarias para procesar y almacenar los datos
...

$data['no_error'] = $this->tareas_de_proceso();
if(IS_AJAX)
{
$this->load->view('ajax_response',$data['no_error']);
}
else
{
//Cargamos la vista estandar
}
}
else
{
//El formulario no es válido
if(IS_AJAX)
{
$data['message'] = validation_errors();
$this->load->view('ajax_no_valid',$data);
}
else
{
//Cargamos la vista estandar
}
}

?>

Para esto asumimos que en el directorio views de nuestra aplicación tenemos los archivos ajax_response.php y ajax_no_valid.php con el siguiente contenido:

<?php
//ajax_response.php
if($no_error)
{
echo "El formulario se procesó con éxito";
}
else
{
echo "Hubo un problema en el procesamiento del formulario";
}
?>

<?php
//ajax_no_valid.php
echo $message;
?>

Y ahora… jQuery

Ya sólo nos falta incluir el código JavaScript que se encargará de enviar el contenido del formulario via AJAX, evitando así que se recargue toda la página:

$(function(){
$('#mi_form').submit(function(evnt){
evnt.preventDefault(); //Evitamos que el evento submit siga en ejecución, evitando que se recargue toda la página
$.post(url+"clip/edit_clip", //La variable url ha de contener la base_url() de nuestra aplicacion
    $("form#edit_form").serialize(), //Codificamos todo el formulario en formato de URL
    function (data) {
        $('div#sending_form').prepend(data); //Añadimos la respuesta AJAX a nuestro div de notificación de respuesta
    });
});
});

En nuestro código jQuery utilizamos la función .serialize(), la cual se encarga de codificar en formato de URL todos los campos del formulario (a=1&b=2&c=3…) evitándonos así el tenerlo que hacerlo nosotros uno a uno. Es importante destacar que la función serialize() no codifica aquellos campos que no tengan el atributo name, así como tampoco serializará los campos <input type=file …/>. Aquí tienen más información sobre la función serialize() (http://api.jquery.com/serialize/).

Pues bien, con esto ya podemos dar por finalizado el envío de formularios a través de AJAX utilizando jQuery en CodeIgniter.

You can read the English version of this post in http://phpsblog.agustinvillalba.com/sending-forms-ajax-codeigniter/

Anuncios
comentarios
  1. goyo dice:

    Muchas gracias por la info. Llevo días buscando una información similar No obstante me resulta bastante complicado hacerlo funcionar. Tienes los archivos para poder descargarlos(me quedan dudas del número de archivos y sus nombres)
    Muchas gracias

  2. Lichblitz dice:

    Hola, ya años tiene esto pero ahora es que ando aprendiendo. En codeigniter 2 uso form_error(‘name_input’); para que el error salga al lado de cada input. Cómo hago para que al recibir la respuesta salga en cada form_error()? No tengo un div de errores como está allí, gracias. 🙂

  3. german dice:

    Me carga varias veces la vista y no la actualiza, como podria hacerlo ?

  4. ines dice:

    disculpa las molestias pero tengo dos preguntitas
    $.post(url+”clip/edit_clip”, //a que se refiere esto es un controlador en el que recibe los datos? clip/edit_clip
    $(“form#edit_form”).serialize(), //y que formulario es este por que el id del formulario que usas en el ejemplo es id=”mi_form”.
    por favor si puedes responder soy nueva en esto. por que en el div de respuesta no aparece nada

    • Exacto, “clip/edit_clip” se refiere al controlador “clip”, y la función dentro de este llamada “edit_clip”, esto es propio de CodeIgniter. En cuanto al formulario, yo en mi vista tengo un form con el id=”edit_form”, tú, en tu vista, puedes tener el formulario con el id que tú necesites.
      Un saludo!

  5. ines dice:

    una consulta que version de jquery utilizas porfavor me interesa saber gracias.

    • Siempre utilizo la última versión disponible y minimizada en google.apis, con este código:
      https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
      Cuando jQuery cambie a la version 2.x.x pues habría que cambiar ese código.
      Saludos!

  6. ines dice:

    gracias por compartir tu codigo me ayudo vastante en las dudas que tenia mil gracias.

  7. eduardo90 dice:

    Amigos tengo una duda, en donde va colocado el jquery.

    ya que no dice por ningun lado.

    • Hola Eduardo,

      la librería jQuery has de colocarlo en el directorio donde almacenas todos tus archivos JavaScript. Habitualmente se hace en uno llamado “js” en la raíz del directorio de tu aplicación web.

      Saludos!

  8. goreOTR dice:

    Ok, gracias por la aclaración y de paso felicitaciones por el blog.

  9. goreOTR dice:

    Una consulta, me da error en ‘url’ no esta definido, en la petición ajax, además que ¿Qué es $this->tareas_de_proceso();? que devuelve? gracias…

    • La variable url es una variable JavaScript global a tu aplicación (puedes definirla en tu template principal, por ejemplo) y ha de contener lo que devuelve la función base_url() de CodeIgniter, algo así como:
      var url = ;

      La función tareas_de_proceso la llamo así de forma genérica, lo que quiero decir es que en ese bloque del código cada uno hará aquellas cosas que necesite procesar la llamada de AJAX. La llamé así por darle un nombre genérico, pero tu has de hacer lo que necesites en tu caso concreto.

  10. Nicho dice:

    Ecelente…estaba tratando de hacer algo así hace tiempo, gracias por este fabuloso aporte

  11. mario dice:

    Como siempre haciendo buenos articulos
    saludos

  12. josepzin dice:

    Muy interesante eso de detectar si es una llamada AJAX, graciasss

  13. Muy, pero que muy interesante. Y como siempre, muy bien explicadito 😉

    Gracias.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s