lunes, 21 de diciembre de 2015

Personalizando elementos del formulario con CSS

En este artículo quiero tratar el tema sobre cómo ubicar y personalizar los componentes html de un formulario mediante reglas CSS, para mejorar el aspecto visual de nuestra aplicación.
Hoy en día son pocos los sitios que no cuentan con algún formulario, ya sea para autenticación o algún dato que necesita entrar el usuario a la aplicación. Supón que tenemos el siguiente formulario y queremos darle una ubicación específica a las etiquetas con respecto a los campos de texto.
image_thumb1[4]
El código HTML del ejemplo anterior es el siguiente:
   1: <form class="my_form">

   2:                 <fieldset>

   3:                     <legend>Alta en el sistema</legend>

   4:                     <label for="nombre">Nombre</label>

   5:                     <input type="text" id="nombre" />

   6:                     <label for="apellidos">Apellidos</label>

   7:                     <input type="text" id="apellidos"/>

   8:                     <label for="dni">DNI</label>

   9:                     <input type="text" id="dni" maxlength="9" />

  10:                     <label for="contrasena">Contraseña</label>

  11:                     <input type="password" id="contrasena" />

  12:                     <input class="btn" type="submit" value="Registrarme" />

  13:                 </fieldset>

  14:             </form>
Si quisiéramos mostrar los <label> encima de los campos de texto aplicando unos estilos sencillos podríamos lograr el efecto mostrado:
image_thumb3[4] Regla CSS:
   1: label { 

   2:      display: block; 

   3:      margin: .5em 0 0 0; 

   4: }

   5: .my_btn { 

   6:       display: block; 

   7:       margin: 1em 0; 

   8: }
Al botón también se le añade una regla CSS para mostrarlo como elemento de bloque y un margen para lograr el efecto deseado.
Si quisiéramos mostrar nuestros elementos <label> al lado izquierdo de los campos de texto, para lograr este resultado:
image_thumb5[4]
Código HTML:
   1: <form class="my_form">

   2:             <fieldset>

   3:                 <legend>Alta en el sistema</legend>

   4:                 <div>

   5:                     <label for="nombre">Nombre</label>

   6:                     <input type="text" id="nombre" />

   7:                 </div>

   8:                 <div>

   9:                     <label for="apellidos">Apellidos</label>

  10:                     <input type="text" id="apellidos"/>

  11:                 </div>

  12:                 <div>

  13:                     <label for="dni">DNI</label>

  14:                     <input type="text" id="dni" maxlength="9" />

  15:                 </div>

  16:                 <div>

  17:                     <label for="contrasena">Contraseña</label>

  18:                     <input type="password" id="contrasena" />

  19:                 </div>

  20:                 <input class="my_btn" type="submit" value="Registrarme" />

  21:             </fieldset>

  22:         </form>
A las reglas le agregaríamos:
   1: div { 

   2:      margin: .4em 0; 

   3: } 

   4: div label { 

   5:      width: 25%; 

   6:      float: left; 

   7: } 

   8: div input { 

   9:      width: 70%; 

  10: }
Combinando los ejemplos anteriores con otras reglas CSS además de posicionarlos se pueden cambiar el aspecto y comportamiento visual de los componentes utilizando pseudo-clases después de los selectores.
Espero les haya servido de ayuda.




{ Leer Más }


martes, 1 de diciembre de 2015

Alternando bases de datos sobre CodeIgniter

En este artículo mostraré como conectar manualmente a una base de datos, lo que resulta útil por ejemplo cuando se desea alternar entre dos o más bases de datos en una misma aplicación web.

Como es conocido, en el fichero application/config/database.php se especifica el nombre de la BD a la que nos conectaremos y la conexión se hará automáticamente. Pero hay situaciones en las que es posible desear manipular más de una base de datos, por ejemplo supongamos que se tienen dos sitios, uno de administración y otro con el contenido público, y que en determinado momento se desea consultar la BD de administración para mostrar algo en el sitio público.

En este caso lo primero sería modificar el fichero database.php de configuración y adicionar un nuevo grupo (o tantos como se desee), de la siguiente manera:

   1: $active_group = 'public';
   2: $active_record = TRUE;
   3:  
   4: $db['public']['hostname'] = 'localhost';
   5: $db['public']['username'] = 'root';
   6: $db['public']['password'] = '';
   7: $db['public']['database'] = 'my_public_db';
   8: $db['public']['dbdriver'] = 'mysql';
   9: $db['public']['dbprefix'] = '';
  10: $db['public']['pconnect'] = TRUE;
  11: $db['public']['db_debug'] = TRUE;
  12: $db['public']['cache_on'] = FALSE;
  13: $db['public']['cachedir'] = '';
  14: $db['public']['char_set'] = 'utf8';
  15: $db['public']['dbcollat'] = 'utf8_general_ci';
  16: $db['public']['swap_pre'] = '';
  17: $db['public']['autoinit'] = TRUE;
  18: $db['public']['stricton'] = FALSE;
  19:  
  20:  
  21: $db['admin']['hostname'] = 'localhost';
  22: $db['admin']['username'] = 'root';
  23: $db['admin']['password'] = '';
  24: $db['admin']['database'] = 'my_admin_db';
  25: $db['admin']['dbdriver'] = 'mysql';
  26: $db['admin']['dbprefix'] = '';
  27: $db['admin']['pconnect'] = TRUE;
  28: $db['admin']['db_debug'] = TRUE;
  29: $db['admin']['cache_on'] = FALSE;
  30: $db['admin']['cachedir'] = '';
  31: $db['admin']['char_set'] = 'utf8';
  32: $db['admin']['dbcollat'] = 'utf8_general_ci';
  33: $db['admin']['swap_pre'] = '';
  34: $db['admin']['autoinit'] = TRUE;
  35: $db['admin']['stricton'] = FALSE;

Nótese que se tienen dos grupos donde la primera llave especifica el nombre del grupo y la segunda el parámetro (por ejemplo $db['public']['database']… especifica el parámetro “nombre de base de datos” del grupo “public”). En el ejemplo de arriba he creado dos grupos, “admin” y “public”, y al inicio del código he declarado como grupo activo el public.

Automáticamente todas las consultas que se hagan en el modelo se harán sobre la BD “my_public_db” que es la activa por defecto, y se buscarán aquí las tablas, relaciones y consultas especificadas.

Ahora, la forma de cargar una BD determinada es usando la sentencia:



   1: $this->load->database('nombre_de_grupo');


Pero se puede usar de la siguiente forma:



   1: $this->db = $this->load->database(' nombre_de_grupo ', TRUE);


Donde el parámetro TRUE permite devolver el objeto DATABASE, que en este caso lo estamos guardando sobre la misma variable $this->db de CodeIgniter, así en los modelos podremos seguir utilizando esta variable transparentemente sin importar a cuál base de datos estemos conectados.

Sabiendo esto, para alternar momentáneamente entre bases de datos basta con poner a nivel de controladores algo como esto:



   1: $this->db = $this->load->database('admin', TRUE);
   2: $records = $this->my_admin_model->get_example_data();
   3: $this->db = $this->load->database('public', TRUE);
   4: //usar $records

En la primera línea se carga la configuración del grupo “admin” y por tanto la base de datos “my_admin_db”; en la segunda línea se consulta la misma; y en la tercera línea se restablece la configuración del grupo “public” con la base de datos “my_public_db”.

Como alternativa, se pueden conectar simultáneamente varias bases de datos, como ilustra el siguiente ejemplo de la documentación de CodeIgniter:



   1: $DB1 = $this->load->database('grupo_uno', TRUE);
   2: $DB2 = $this->load->database('grupo_dos', TRUE);

Y en lugar de usar el objeto $this->db se usarían los objetos $DB1 y $DB2:

   1: $DB1->query();
   2: $DB1->result();
   3: etc...


Es todo, espera les sea de utilidad e interés el tema.

{ Leer Más }


martes, 17 de noviembre de 2015

Trabajo con elementos select multiples (jQuery)

En este artículo quiero tratar el tema sobre cómo trabajar con los componentes html select multiple.

image

Supón que, en tu sitio tienes un la necesidad de cargar en una vista similar a la que se muestra encima en la que cargas todas las posibles opciones en el componente origen y necesitas que el usuario tenga la capacidad de seleccionar varias de ellas agregándolas al componente destino para luego hacer un tratamiento con las seleccionadas.

Para hacer lo antes comentado se crea la vista con dichos componentes y cargando en el origen los valores deseados. Debajo un ejemplo de cómo quedaría el origen:

   1: <h4>Origen</h4>
   2: <select name="data_source" id="data_source" size="5" multiple>
   3:  <option value="1">opcion 1</option>
   4:
   5:  <option value="n">opcion n</option>
   6: </select>
   7: <input type="button" id="asc" value="asc"/>
   8: <input type="button" id="desc" value="desc"/>


Ahora veremos cómo desarrollar las diferentes funcionalidades para los botones, el primer seria el agregar todos (>>):



   1: //se realiza la función en el evento click del botón
   2: $('#all_plus').click(function(e) {
   3:    //se separan del origen y se guardan en una variable los elementos                                                                                             option 
   4:    var $option = $('#data_source option').detach();
   5:    //luego se le agregan al componente destino con la función append
   6:    $('#data_destiny').append($option);
   7: });


La funcionalidad eliminar todos (<<) seria igual solamente habría que intercambiar el origen y el destino en este caso llamados por los id (data_source y data_destiny).

Para las funcionalidades de agregar (>) y eliminar (<), es algo muy parecido solo que hay que tener en cuenta el elemento option seleccionado y no todos los hijos del select, algo como esto es lo que haría falta:



   1: //se realiza la función en el evento click del botón
   2: $('#minus').click(function(e) {
   3:   //en separa del elemento select la opción seleccionada y se guarda en una variable
   4:   var $option = $('#data_destiny :selected').detach();
   5:   //luego se le agrega el otro componente select con la función append
   6:   $('#data_source').append($option);
   7: });


En el ejemplo anterior se mostró el eliminar (<), como se dijo anteriormente solo es cuestión de intercambiar los id para lograr obtener el agregar.

Espero les haya servido de ayuda.

{ Leer Más }


lunes, 9 de noviembre de 2015

Exportando a PDF sobre CodeIgniter

En este artículo les voy a poner dos ejemplos del uso de bibliotecas externas en este caso para generar un PDF con información para mostrar en el navegador o descargar si se tiene definido. La necesidad está en posicionar en nuestro sitio alguna opción de descargar información (que se esté mostrando o no) pero en formato de pdf. Estaremos hablando de las bibliotecas mpdf y fpdf como soluciones a este problema, ambas compatibles con el framework de desarrollo CodeIgniter.

MPDF

La biblioteca mpdf es una de las más difundidas y usadas sobre CodeIgniter (y la que he estado usando durante largo tiempo en el desarrollo de mis sitios, hasta chocar con un inconveniente que comentaré más adelante). Se puede descargar desde varios sitios, descompactada tiene unos 26.5 MB.

El trabajo con la mpdf básicamente consiste en pasarle un stream de código HTML y definir si se desea enviar el resultado del procesamiento hacia el navegador o abrir la típica ventana de Abrir/Salvar archivo.

Como siempre recomiendo, sobre CodeIgniter resulta útil definir una interfaz entre nuestra aplicación y la biblioteca externa, en este caso pudiera llamar mpdf_manager y no es necesario que herede de ninguna otra clase.

En el encabezado de nuestro fichero incluiríamos la mpdf con:

   1: include('mpdf/mpdf.php');


Y se podrían definir dos funciones según como se quiera mostrar el PDF originado:



   1: function open_in_browser($html_content)
   2:  {
   3:         $mpdf=new mPDF();
   4:         $mpdf->WriteHTML($html_content);
   5:         $mpdf->Output();
   6:  }
   7:  
   8: function save_to_pdf($html_content, $file_name)
   9: {
  10:         $mpdf=new mPDF();
  11:         $mpdf->WriteHTML($html_content);
  12:         $mpdf->Output($file_name, 'D');
  13: }
  14:  


La primera abre el PDF embebido en el navegador, mientras que la segunda da la posibilidad de salvarlo. En ambos casos se pasa un $html_content que no es más que el código HTML que se quiere imprimir en el PDF, y también se puede pasar el parámetro $file_name con el que se desea guardar el fichero.

Para usar estas funciones desde un controlador se podría hacer de la siguiente manera:



   1: $view = $this->load->view('pdf_print_view.php', $data, true);
   2: $this->load->library('mpdf_manager');
   3: $this->mpdf_manager->save_to_pdf($view, 'Registro_Taller.pdf');


Es decir, se utiliza la función load->view de codeigniter para cargar el contenido HTML desde una vista (en este ejemplo estoy pasando un $data para generar una página con datos dinámicos). Recordar usar el tercer parámetro con valor true para obtener el HTML en la variable $view en vez de abrir la página en el navegador.

Luego de cargar la vista en la variable $view cargo la biblioteca interfaz mpdf_manager y utilizo la función para salvar el PDF hacia la PC.

Otra facilidad interesante de la biblioteca mpdf es la posibilidad de insertar saltos de páginas y varios contenidos HTML, por lo que las funciones antes presentadas se pueden modificar para recibir un arreglo de códigos HTML y luego en un ciclo combinar las funciones:



   1: //dentro de un ciclo!!
   2: $mpdf->WriteHTML($html_content_i);
   3: $mpdf->AddPage();


Si no se deseara cargar una vista para generar el pdf pues sencillamente se puede escribir el código “a mano”, ejemplo:



   1: <div>
   2:         <strong>mi texto</strong>
   3: </div>


FPDF

La biblioteca mpdf brinda una gran flexibilidad en cuanto a que se le puede pasar una vista en HTML prediseñada, pero cuando se le pasan muchos datos resulta demasiado lenta. Por ejemplo suponga que tiene una vista con una tabla donde se muestran datos de un estudiante, y que cíclicamente se pasan datos de estudiantes a dicha vista y luego ese contenido se le pasa a la biblioteca mpdf… si se tramitan por ejemplo unos 1500 estudiantes puede tardarse hasta 20 minutos para generar el PDF (sin caer en demasiados detalles de las prestaciones de la PC utilizada ni los datos enviados, se podría decir que algo que le demore más de 5 segundos a un usuario se puede considerar como lento en algunas ocasiones).

En estos casos se puede acudir a la biblioteca FPDF como alternativa.

Esta biblioteca es un poco más difícil o incómoda de utilizar pero sí resulta mucho más rápida (el ejemplo de arriba se puede generar en unos pocos segundos así que la diferencia de velocidad es abismal), y se puede utilizar en el mismo ejemplo anterior donde lo que se está llevando al PDF son tablas sencillas.

En este caso se definiría una interfaz que herede de la biblioteca FPDF



   1: require('fpdf/fpdf.php');
   2: class fpdf_manager extends FPDF


Y utilizando los mismos ejemplos que vienen con la distribución de la biblioteca, se incluyen 3 funciones predefinidas para sobrecargar las existentes en la FPDF: Header, para definir el encabezado de las páginas; Footer, para definir los pies de páginas, y FancyTable para generar el contenido de las páginas. El código sería aproximadamente así:



   1: //Page header
   2: function Header()
   3: {
   4:         //Logo
   5:         $this->Image(base_url().'images/logo.jpg', 40, 12, 40);
   6:         //Arial bold 15
   7:         $this->SetFont('Arial', 'B', 15);
   8:         //Move to the right
   9:         $this->Cell(70);
  10:         $this->Cell(30, 10, "ESTE ES UN TEXTO DE ENCABEZADO", 0, 0, 'L');
  11:         $this->Ln(6);
  12:         $this->Cell(70);
  13:         $this->Cell(30, 10, "SEGUNDA LÍNEA DEL TEXTO", 0, 1, 'L');
  14:         $this->Ln(12);
  15: }
  16:  
  17: //Page footer
  18: function Footer()
  19: {
  20:         //Position at 1.5 cm from bottom
  21:         $this->SetY(-15);
  22:         //Arial italic 8
  23:         $this->SetFont('Arial', 'I', 8);
  24:         //Page number
  25:         $this->Cell(0, 10, $this->PageNo(), 0, 0, 'C');
  26:         $this->Cell(0, 0, 'Copyright '.utf8_decode('©').' 2015 ', 0, 1, 'R');
  27: }


Sin entrar en demasiados detalles, en estas funciones se está definiendo un logo y un texto para el encabezado y una firma y copyright para el footer, usando funciones como SetX, SetY y Cell.

De igual forma dentro de la función FancyTable, que recibe como parámetros una tabla o grupos de tablas en formato de BD, se recorrería cada una de las tablas-datos enviadas y usando la función Cell y Ln para saltar de línea se construirían las tablas para mostrar los datos. Se puede usar la función SetFillColor para colorear las celdas y así dibujar tablas con filas de colores alternos. También se puede usar la función MultiCell para generar celdas con mucho texto y lograr un efecto de wrap del texto.

Desde un controlador se utilizaría la biblioteca de la siguiente manera:



   1: $this->load->library('fpdf_manager');
   2: $pdf = new fpdf_manager();
   3: $pdf->SetFont('Arial', '', 14);
   4: $pdf->AddPage();
   5: $pdf->FancyTable($tables);
   6: $pdf->Output('Datos de la empresa.pdf', 'D');


Como conclusión se podría decir que según el objetivo a lograr así sería la selección de la biblioteca a utilizar (de estas dos propuestas entre muchas otras que puedan existir): la mpdf resulta más cómoda de utilizar y más flexible a la hora de pasar un contenido html, mientras que la fpdf es un poco menos flexible pero muchísimo más rápida.

{ Leer Más }


IconIconIcon