bigup.js 28,77 Kio
/**
* Pour un input de type file sélectionné,
* gère l'upload du ou des fichiers, via html5 et flow.js
*
* Retourne uniquement la liste des input qui viennent
* d'être activés avec bigup.
*
* Ça permet de gérer des callbacks derrière, sans ajouter
* la callback à chaque rechargement ajax du js.
*
* $('input.bigup')
* .bigup()
* .on('bigup.fileSuccess', function(...){...});
*
* On peut aussi envoyer une fonction de callback directement.
*
* $('input.bigup').bigup({}, {
* fileSuccess: function(...){...},
* });
*
* Où pour quand les uploads sont terminés
*
* $('input.bigup').bigup({}, {
* complete: function(){...},
* });
*
* @param object options
* @param object callbacks
* @return jQuery
*/
$.fn.bigup = function(options, callbacks) {
// les options… on verra si on l'utilisera
var options = options || {};
// les callbacks éventuelles directes
var callbacks = callbacks || {};
var inputs_a_gerer = $(this).not(".bigup_done").each(function() {
var $editer = $(this).closest('.editer');
if ($editer.length) {
$editer.addClass('biguping');
var h = $editer.get(0).offsetHeight;
var s = $editer.attr('style');
if (typeof s === "undefined") {
s = '';
}
$editer.attr('data-prev-style',s);
s += 'height:'+h+'px;overflow:hidden';
$editer.attr('style',s);
}
// indiquer que l'input est traité. Évite de charger plusieurs fois Flow
$(this).addClass('bigup_done');
var $input = $(this);
var $form = $input.parents('form');
// Équivalent au filtre sinon
var sinon = function(valeur, defaut) {
return valeur ? valeur : defaut;
}
// config globale de bigup.
var conf = $.extend(true, {
maxFileSize: 0
}, $.bigup_config || {});
var bigup = new Bigup(
{
form: $form,
input: $input,
formulaire_action: $form.find('input[name=formulaire_action]').val(),
formulaire_action_args: $form.find('input[name=formulaire_action_args]').val(),
token: $input.data('token')
},
{
contraintes: {
accept: $input.prop('accept'),
maxFiles: ($input.prop('multiple') ? sinon($input.data('maxfiles'), 0) : 1),
maxFileSize: sinon($input.data('maxfilesize'), conf.maxFileSize),
}
},
callbacks
);
if (!bigup.support) {
return false;
}
// Prendre en compte les fichiers déjà présents à l'ouverture du formulaire
bigup.integrer_fichiers_presents();
// Gérer le dépot de fichiers
bigup.gerer_depot_fichiers();
if ($editer.length) {
$editer.attr('style',$editer.attr('data-prev-style'));
$editer.attr('data-prev-style',null);
$editer.addClass('editer_with_bigup').removeClass('biguping');
}
});
return inputs_a_gerer;
}
/**
* Bigup gère les fichiers des input concernés (avec Flow.js)
* et leur communication avec SPIP
*
* Nécessite un accès à Trads.
*
* @param [params]
* @param {jquery} [params.form]
* @param {jquery} [params.input]
* @param {string} [params.formulaire_action]
* @param {string} [params.formulaire_action_args]
* @param {string} [params.token]
* @param [opts]
* @param {object} [opts.contraintes]
* @param {string} [opts.contraintes.accept]
* @param {int} [opts.contraintes.maxFiles]
* @param {int} [opts.contraintes.maxFileSize]
* @param {int} [opts.flow.simultaneousUploads]
* @param {int[]} [opts.flow.permanentErrors]
* @param {int} [opts.flow.chunkRetryInterval]
* @param {int} [opts.flow.maxChunkRetries]
* @param [callbacks]
* @param {function} [callbacks.fileSuccess]
* @constructor
*/
function Bigup(params, opts, callbacks) {
this.form = params.form;
this.input = params.input;
this.formulaire_action = params.formulaire_action;
this.formulaire_action_args = params.formulaire_action_args;
this.token = params.token;
this.target = $.enlever_ancre(this.form.attr('action'));
this.name = this.input.attr('name');
this.class_name = $.nom2classe(this.name);
this.multiple = this.input.prop('multiple');
this.zones = {
depot: null,
depot_etendu: null,
fichiers: null
};
this.defaults = {
contraintes: {
accept: '',
maxFiles: 1,
maxFileSize: 0
},
options: {
// previsualisation des images
previsualisation: {
activer: !!this.input.data("previsualiser"),
fileSizeMax: 10 // 10 Mb
}
},
flow: {
simultaneousUploads: 2, // 3 par défaut
permanentErrors : [403, 404, 413, 415, 500, 501], // ajout de 403 à la liste par défaut.
chunkRetryInterval: 1000, // on rééssaye de télécharger le chunk après 1s si erreur
maxChunkRetries: 5,
},
templates: {
zones: {
// Zone de dépot des fichiers
depot: function (name, multiple) {
var template =
'\n<div class="dropfile dropfile_' + name + '" style="display:none;">'
+ '\n\t<span class="dropfilebutton bigup-btn btn btn-default">'
+ _T('bigup:choisir')
+ '</span>'
+ '\n\t<span class="dropfileor">' + _T('bigup:ou') + '</span>'
+ '\n\t<span class="dropfiletext">'
+ '\n\t\t'
+ Trads.singulier_ou_pluriel(multiple ? 2 : 1, 'bigup:deposer_votre_fichier_ici', 'bigup:deposer_vos_fichiers_ici')
+ '\n\t</:span:>'
+ '\n</div>\n';
return template;
},
// Zone de liste des fichiers déposés (conteneur)
fichiers: function (name) {
var template = "<div class='bigup_fichiers fichiers_" + name + "'></div>";
return template;
},
},
// Présentation d'un fichier déposé
fichier: function(file) {
// retouver l'extension
var extension = $.trouver_extension(file.name);
var template =
'\n<div class="fichier">' +
'\n\t<div class="description">' +
'\n\t\t<div class="vignette_extension ' +
$.escapeHtml(extension) +
'" title="' +
file.type +
'"><span></span></div>' +
'\n\t\t<div class="infos">' +
'\n\t\t\t<span class="name"><strong>' +
$.escapeHtml(file.name) +
'</strong></span>' +
'\n\t\t\t<span class="size">' +
$.taille_en_octets(file.size) +
'</span>' +
'\n\t\t</div>' +
'\n\t\t<div class="actions">' +
'\n\t\t\t<span class="bigup-btn btn btn-default cancel" onClick="$.bigup_enlever_fichier(this);">' +
_T('bigup:bouton_annuler') +
'</span>' +
'\n\t\t</div>' +
'\n\t</div>' +
'\n</div>\n';
return template;
}
}
};
/**
* Current options
* @type {Object}
*/
this.opts = $.extend(true, this.defaults, opts || {});
// Un seul fichier aussi si multiple avec max 1 file.
this.singleFile = !this.multiple || (this.opts.contraintes.maxFiles === 1);
// Ajoute chaque callback transmise
var me = this;
$.each(callbacks || {}, function(nom, callback) {
me.input.on('bigup.' + nom, callback);
});
// La librairie d'upload
this.flow = new Flow({
input: this.input,
target: this.target,
testChunks: true,
maxFiles: this.opts.contraintes.maxFiles,
singleFile: this.singleFile,
simultaneousUploads: this.opts.flow.simultaneousUploads,
permanentErrors : this.opts.flow.permanentErrors,
chunkRetryInterval : this.opts.flow.chunkRetryInterval,
maxChunkRetries: this.opts.flow.maxChunkRetries,
onDropStopPropagation: true, // ne pas bubler quand la drop zone est multiple
query: {
action: "bigup",
bigup_token: this.token,
formulaire_action: this.formulaire_action,
formulaire_action_args: this.formulaire_action_args,
}
});
// sait on gérer (upload html5 requis) ?
this.support = this.flow.support;
// Bigup accessible depuis l'input
this.input.data('bigup', this);
/**
* On drop extended event
*
* On ne bloque pas la cascade des événements si on ne dépose pas de fichiers
* @function
* @param {MouseEvent} event
*/
this.onDropExtended = function (event) {
if (me.eventHasFiles(event)) {
me.flow.onDrop(event);
/* Parfois on arrive à droper sur un bigup alors qu’une zone étendue d’un autre bigup est ouverte */
$('.bigup-extended-drop-zone.drag-over').trigger('dragleave');
}
}
}
Bigup.prototype = {
/**
* Redéfinir des options
* @param object options Options à modifier
*/
setOptions: function(options) {
options = options || {};
this.opts.options = $.extend(true, this.opts.options, options);
},
/**
* Intégrer les fichiers déjà listés dans la zone des fichiers, au chargement du formulaire
*
* Remplacer les boutons "Enlever" d'origine sur les fichiers déjà présents
* dans le formulaire (listés au dessus du champ).
* On remplace par un équivalent qui fera la chose en pur JS + ajax
*
* Affecter l'objet bigup sur chaque emplacement de fichier pour facilités.
*/
integrer_fichiers_presents: function() {
// Définir la zone de listing des fichiers
this.creer_zone_fichiers();
var me = this;
// Trouver les fichiers s'il y en a
this.zones.fichiers.find('.fichier').each(function(){
var $button = $(this).find("button[name=bigup_enlever_fichier]");
var identifiant = $button.val();
$button.remove();
$(this)
.data('bigup', me)
.data('identifiant', identifiant);
me.ajouter_bouton_enlever(this);
});
this.input.trigger('bigup.ready', [me]);
},
/**
* Ajoute un "Enlever" sur un fichier
*
* @param string fichien DOM de l'emplacement de présentation du fichier
*/
ajouter_bouton_enlever: function(fichier) {
var js = "$.bigup_enlever_fichier(this); return true;";
var inserer = '<span class="bigup-btn btn btn-default" onClick="' + js + '">'
+ _T('bigup:bouton_enlever')
+ '</span>';
$(fichier).find('.actions').append(inserer);
return this;
},
/**
* Gérer le dépot des fihiers
*/
gerer_depot_fichiers: function() {
this.definir_zone_depot();
var me = this;
// Présenter le fichier dans liste des fichiers en cours
// Valider le fichier déposé en fonction du 'accept' de l'input (si présent).
this.flow.on('fileAdded', function(file, event) {
me.ajouter_fichier(file);
me.input.trigger('bigup.fileAdded', [file]);
me.adapter_visibilite_zone_depot();
if (!me.accepter_fichier(file)) {
me.presenter_erreur(file.emplacement, file.erreur);
return false;
}
});
// Téléverser aussitôt les fichiers valides déposés
this.flow.on('filesSubmitted', function (files) {
if (files.length) {
$.each(files, function(key, file) {
me.progress.ajouter(file.emplacement);
me.input.trigger('bigup.fileSubmitted', [file]);
});
me.flow.upload();
}
});
// Actualiser la barre de progression de l'upload
this.flow.on('fileProgress', function(file, chunk){
var percent = Math.round(file._prevUploadedSize / file.size * 100);
var progress = file.emplacement.find('progress');
progress.text( percent + " %" );
me.progress.animer(progress, percent);
});
// Réussite de l'opload :
// Adapter le bouton 'Annuler' => 'Enlever'
// Retirer la barre de progression
this.flow.on('fileSuccess', function(file, message, chunk){
// console.info("success", file, message, chunk);
var desc = "";
try {
desc = JSON.parse(message);
// enlever le bouton annuler
file.emplacement.find(".cancel").fadeOut("normal", function(){
$(this).remove();
// et mettre un bouton enlever !
if (desc.bigup.identifiant) {
file.emplacement.data('identifiant', desc.bigup.identifiant);
me.ajouter_bouton_enlever(file.emplacement);
}
});
me.progress.retirer(file.emplacement.find("progress"));
me.input.trigger('bigup.fileSuccess', [file, desc]);
} catch(e) {
desc = _T('bigup:erreur_de_transfert')+" : "+e;
me.progress.retirer(file.emplacement.find("progress"));
me.presenter_erreur(file.emplacement, desc);
}
});
// Un fichier a été enlevé, soit par nous, soit par Flow
// lorsqu'on a ajouté un fichier supplémentaire alors que la saisie
// attend un fichier unique.
this.flow.on('fileRemoved', function(file) {
// si ce n'est pas nous qui avons supprimé ce fichier
if (!file.bigup_deleted) {
me.enlever_fichier(file.emplacement);
}
});
// Rajoute l'Events complete()
// qui se déclenche quand tous les upload sont terminés
this.flow.on('complete', function () {
//console.log("uploads Completed");
me.input.trigger('bigup.complete');
});
// Erreur, pas de bol !
// Afficher l'erreur
// Retirer la barre de progression
this.flow.on('fileError', function(file, message, chunk){
console.warn("error", file, message, chunk);
var message_erreur = _T('bigup:erreur_de_transfert');
if (message) {
try {
data = JSON.parse(message);
if (typeof data.error !== 'undefined') {
message_erreur = data.error;
}
} catch(e){
message_erreur += " : "+e;
}
}
me.progress.retirer(file.emplacement.find("progress"));
me.presenter_erreur(file.emplacement, message_erreur);
});
},
/**
* créer la zone de dépot et l'indiquer à Flow.js
*/
definir_zone_depot: function() {
// Cacher l'input original
this.input.hide();
this.creer_zone_depot();
// Voir la zone, si on n'a pas déjà atteint le quota de fichiers
this.adapter_visibilite_zone_depot();
// Assigner la zone et son bouton à flow.
this.flow.assignBrowse(
this.zones.depot.find('.dropfilebutton'),
false,
!this.multiple,
{accept: this.opts.contraintes.accept}
);
this.assignDropExtended(this.zones.depot_etendu);
},
/**
* Créer la zone de dépot des fichiers
*/
creer_zone_depot: function() {
$.bigup_verifier_depots_etendus();
// Trouver une zone où déposer les fichiers dans le HTML existant
var $zone_depot = this.form.find(".dropfile_" + this.class_name);
// S'il n'y en a pas, créer le template par défaut et l'ajouter
if (!$zone_depot.length) {
var template = this.opts.templates.zones.depot(this.class_name, !this.singleFile);
this.input.after(template);
$zone_depot = this.form.find(".dropfile_" + this.class_name);
}
// gerer une eventuelle zone etendue
var $depot_etendu = $zone_depot;
var depot_etendu = this.input.data('drop-zone-extended');
if (typeof depot_etendu !== "undefined") {
$depot_etendu = jQuery(depot_etendu)
.not('.bigup-extended-drop-zone')
.addClass('bigup-extended-drop-zone')
.data('bigup', this)
.add($zone_depot);
}
var me = this;
$depot_etendu.on('dragenter dragover', function(event) {
if (me.eventHasFiles(event.originalEvent)) {
$(this).addClass('drag-over');
$zone_depot.addClass('drag-target');
}
});
$depot_etendu.on('dragleave', function(){
$(this).removeClass('drag-over');
$zone_depot.removeClass('drag-target');
});
$depot_etendu.on('drop', function(){
// drop ne buble pas, on enleve donc tout d'un coup
$depot_etendu.removeClass('drag-target').removeClass('drag-over');
});
this.zones.depot = $zone_depot;
this.zones.depot_etendu = $depot_etendu;
},
/**
* Créer la zone de listing des fichiers téléversés ou en cours de téléversement
*/
creer_zone_fichiers: function() {
// Trouver une zone où afficher les fichiers dans le HTML existant
var $fichiers = this.form.find(".fichiers_" + this.class_name);
// S'il n'y en a pas, créer le template par défaut et l'ajouter
if (!$fichiers.length) {
var template = this.opts.templates.zones.fichiers(this.class_name);
this.input.before(template);
$fichiers = this.form.find(".fichiers_" + this.class_name);
}
this.zones.fichiers = $fichiers;
},
/**
* Affiche ou cache la zone de dépot en fonction du nombre de fichiers déjà actifs
*/
adapter_visibilite_zone_depot: function() {
var nb = this.zones.fichiers.find(".fichier").length;
if (!this.opts.contraintes.maxFiles || (this.opts.contraintes.maxFiles > nb)) {
this.zones.depot.show();
} else {
this.zones.depot.hide();
}
},
/**
* Tester que le fichier est valide par rapport à l'attribut `accept` de l'input.
* @param FlowFile file
* @return true si OK.
*/
accepter_fichier: function(file) {
if (this.opts.contraintes.maxFileSize) {
var taille = this.opts.contraintes.maxFileSize * 1024 * 1024;
if (file.size > taille) {
file.erreur = _T('bigup:erreur_taille_max', {taille: $.taille_en_octets(taille)});
return false;
}
}
if (this.opts.contraintes.accept) {
var accept = this.opts.contraintes.accept;
if (accept && !this.valider_fichier(file.file, accept)) {
file.erreur = _T('bigup:erreur_type_fichier');
return false;
}
}
return true;
},
/**
* Vérifier un fichier par rapport à un attribut 'accept'
* Code issu de Dropzone.
*
* @param html5.file file
* @param html5.accept acceptedFiles
* @return bool
*/
valider_fichier: function(file, acceptedFiles) {
var baseMimeType, mimeType, validType, _i, _len;
if (!acceptedFiles) {
return true;
}
acceptedFiles = acceptedFiles.split(",");
mimeType = file.type;
baseMimeType = mimeType.replace(/\/.*$/, "");
for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) {
validType = acceptedFiles[_i];
validType = validType.trim();
if (validType.charAt(0) === ".") {
if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {
return true;
}
} else if (/\/\*$/.test(validType)) {
if (baseMimeType === validType.replace(/\/.*$/, "")) {
return true;
}
} else {
if (mimeType === validType) {
return true;
}
}
}
return false;
},
/**
* Ajoute le fichier transmis dans la liste des fichiers
*
* @param FlowFile file
*/
ajouter_fichier: function(file) {
// pouvoir nous retrouver facilement
file.bigup = this;
// zone de listing des fichiers
this.creer_zone_fichiers();
// Ajouter le fichier à la zone
var template = this.opts.templates.fichier(file.file);
this.zones.fichiers.append(template);
// Conserver en mémoire l'objet sur la vue du fichier, et inversement.
var fichier = this.zones.fichiers.find(".fichier:last-child");
file.emplacement = fichier;
// Calculer la preview
this.presenter_previsualisation(file);
fichier
.animateAppend()
.data('file', file)
.data('bigup', this);
return true;
},
/**
* Enlève le fichier transmis dans la liste des fichiers
*
* @param jquery emplacement
* Emplacement du fichier dans la liste des fichiers
*/
enlever_fichier: function(emplacement) {
var me = this;
emplacement.addClass('annuler');
// Identifiant du fichier
// Soit celui de flow.js, soit celui du serveur
// pour les fichiers présents à l'ouverture du formulaire
var identifiant = emplacement.data('identifiant')
// si on a un data 'file', le désintégrer…
if (file = emplacement.data('file')) {
file.abort();
file.bigup_deleted = true;
file.cancel();
if (!identifiant) {
identifiant = file.uniqueIdentifier;
}
}
this.post({
bigup_action: 'effacer',
identifiant: identifiant
})
.done(function() {
emplacement.animateRemove(function(){
$(this).remove();
me.adapter_visibilite_zone_depot();
me.input.trigger('bigup.fileRemoved', [file]);
});
})
.fail(function() {
emplacement.removeClass('annuler');
me.presenter_erreur(emplacement, _T('bigup:erreur_probleme_survenu'));
});
},
/**
* Poster une requête ajax, en transmettant des paramètres par défaut
* tel que le nom du formulaire, les actions, le token…
*
* @example
* bigup.post({ action:bigup_document }).done(function(){ ... });
* @param object data
* @return jqXHR
*/
post: function(data) {
data = $.extend({
action: "bigup",
formulaire_action: this.formulaire_action,
formulaire_action_args: this.formulaire_action_args,
bigup_token: this.token,
}, data);
return $.post(this.target, data);
},
/**
* Poste un FormData sur le formulaire bigup.
*
* @param FormData data
* @param {*} options
* @return jqXHR
*/
send: function(data, options) {
const ajaxOptions = Object.assign({
type: "POST",
url: this.target,
data: data,
processData: false,
contentType: false,
cache: false,
}, options || {});
return $.ajax(ajaxOptions);
},
/**
* Afficher une erreur sur un fichier
* @param string emplacement
* Emplacement du fichier dans la liste des fichiers
* @param string message
* Message d'erreur
*/
presenter_erreur: function(emplacement, message) {
emplacement
.addClass('erreur')
.find('.infos')
.append("<span class='message_erreur'>" + message + "</span>");
return this;
},
/**
* Afficher un message gentil sur un fichier
* @param string emplacement
* Emplacement du fichier dans la liste des fichiers
* @param string message
* Message
*/
presenter_succes: function(emplacement, message) {
emplacement
.addClass('succes')
.find('.infos')
.append("<span class='message_ok'>" + message + "</span>");
return this;
},
/**
* Présenter une vignette de l'image qui vient d'être déposée,
* à la place du logo de la vignette.
*
* @param FileObj file
*/
presenter_previsualisation: function(file) {
if (!this.opts.options.previsualisation.activer) {
return false;
}
if (this.opts.options.previsualisation.fileSizeMax) {
var taille = this.opts.options.previsualisation.fileSizeMax * 1024 * 1024;
if (file.file.size > taille) {
return false;
}
}
this.readURL(file.file, function() {
// source base64 de l'image dans this.result
if (this.result) {
var title =
file.emplacement.find('.infos .name').text()
+ ' (' + file.emplacement.find('.infos .size').text() + ')';
file.emplacement
.find('.vignette_extension')
.removeClass('vignette_extension')
.addClass('previsualisation')
.attr('title', title)
.find('> span')
.css('background-image', 'url(' + this.result + ')');
}
});
},
/**
* Calculer une URL (base64) à partir d'un fichier
* d'image déposé.
*
* @link http://stackoverflow.com/questions/4459379/preview-an-image-before-it-is-uploaded
* @link https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
*
* @param File file
* @param function callback
* Sera appelé dès que le fichier aura été lu
* this.result contiendra l'image en base64
* @return bool true si fichier d'image correct, false sinon
*/
readURL: function(file, callback) {
if (file) {
var reader = new FileReader();
// trop simple ?
// var imageType = /^image.*/i;
// exemple de mozilla raccourci (image/ en tête de regexp plutôt que dans chaque élément)
var imageType = /^image\/(?:bmp|cis\-cod|gif|ief|jpeg|jpeg|jpeg|pipeg|png|svg\+xml|tiff|x\-cmu\-raster|x\-cmx|x\-icon|x\-portable\-anymap|x\-portable\-bitmap|x\-portable\-graymap|x\-portable\-pixmap|x\-rgb|x\-xbitmap|x\-xpixmap|x\-xwindowdump)$/i;
if (!file.type.match(imageType)) {
return false;
}
if (typeof callback == 'function') {
reader.addEventListener("load", callback);
}
reader.readAsDataURL(file);
return true;
}
return false;
},
progress: {
/**
* Ajoute une balise progress dans le contenu, en douceur
* @param string emplacement
* Emplacement du fichier dans la liste des fichiers
*/
ajouter: function(emplacement) {
var progress = $('<progress value="0" max="100" style="display:none">0 %</progress>');
emplacement.append(progress);
progress.fadeIn(1000); /* marche pas terrible */
return this;
},
/**
* Augmente une balise progress à la valeur indiquée. Mais doucement
* @param jquery progress Le progress concerné.
* @param int val Valeur que l'on veut attribuer au progress.
*/
animer: function(progress, val) {
progress.each(function() {
var me = this;
$({percent: me.value}).animate({percent: val}, {
duration: 200,
step: function () { me.value = this.percent; }
});
});
return this;
},
/**
* Retire une balise progress du html, en douceur
* @param jquery progress Le progress concerné.
*/
retirer: function(progress) {
// meme durée que sur animer_progress() pour attendre la fin
progress.delay(200).fadeOut("normal", function(){
$(this).slideUp("normal", function(){ $(this).remove(); });
});
return this;
}
},
/**
* Récupère les champs que le formulaire poste habituellement
*
* Peut être utile pour faire un hit ajax, sans modifier le formulaire.
* Code en partie repris de dropzone.js
*
* On ne récupère pas les type file, ni sumbit.
*
* @note
* Dans certains cas (en présence de `name` avec des champs mulitples comme `name="items[]"`),
* cette fonction ne retourne pas l’ensemble des valeurs attendues…
* @deprecated Use buildFormData() instead
* @return object Couples [nom du champ => valeur]
*/
getFormData: function () {
console.info(
'Method `bigup.getFormData` is deprecated and will be removed in future version of Bigup.',
'Please use `bigup.buildFormData` instead and adapt your code (see #4861)'
);
var inputName, inputType;
var data = {};
this.form.find("input, textarea, select, button").each(function(){
inputName = $(this).attr('name');
inputType = $(this).attr('type');
if (inputName) {
if (this.tagName === "SELECT" && this.hasAttribute("multiple")) {
$.each(this.options, function (key, option) {
if (option.selected) {
data[inputName] = option.value;
}
});
} else if (
!inputType
|| ($.inArray(inputType, ["file", "checkbox", "radio", "submit"]) == -1)
|| this.checked
) {
data[inputName] = this.value;
}
}
});
return data;
},
/**
* Récupère les champs que le formulaire poste habituellement
*
* Peut être utile pour faire un hit ajax, sans modifier le formulaire.
* Code en partie repris de dropzone.js
*
* On ne récupère pas les type file, ni sumbit.
*
* @return FormData object
*/
buildFormData: function() {
const formData = new FormData();
const form = this.form[0];
for (let input of form.querySelectorAll(
"input, textarea, select, button"
)) {
let inputName = input.getAttribute("name");
let inputType = input.getAttribute("type");
if (inputType) inputType = inputType.toLowerCase();
// If the input doesn't have a name, we can't use it.
if (typeof inputName === "undefined" || inputName === null) continue;
if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
// Possibly multiple values
for (let option of input.options) {
if (option.selected) {
formData.append(inputName, option.value);
}
}
} else if (
!inputType ||
(
inputType !== "checkbox"
&& inputType !== "radio"
&& inputType !== "file"
&& inputType !== "submit"
) ||
input.checked
) {
formData.append(inputName, input.value);
}
}
return formData;
},
/**
* Assign one or more DOM nodes as a drop extended target.
* @function
* @param {Element|Array.<Element>} domNodes
*/
assignDropExtended: function (domNodes) {
if (typeof domNodes.length === 'undefined') {
domNodes = [domNodes];
}
Flow.each(domNodes, function (domNode) {
domNode.addEventListener('dragover', this.flow.preventEvent, false);
domNode.addEventListener('dragenter', this.flow.preventEvent, false);
domNode.addEventListener('drop', this.onDropExtended, false);
}, this);
},
/**
* Un-assign drop extended event from DOM nodes
* @function
* @param domNodes
*/
unAssignDrop: function (domNodes) {
if (typeof domNodes.length === 'undefined') {
domNodes = [domNodes];
}
Flow.each(domNodes, function (domNode) {
domNode.removeEventListener('dragover', this.flow.preventEvent);
domNode.removeEventListener('dragenter', this.flow.preventEvent);
domNode.removeEventListener('drop', this.onDropExtended);
}, this);
},
removeExtendedDropZone: function() {
$depot_etendu = this.zones.depot_etendu;
this.unAssignDrop($depot_etendu);
$depot_etendu
.removeClass('bigup-extended-drop-zone')
.off('dragenter dragover')
.off('dragleave drop')
.removeData('bigup');
},
/**
* A drag event contain files ?
* @param MouseEvent event
* @return bool
*/
eventHasFiles: function (event) {
if (event.dataTransfer.types) {
for (var i = 0; i < event.dataTransfer.types.length; i++) {
if (event.dataTransfer.types[i] === "Files") {
return true;
}
}
}
return false;
}
};
/**
* Enlever un fichier déjà téléversé ou annuler un transfert en cours
*
* La différence tient dans la présence de l'identifiant du fichier.
* C'est l'identifiant sur le serveur si le fichier est complet là bas.
*
* @param object me
* L'élément qui a cliqué
*/
$.bigup_enlever_fichier = function(me) {
var emplacement = $(me).parents('.fichier');
var bigup = emplacement.data('bigup');
$(me).addClass('btn-disabled');
bigup.enlever_fichier(emplacement);
};
$.bigup_verifier_depots_etendus = function() {
// desactiver toutes les data-drop-zone-extended qui ne sont plus liees a un input present dans le html
jQuery('.bigup-extended-drop-zone').each(function (){
var bigup = jQuery(this).data('bigup');
if (!bigup) {
$(this).removeClass('bigup-extended-drop-zone')
} else if (!document.body.contains(bigup.zones.depot.get(0))) {
bigup.removeExtendedDropZone();
}
});
}