Ya había mencionado que mi objetivo principal era desarrollar funciones y componentes que sean reutilizables y fáciles usar, a continuación voy a tratar de mejorar el componente ui de jquery para que pueda conectarse directamente con una tabla de la base de datos, en el ejemplo anterior en nombre de la tabla que se usó es historial, pero que pasaría si queremos usar este componente en otro proyecto tendríamos que hacer cambios cada vez y puede ser que ya la tabla no se llame historial inclusive el nombre del campo puede variar, para eso pensé en crear un modelo "genérico" que reciba cualquier nombre de tabla y campo, se conecte a la bd y que obtenga los datos necesarios, lo llamaré generic_model, nos servirá para posteriores ejemplos al cual iremos añadiendo nuevas funcionalidades.
application/models/generic_model.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php class Generic_model extends CI_Model { function __construct() { // Call the Model constructor parent::__construct(); } /** * Obtiene los registros de un campo de una tabla de la base de datos * @param $nombre_tabla El nombre de la tabla * @param $nombre_campo El nombre del campo de la tabla */ function get_datos($nombre_tabla,$nombre_campo) { // SQL equivalente a SELECT $nombrecampo FROM $nombre_tabla; $this->db->select($nombre_campo); $this->db->from($nombre_tabla); $query = $this->db->get(); return $query->result(); } } |
Como se puede observar la función get_datos($nombre_tabla,$nombre_campo) acepta 2 parámetros que recibimos por medio de nuestro controller, y gracias a las funciones de la clase Database de codeigniter obtenemos el equivalente al código sql SELECT $nombrecampo FROM $nombre_tabla;
He conseguido que el modelo sea "mas genérico" ya que ahora el nombre de la tabla es variable y también del campo.
A continuación hacemos los correspondientes cambios al controller en la función datos_dp, esencialmente recibe de la vista los datos correspondientes al nombre de la tabla y del campo que son enviados por ajax usando los métodos de la clase input de codeigniter vease manual , casi es el mismo código al ejemplo anterior.
application/controllers/dp.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?php class Dp extends CI_Controller { public function __construct() { parent::__construct(); // cargamos nuestro base de datos ahora lo hacemos por defecto $this->load->database(); } public function index() { // en este caso queremos que la vista haga las peticiones no el controller // cargamos nuestra vista $this->load->view('dp_view'); } public function datos_dp() { $tabla = $this->input->post('tabla'); //el nombre de la tabla de la bd $campo = $this->input->post('campo');//el nombre de campo de la tabla $this->load->model("Generic_model");// cargo mi modelo generico // le envio el nombre de la tabla y el campo al modelo a travez de get_datos $datos['query'] = $this->Generic_model->get_datos($tabla, $campo); // codificamos el array a json usando json_encode mirar manual de php $data_json = json_encode($datos); // enviamos el json a la vista echo $data_json; } } |
Los cambios son mas amplios en el javascript, ya que creamos una función que podemos reutilizarla las veces que consideremos necesarias.
js/dp.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /* * La lógica por parte del cliente usando jquery */ jQuery(document).ready(function(){ datepicker("#datepicker"); // ejemplo de uso de la función datepicker /** * La función datepicker crea un datepicker logico no? * @param $id_input Es el id del input que se convierte en datepicker */ function datepicker($id_input){ //creamos el datepicker $($id_input).datepicker({ dateFormat: "dd/mm/yy" }); var nombre_tabla = $($id_input).attr("tabla"); var nombre_campo = $($id_input).attr("campo"); var json_conf_dp = { tabla:nombre_tabla, campo:nombre_campo }; $.ajax({ type: "POST", url: "dp/datos_dp", data: json_conf_dp, success: function(msg){ var datos = $.evalJSON(msg);// se convierte de json a un objeto javascript $( $id_input ).datepicker('setDate', datos.query[1][nombre_campo]); } }); } });// fin de ready function |
Estas dos lineas en mi javascript var nombre_tabla = $($id_input).attr("tabla"); y var nombre_campo = $($id_input).attr("campo"); obtienen el valor de los atributos de mi input que en este caso se contienen el valor historial y fecha respectivamente que luego son pasados por medio de un objeto json json_conf_dp a la función ajax.
Luego dentro de mi función ajax el siguiente código $('#datepicker').datepicker('setDate', datos.query[1][nombre_campo]); asigna la fecha a mi datepicker por medio del parámetro datos.query[1][nombre_campo] que contiene nuestra fecha obtenida de la base de datos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!doctype html> <html lang="es"> <head> <link type="text/css" href="../js/css/smoothness/jquery-ui-1.8.17.custom.css" rel="stylesheet" /> <script type="text/javascript" src="../js/jquery-1.7.1.min.js"></script> <script type="text/javascript" src="../js/jquery-ui-1.8.17.custom.min.js"></script> <script language="JavaScript" type="text/javascript" src="../js/jquery.json-2.3.min.js"></script> <script type="text/javascript" src="../js/dp.js"></script> </head> <body> <div> <input id="datepicker" type="text" tabla="historial" campo="fecha"> </div> </body> </html> |
Al final puedo poner tantos datepickers como quiera a mi vista pero tengo que tener en cuenta ciertos detalles, el id del input debe ser único, además también tengo que llamar a la función por cada datepicker de la siguiente manera
datepicker("#datepicker1"); // ejemplo de uso de la función datepicker
datepicker("#datepicker2"); // ejemplo de uso de la función datepicker
Aunque todavía nos toca escribir un poco de código es mucho mejor que con el ejemplo anterior ya que lo he reducido a 2 lineas, imagínate que tuvieras que incluir 10 datepickers cuanto código se necesitaría, con esta función solo se necesitaría 10 lineas y por supuesto reutilizar la función datepicker.
Aunque sería interesante que no tuviéramos que cambiar el javascript para nada y solo añadiéramos nuestros inputs al html de nuestra vista y se creara automáticamente los datepicker, como se podría lograr ?
La primera forma que se me ocurre es utilizando los parámetros extras que le incluimos al input
<input id="datepicker" type="text" tabla="historial" campo="fecha"> que son tabla y campo, la función debería detectar si cada input en mi vista contiene estos dos campos, si los contiene entonces que cree nuestros datepicker con conexión a nuestra base de datos.
La segunda forma es crear nuestra propia etiqueta que se llame por ejemplo datepicker, la función debería detectar y crearlos automáticamente, el html quedaría así <datepicker id="datepicker1" tabla="historial" campo="fecha"> además de ser semánticamente mas correcto, visualmente podríamos detectar más rápidamente dentro de nuestro código cual es un input ordinario y un datepicker, si se confundieron aquí lo aclararé implementando esta parte en el siguiente artículo :)
Todo esto se puede mejorar añadiendo más funcionalidad a mi componente, por ejemplo además de que obtenga una fecha de la bd se puede intentar actualizar un campo de dicha tabla o agregar una fecha, etc..
No hay comentarios:
Publicar un comentario