DesarrolloLibre

Desarrollo Web, Android, juegos y mucho más

Categorias
21-08-2017

En una entrada anterior vimos cómo cargar archivos mediante CodeIgniter, en donde se explicó cómo crear un formulario en HTML para la carga de archivos, cómo recibir estos datos desde CodeIgniter en el controlador, parámetros de configuración y mostrar posibles errores al momento de realizar un upload o carga de archivo.

En esta entrada daremos un paso más y emplearemos el plugin llamado Dropzone, el cual permite realizar el Drag and Drop de nuestros archivos fácilmente; puedes obtener el plugin de manera gratuita desde el siguiente enlace:

http://www.dropzonejs.com/

Es un plugin que necesita jQuery para su, tiene un alto nivel de personalización y su instalación consiste en vincular el archivo JavaScript y de estilo correspondiente al plugin en nuestro documento:

<script src="<?php echo base_url() ?>assets/js/jquery.js"></script>

<link rel="stylesheet" href="<?php echo base_url() ?>assets/css/dropzone.min.css" rel="stylesheet" type="text/css" />

<script src="<?php echo base_url() ?>assets/js/dropzone.min.js"></script>
Con DropZone podemos manejar los archivos en nuestro servidor, ya que como veremos no solo permite cargar archivos via drag and drop, si no listar y eliminar nuestros archivos

Definiendo el formulario para la carga de archivos

No necesitamos un formulario en especial, solo colocarle un identificador para establecerlo en el código JavaScript que veremos más adelante y Dropzone se encargará del resto.

<form class="dropzone well" id="dropzone-ta" action="<?php echo base_url() ?>documento/cargar_ta/<?php echo $document->document_id ?>"></form>

Configurando en JS

Como todo en JavaScript, el funcionamiento es bastante fácil; se trata de sobrescribir métodos y de establecer valores a distintos parámetros según se requiera; parámetros para definir tamaño máximo de archivos, tipo de archivos, archivos permitidos, nombre del contenedor, número de archivos en carga y un largo etc; puedes ver la lista completa aquí:

Dropzone.js: Configuration options

Definiremos algunos parámetros como los siguientes:

paramName: "ta",
dictDefaultMessage: '<span class="bigger-150 bolder"><i class="ace-icon fa fa-caret-right red"></i> Arrastre el PDF para el TA - alta</span> \
                        <span class="smaller-80 grey">(o clic)</span> <br /> \
                        <i class="upload-icon ace-icon fa fa-cloud-upload blue fa-3x"></i>',
addRemoveLinks: true,
dictRemoveFile: "Eliminar",
uploadMultiple: false,
parallelUploads: 1,
maxFiles: 1,
acceptedFiles: "application/pdf"
El parámetro paramName permite definir el nombre del contenedor o de nuestro elemento (el nombre del input de tipo file en HTML clásico) que emplearemos para referenciarlo en nuestro PHP/CodeIgniter.

Con el código anterior definimos un mensaje por defecto en el bloque contenedor, habilitamos la funcionalidad para eliminar archivos, indicamos el nombre del tag del enlace a eliminar el archivo, indicamos que NO acepte múltiples uploads o cargas al mismo tiempo, que solo podemos cargar un archivo y que el único tipo de archivo permitido son PDF.

Método de eliminar archivos de Dropzone

Además del código anterior definiremos algunos métodos, el método para cuando eliminamos un archivo cargado de por vez mediante un enlace:

removedfile: function (file) {
    var _ref;
    $.ajax({
    url: "<?php echo base_url() ?>documento/eliminar_ta/<?php echo $document->document_id ?>",
                    data: {nombre: file.name},
                    type: 'POST',

                    success: function (data) {
                        //archivo eliminado con exito
                    },
                    error: function (data) {
                        // Error al eliminar el archivo
                    }
                });
    var _ref;
    return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;
},

En donde definimos un ajax solo para caso de ejemplo que es el que elimina dicho documento mediante el nombre del mismo.

Método de inicialización de Dropzone

El método de inicialización del plugin en donde podemos hacer tareas como la carga inicial de los archivos que se cargaron con anterioridad:

init: function () {

    var existingFiles = [
        {name: ta, size: 12345678},
    ];

    if (ta != "") {
        this.emit("addedfile", existingFiles[0]);
        this.emit("thumbnail", existingFiles[0], "<?php echo base_url() ?>uploads/<?php echo $document->document_id ?>/ta" + "/" + existingFiles[0].name);
        this.emit("complete", existingFiles[0]);
    }
}

Método de aceptación/rechazo de carga de archivos de Dropzone

Y por último el método que se ejecuta cuando cargamos algún archivo, aquí podemos emplear cualquier tipo de lógica que nosotros queramos y que no podemos emular con la configuración de los parámetros:

accept: function (file, done) {
     if (ta != "") {
         done("Error");
     } else {
         done();
     }
 },

Un punto importante es el uso de la función done(), si en la misma se define un parámetro, esto hará que el plugin Dropzone indique al usuario que la cargas se ejecutó con error con el mensaje que definamos como parámetro en dicha función:

dropzone error Upload

Finalmente, mostramos la totalidad del código JavaScript completo del experimento:

Dropzone.options.dropzoneTa = {
      paramName: "ta",
      dictDefaultMessage: '<span class="bigger-150 bolder"><i class="ace-icon fa fa-caret-right red"></i> Arrastre el PDF para el TA - alta</span> \
                              <span class="smaller-80 grey">(o clic)</span> <br /> \
                              <i class="upload-icon ace-icon fa fa-cloud-upload blue fa-3x"></i>',
      addRemoveLinks: true,
      dictRemoveFile: "Eliminar",
      uploadMultiple: false,
      parallelUploads: 1,
      maxFiles: 1,
      acceptedFiles: "application/pdf",
      removedfile: function (file) {
          var _ref;
          $.ajax({
              url: "<?php echo base_url() ?>documento/eliminar_ta/<?php echo $document->document_id ?>",
                              data: {nombre: file.name},
                              type: 'POST',

                              success: function (data) {
                                  //archivo eliminado con exito
                              },
                              error: function (data) {
                                  // Error al eliminar el archivo
                              }
                          });

                          var _ref;
                          return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;
                      },
                      accept: function (file, done) {
                          if (ta != "") {
                              done("Error");
                          } else {
                              done();
                          }
                      },
                      init: function () {

                          var existingFiles = [
                              {name: ta, size: 12345678},
                          ];

                          if (ta != "") {
                              this.emit("addedfile", existingFiles[0]);
                              this.emit("thumbnail", existingFiles[0], "<?php echo base_url() ?>uploads/<?php echo $document->document_id ?>/ta" + "/" + existingFiles[0].name);
                              this.emit("complete", existingFiles[0]);
                          }
                      }

                  };

Definiendo el controlador en CodeIgniter para la carga del archivo

Por último nuestro método en CodeIgniter que no ha variado demasiado con el presentado en la entrada cómo cargar archivos mediante CodeIgniter:

 public function cargar_certificado($documento_id = null) {

        if (!isset($documento_id)) {
            show_404();
        }

        $document = $this->Document->find($documento_id);

        if (!isset($document)) {
            show_404();
        }

        $this->subir_pdf($document->document_id);
    }

private function subir_pdf($document_id) {

        $dir = 'uploads/' . $document_id . '/' . $tag;
        if (!is_dir($dir)) {
            mkdir($dir, 0755, TRUE);
        }

        // preparo los parametros para la subida de la foto

        $nombre = 'pdf_' . $document_id . "_" . $tag;
        $config['upload_path'] = $dir;
        $config['file_name'] = $nombre;
        $config['allowed_types'] = "pdf";
//        $config['max_size'] = "100000";
        $config['overwrite'] = TRUE;

        // carga modelos, helper y vistas
        $this->load->library('upload', $config);

        // ocurrio un error
        if (!$this->upload->do_upload($tag)) {

            $data['uploadError'] = $this->upload->display_errors();
            $this->session->set_flashdata('messageError', $this->upload->display_errors());
            echo $this->upload->display_errors();
            return;
        }

        // informacion acerca de la subida
    // $data = $this->upload->data();

    // hacer algo con el nombre del archivo en base de datos
    $this->Document->ta($nombre . ".pdf", $document_id);    
}

Cómo vemos, el código no ha variado mucho con el presentado en cómo cargar archivos mediante CodeIgniter; definimos algunas validaciones de ejemplo sobre la validación a un supuesto identificador de un documento y luego invocamos el método subir_pdf() que se encarga de realizar la carga correspondiente; se realizó la carga del archivo en una función con el objetivo de hacerlo más modular, dicha implementacion de carga de archivo puede seguir funcionando dentro de la acción del controlador.

Un punto interesante es que colocamos cada archivo en un directorio específico creado de manera automática con el método mkdir.

Extra: función de eliminación

Como un extra mostramos el cuerpo de la acción para la eliminación de un archivo, esto incluye una función para eliminar el registro en base de datos y de la carpeta:

public function eliminar_ta($documento_id = null) {

    if (!isset($documento_id)) {
        show_404();
    }

    $document = $this->Document->find($documento_id);

    if (!isset($document)) {
        show_404();
    }

    // elimino el documento
    unlink('uploads/' . $document->document_id . '/ta/' . $document->ta);
    $this->Document->ta(NULL, $document->document_id);
}

Publicidad

Give me for a beer!

Algunos recursos que te pueden interesar

InstaStream: plugin para mostrar imágenes desde Instagram

InstaStream: plugin para mostrar imágenes desde Instagram

API REST en CodeIgniter

API REST en CodeIgniter

Monthly.js : Plugin de jQuery para eventos en el calendario

Monthly.js : Plugin de jQuery para eventos en el calendario

Algunos artículos que te pueden interesar

Detectando la Orientación de un dispositivo con jQuery Mobile

Detectando la Orientación de un dispositivo con jQuery Mobile

En esta entrega veremos como podemos detectar o capturar la rotación de un dispositivo con jQuery Mobile.

Andrés Cruz 17-07-2014

Procesamiento simple de imágenes con CodeIgniter

Procesamiento simple de imágenes con CodeIgniter

Andrés Cruz 16-01-2018

4 formas de pintar mapas con jQuery y JavaScript

4 formas de pintar mapas con jQuery y JavaScript

Se muestran 4 plugins de pago/gratuitos para dibujar mapas vectorizados con HTML nativo en nuestra web a través de jQuery.

Andrés Cruz 25-04-2016