viernes, junio 06, 2008

Fusion de 2 grandes, CakePHP 1.2 con Flexigrid.

Hace un tiempo que estoy desarrollando aplicaciones web con el Framework CakePHP mas específicamente desde Diciembre del 2007. Desde siempre he tenido dificultades a la hora de hacer buenos diseños o estilos para las rejillas de datos. Hace un tiempo me habian pasado el enlace a un control realizado en javascript llamado Flexigrid, era la solucion algo realmente fantástico, el unico problema era que no habia forma de encontrarle la vuelta para poder integrarlo en cakePHP, busque en web, foros, y no encontré nada solo un post indicando que quería integrarlo pero no podia. Esto me motivó a integrarlo yo mismo, asi que ahora les dejo el como integrar el Flexigrid con CakePHP 1.2, espero les sea util, ahora mismo me encuentro modificando el Flexigrid para darle la oportunidad de ponerle filtros.


Antes que nada hay que descargarse el control de la pagina web e incluir los archivos .js y .css necesarios, esto lo podemos hacer desde la pagina de Flexigrid.

Bueno dentro del model no hay ninguna modificación.
Ahora vemos que hay que hacer en el controller, la funcion index ya no es mas la encargada de devolverle los datos a la view del index, este se va a cargar via ajax jquery por xml, en mi caso la funcion index queda vacia, ademas creo una accion llamada grid_data que va a ser la encargada de pasarle los datos por xml al index.

function grid_data()
{
$this->layout='xml';

if(!empty($_POST['page']))
{
$page = $_POST['page'];
}
else
{
$page = 1;
}

if(!empty($_POST['rp']))
{
$rp = $_POST['rp'];
}
else
{
$rp = 10;
}

$start = (($page-1) * $rp);
$limit = $start. ", ". $rp;

if(!empty($_POST['sortname']))
{
$sortname = $_POST['sortname'];
}
else
{
$sortname = 'ban_nombre';
}

if(!empty($_POST['sortorder']))
{
$sortorder = " " . $_POST['sortorder'];
}
else
{
$sortorder = ' asc';
}


if(!empty($_POST['query']))
{
$query = $_POST['query'];
}
else
{
$query = null;
}

if(!empty($_POST['qtype']))
$qtype = $_POST['qtype'];

$where = "";
if ($query)
{
$where = "{$qtype} LIKE '%{$query}%'";
}

$orden = $sortname . $sortorder;
$count = $this->Banco->find('count');

$this->set('count', $count);
$this->set('page', $page);
$this->set('rp', $rp);
$this->set('data',$this->Banco->find('all', array('conditions'=>$where, 'limit'=>$limit, 'order'=>$orden)));
}

en esta accion del controller tienen todas las caracteristicas, la paginación, la búsqueda y la ordenación haciendo click en los encabezados de las columnas.

Si se han fijado bien, en la accion hace uso de un layout que no viene por defecto, xml, para ello van a tener que escribir dicho layout, xml.ctp.


header('Content-Type: text/xml; charset=utf8');
echo $content_for_layout;
?>

Ahora bien, dado que la accion se llama grid_data y que no estamos haciendo render a ninguna vista distinta, cakePHP va a buscar una vista llamada grid_data.ctp, este archivo es el que escribe el xml en la forma que el flexigrid lo comprenda.


$strView = "";
$strView .= "";
$strView .= "".$page."";
$strView .= "".$count."";
foreach ($data as $v)
{
$strView .= "";
$strView .= "".$v['Banco']['ban_nombre']."";
$strView .= "";
}
$strView .= "";

echo $strView;
?>

Por ultimo queda el index.ctp:


$strView = "\n
";
$strView .= "\n".$form->create(null, array("action"=>"index", "name"=>"index","id"=>"index"));
$strView .= "\n".$form->hidden('Banco.accion',array("id"=>"accion"));
$strView .= "\n".$javascript->codeBlock("
$(document).ready(function () {
$('.flexme').flexigrid({
url: '".$html->url('/bancos/grid_data')."',
colModel : [
{display: '', name : '', width : 60, sortable : false, align: 'left'},
{display: 'Nombre', name : 'ban_nombre', width : 595, sortable : true, align: 'left'}
],
buttons : [
{name: 'Insertar Banco', bclass: 'add', onpress: insertarBanco},
{name: 'Imprimir', bclass: 'imprimir'},
{name: 'Eliminar', bclass: 'delete'},
{separator: true}
],
searchitems : [
{display: 'Nombre', name : 'ban_nombre', isdefault: true}
],
sortname: 'ban_nombre',
sortorder: 'asc',
usepager: true,
title: 'Bancos',
useRp: true,
rp: 10,
showTableToggleBtn: true,
width: 700,
height: 245
});
});

function insertarBanco()
{
setValue('add');
}
");
$strView .= "\n";
$strView .= "\n
";

$strView .= "\n".$form->end();
$strView .= "\n
";


echo $strView;
?>


Y con eso ya debería de quedar totalmente integrado la grandiosa rejilla de datos a nuestro querido Framework CakePHP.
Cualquier error, sugerencia queja o lo que soy todo oidos, ya si voy desarrollando algo mas para este control lo voy a ir dejando por aqui.