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