Skip to content

2 marzo, 2010

Enviar formulario sin recargar la página con Zend Framework y JQuery.

Cuando se están manejando formularios con PHP guardando los datos en algún gestor de base de datos como MySQL llega a surgir la duda de cómo guardar dichos datos utilizando Ajax (JQuery en éste caso) para evitarnos el refresco de pantalla y poder seguir haciendo uso del sistema sin este pequeño (o grande) retraso.

Primero que nada utilizaré Zend Framework, JQuery y MySQL como gestor de base de datos. Para éste ejemplo empezaremos creando una base de datos sencilla llamada clientes donde única y exclusivamente guardaremos el nombre (para no hacer tan extenso ésto).

Muy bien para crear nuestra tabla primeramente debemos tener creada la base de datos, puedes utilizar phpmyadmin o la línea de comandos, como más te agrade, de todas maneras adjunto el código de la creación de la base de datos como también de la tabla.

CREATE DATABASE `prueba`;

CREATE TABLE `prueba`.`clientes` (
  `id_cliente` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  `cliente` VARCHAR( 100 ) NOT NULL
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Si te fijas la base de datos la llamé prueba y la tabla la llamé cliente con dos campos, id_cliente y cliente.
No entraré en detalles en creación de controladores, modulos, vistas, en nuestro árbol de directorios de Zend Framework.

Creo el módulo (application/models/Clientes.php) con un método llamado getClientes, éste método nos devolverá posteriormente los clientes guardados en la base de datos:

<?php

class Clientes extends Zend_Db_Table
{
    protected $_name = 'clientes';

    public function getClientes()
    {
        $c = new Clientes();
        $c_select = $c->select()->order('cliente');

        return $c->fetchAll($c_select);
    } // end getClientes

}

El controlador lo llamaré Clientes así que queda de la siguiente manera (application/controllers/ClientesController.php):

<?php

class ClientesController extends Zend_Controller_Action
{

    public function init()
    {
        $this->initView();
        $this->view->baseUrl = $this->_request->getBaseUrl();
    }

    public function indexAction()
    {
        Zend_Loader::loadClass('Clientes');
        $c = new Clientes();
        $this->view->clientes = $c->getClientes();

    } // end indexAction()

}

?>

El método init nos arroja la variable baseUrl, la cual utilizaremos para la llamada de archivos en nuestra vista, como también tiene la acción index y hace una consulta a nuestra base de datos clientes (getClientes) como lo mencionamos anteriormente y dicha consulta la podremos ver en nuestra vista.

Aquí quedaría nuestra vista (application/views/scripts/clientes/index.phtml):

<script type="text/javascript" language="javascript" src="<?php echo $this->baseUrl;?>/public/scripts/jquery.js"></script>
<script type="text/javascript" language="javascript" src="<?php echo $this->baseUrl;?>/public/scripts/guardarCliente.js"></script>
<form action="" name="form1" id="form1" method="post">
    <label>Cliente: </label><div id="div_cliente">
        <select name="cliente" id="cliente">
            <?php foreach ($this->clientes as $cliente) : ?>
            <option value="<?php echo $cliente->id_cliente; ?>"><?php echo $cliente->cliente; ?></option>
            <?php endforeach; ?>
        </select>
    </div>
</form>

<div id="form_ajax">
    <form name="guardar_cliente">
        <p>Cliente:</p>
        <input type="text" name="nombre_cliente" id="nombre_cliente" value="" />
        <input type="submit" name="submit" value="Guardar" id="guardarCliente" />
    </form>
</div>

En el código anterior hemos agregado la libreria de JQuery que la puedes descargar de Aquí y además el archivo agregarCliente que se encargará de hacer la petición AJAX del guardado del cliente. Este archivo quedaría como lo siguiente (public/scripts/agregarCliente.js):

$(function() {

    // bloqueamos la tecla enter para que no recargue la página
    $('#form_ajax').bind('keypress', function(e) {
        if (e.keyCode == 13) return false;
    });

    $('#guardarCliente').click(function() {

        var nombre_cliente = $('#nombre_cliente').val();
        var baseUrl = '/prueba';
        var dataString = 'nombre_cliente=' + nombre_cliente;

        $.ajax(
        {
            async: true,
            dataType: 'html',
            type: 'POST',
            contentType: 'application/x-www-form-urlencoded',
            url: baseUrl + '/clientes/guardar-cliente/',
            data: dataString,
            beforeSend: function(data){
                    $('#div_cliente').html('<label>Cargando...</label>');
            },
            success: function(requestData){
                    $('#div_cliente').html(requestData);
            },
            error: function(requestData, strError, strTipoError){
                    alert('Error ' + strTipoError +': ' + strError);
            },
            complete: function(requestData, exito){
            }
        });

        $('#nombre_cliente').val('');
        return false;
    });
});

Ten en cuenta el atributo url de $.ajax ( url: baseUrl + ‘/clientes/guardar-cliente/’) ya que es en donde se ejecuta el script del lado del servidor (PHP) que guardará finalmente nuestro cliente.
La variable baseUrl de nuestro archivo javascript igualmente hace referencia al directorio en el que se encuentra nuestro sistema dentro de nuestro servidor web.

Por último volvemos a modificar nuestro controlador, agregando la acción guardar-cliente y nuestro archivo application/controllers/ClientesController.php será el siguiente:

<?php

class ClientesController extends Zend_Controller_Action
{

    public function init()
    {
        $this->initView();
        $this->view->baseUrl = $this->_request->getBaseUrl();
    }

    public function indexAction()
    {
        Zend_Loader::loadClass('Clientes');
        $c = new Clientes();
        $this->view->clientes = $c->getClientes();

    } // end indexAction()

    public function guardarClienteAction()
    {
    if ($this->getRequest()->isXmlHttpRequest()) { //Detectamos si es una llamada AJAX

        $this->_helper->viewRenderer->setNoRender();
        Zend_Loader::loadClass('Clientes');
        $c = new Clientes();

        // agregamos el estado
        $cliente = $this->_request->getPost('nombre_cliente');

        $cliente_data = array ('cliente' => $cliente);
        $c->insert($cliente_data);

        // consulta de la nueva lista de clientes
        $clientes = $c->getClientes();
        if (count($clientes) > 0) {

            echo '<select name="cliente" id="clienteo">';
            foreach($clientes as $cl):
                $selected = '';
                if ($cl->cliente == $cliente) { $selected = 'selected="selected"'; }
                echo '<option value="'.$cl->id_cliente.'" '.$selected.'>'.$cl->cliente.'</option>';
            endforeach;
            echo '</select>';

        } // end if (count($clientes) > 0)

     } // end if ($this->getRequest()->isXmlHttpRequest())

    } // end guardarClienteAction

}

?>

Y listo ya tienes tu modulo clientes el cual te lista los clientes ya existentes y desde la misma página podrás agregar más sin necesidad de recargar la página como lo hace un formulario normal.

Cabe destacar que yo lo realicé con el Zend Framework, pero si se analiza el código es bastante simple y puede aplicarse sin éste, pero eso ya les toca a ustedes hacerlo.

Cualquier aportación o comentario serán bien recibidos :)

Share your thoughts, post a comment.

(required)
(required)

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments