DragDropFile Au niveau ergonomie, le drag and drop de fichiers est intuitif et de plus en plus utilisé sur les sites web tel que drive, gmail, wordpress, … Voici comment ça marche

Le principe est de rajouter des listeners sur un div afin qu’il soit réactif aux événements souris drag and drop. Ces évènements sont des évènements HTML5 et donc disponibles sur les versions récentes des navigateurs!

//Récupération de l'élément div id="divTarget"
filedrag = document.getElementById('divTarget');

//Ajout des listeners
filedrag.addEventListener("dragover", fFileDragHover, false);
filedrag.addEventListener("dragleave", fFileDragHover, false);
filedrag.addEventListener("drop", fFileSelectHandler, false);

Les deux premiers évènements appellent une fonction qui va gérer le css de la zone en fonction du survol de la souris.
Le dernier évènement appelle la fonction qui va récupérer le fichier pour le mettre en ligne.

Si on “drop” un fichier, on doit stopper les actions par défaut, c’est à dire l’ouverture du fichier par le navigateur.

e.stopPropagation();
e.preventDefault();

L’objet évènement ‘e’ contient plusieurs infos dont le type d’évènement, le div cible, le fichier, …

//Récupération du ou des fichiers
var aFiles = e.target.files || e.dataTransfer.files;

Exemple de fonctions :

// File drag hover : Changement du css de la zone cible
function fFileDragHover(e)
    e.stopPropagation();
    e.preventDefault();
    e.target.className = (e.type == "dragover" ? "filedrag filedragHover" : "filedrag");
}
// file selection
function fFileSelectHandler(e) {

    //Récupère l'id de la cible
    idTarget = e.currentTarget.id;

    // cancel event and hover styling
    fFileDragHover(e);

    // fetch FileList object
    var files = e.target.files || e.dataTransfer.files;

    // process all File objects
    for (var i = 0, f; f = files[i]; i++) {
        UploadFile(f,idTarget);
    }
}

La fonction UploadFile va gérer l’upload du fichier! Cela peut être en ajax, en appelant un webservice / API (exemple google Drive), où en soumettant un form tous simplement.
NB : J’ai passé l’id de la cible au niveau de la fonction car j’ai nommé mes autres élements avec ce nom comme suffixe : “upload_divTarget”, “form_divTarget”, … ça me permet de dynamiser ce mécanisme.

function UploadFile(file,idTarget) {
     var xhr = new XMLHttpRequest();
     if (xhr.upload){
         //Fonctions supplémentaires
         ...

         // start upload
         xhr.open("POST", document.getElementById("upload_"+idTarget).action, true);
         xhr.setRequestHeader("X_FILENAME", file.name);
         xhr.send(file);
     }
}

Cette fonction crée un objet XMLHttpRequest qui va faire l’envoi du fichier en ajax. On peut rajouter de l’information dans le header (via setRequestHeader) afin de les récupérer côté serveur.

On peut agrémenter cette fonction en rajoutant des contrôles sur le fichier (taille, extension, …). Par exemple :

...
if (xhr.upload){
        //Si la taille du fichier dépasse la limte on affiche un message
        if(file.size >= 2000000) {
            alert('La taille du fichier dépasse la limite de 2 Mo');
            return false;
        }

        //Contrôle sur l'extension du fichier
        var _invalidFileExtensions = [".cfm", ".cfc", ".exe"];
        var sFileName = file.name;
        if (sFileName.length > 0) {
              var blnValid = false;
              for (var j = 0; j < _invalidFileExtensions.length; j++) {
                  var sCurExtension = _invalidFileExtensions[j];
                  if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
                        blnValid = true;
                        break;
                   }
              }

              if (blnValid) {
                    alert("Désolé, l'extension du fichier " + sFileName + " n'est pas valide");
                    return false;
              }
       }
...

Ou une barre de progression :

<!-- Création d'une div qui sera la barre de progression -->
<div id="progress_divTarget"></div>
function UploadFile(file,idTarget) {
     var xhr = new XMLHttpRequest();
     if (xhr.upload){

          //Fonction de contrôle sur les fichiers
          ...

          // create progress bar
          var o = document.getElementById("progress_"+idTarget);
          var progress = o.appendChild(document.createElement("p"));
          progress.appendChild(document.createTextNode("upload " + file.name));

          // progress bar
          xhr.upload.addEventListener("progress_"+idTarget, function(e) {
               var pc = parseInt(100 - (e.loaded / e.total * 100));
               progress.style.backgroundPosition = pc + "% 0";
          }, false);

          // file received/failed - Changement class css suivant la réponse
          xhr.onreadystatechange = function(e) {
             if (xhr.readyState == 4) {
                progress.className = (xhr.status == 200 ? "success" : "failure");
             }
          };

...

Plus d’infos :
http://www.w3schools.com/html/html5_draganddrop.asp
http://www.sitepoint.com/html5-file-drag-and-drop/

SBU

 Last News