diff --git a/Resources/js/widget/file_upload.js b/Resources/js/widget/file_upload.js index 2fd78ee2e3cc9ebcf726ceefd420447e0ed09bf4..d8d67341654bd187547e74adde1cda696e3492e9 100644 --- a/Resources/js/widget/file_upload.js +++ b/Resources/js/widget/file_upload.js @@ -2,25 +2,26 @@ * Copyright (C) 2015 IRSTEA * All rights reserved. */ -(function($, Translator) { +(function ($, Translator) { - var formatFileSize = function(size) { + var formatFileSize = function (size) { var unit; - if(size > 1000000000) { - size = (size/1000000000).toFixed(2); + if (size > 1000000000) { + size = (size / 1000000000).toFixed(2); unit = 'Gi'; - } else if(size > 1000000) { - size = (size/1000000).toFixed(2); + } else if (size > 1000000) { + size = (size / 1000000).toFixed(2); unit = 'Mi'; - } else if(size > 1000) { - size = (size/1000).toFixed(2); - unit ='Ki'; + } else if (size > 1000) { + size = (size / 1000).toFixed(2); + unit = 'Ki'; } else { unit = ''; } - return Translator.trans('file_size(%size%,%unit%)', {size:size, unit:unit}, 'file_upload'); + 'UPLOADING !' + return Translator.trans('file_size(%size%,%unit%)', {size: size, unit: unit}, 'file_upload'); }, - formatBitrate = function(rate) { + formatBitrate = function (rate) { return formatFileSize(rate) + '/s'; }; @@ -29,29 +30,52 @@ /** Plugin irsteaFileUpload. */ - $.fn.irsteaFileUpload = function(options) { - - var $this = $(this), - $button = $this.find('.fileinput-button'), - $entries = $this.find('.fileinput-entries'), - nextIndex = $entries.find('.fileinput-entry').length, - createUrl = options.createUrl, - uploadPrototype = options.uploadPrototype, + $.fn.irsteaFileUpload = function (options) { + + var $this = $(this), + $button = $this.find('.fileinput-button'), + input = $this.find(':file')[0], + $entries = $this.find('.fileinput-entries'), + nextIndex = $entries.find('.fileinput-entry').length, + createUrl = options.createUrl, + uploadPrototype = options.uploadPrototype, downloadPrototype = options.downloadPrototype, - csrfQuery = '?token=' + options.csrfToken; + csrfQuery = '?token=' + options.csrfToken; delete options.createUrl; delete options.uploadPrototype; delete options.downloadPrototype; delete options.csrfToken; - if(options.acceptFileTypes) { + if (options.acceptFileTypes) { options.acceptFileTypes = new RegExp('^' + options.acceptFileTypes + '$'); } - var showError = function(entry, message) { + var checkValidity = function () { + var counts = { + upload: $entries.find('.template-upload').length, + download: $entries.find('.template-download').length, + error: $entries.find('.alert-danger').length, + }, + error = ''; + + if (counts.upload > 0) { + error = Translator.trans('file_upload.running_upload'); + + } else if (counts.error > 0) { + error = Translator.trans('file_upload.upload_error'); + + } else if (options.required && counts.download < 1) { + error = Translator.trans('file_upload.required_file'); + } + + input.setCustomValidity(error); + + // console.debug(input, counts, input.validationMessage, input.validity); + }, + showError = function (entry, message) { var $this = $(entry); - if(message) { + if (message) { $this.find('.error').text(Translator.trans(message)); } $this.addClass('alert alert-danger'); @@ -62,20 +86,19 @@ $this.find('.description').remove(); $this.find('.id').remove(); }, - updateDisplay = function() { + updateDisplay = function (event) { var hasEntry = false; - $entries.find('.fileinput-entry').each(function() { + $entries.find('.fileinput-entry').each(function () { var data = $(this).data('data'); - if(data && data.files.error) { + if (data && data.files.error) { showError(this, data.files[0].error); } hasEntry = true; }); $button.toggle(options.multiple || !hasEntry); + checkValidity(); }; - updateDisplay(); - // Activation $button.fileupload($.extend( options, @@ -89,7 +112,7 @@ filesContainer: $this.find('.fileinput-entries'), dropZone: $this, i18n: Translator.trans, - uploadTemplate: function(data) { + uploadTemplate: function (data) { var rows = $(); $.each(data.files, function (index, file) { var row = $(uploadPrototype); @@ -103,7 +126,7 @@ }); return rows; }, - downloadTemplate: function(data) { + downloadTemplate: function (data) { var rows = $(); $.each(data.files, function (index, file) { var row = $(downloadPrototype.replace(/__index__/g, nextIndex++)); @@ -122,10 +145,10 @@ .attr('data-url', file.delete_url + csrfQuery); row.find('input.id') .val(file.id); - if(file.icon && file.icon !== 'file') { + if (file.icon && file.icon !== 'file') { row.find('.icon') .removeClass('fa-file-o') - .addClass('fa-file-'+file.icon+'-o'); + .addClass('fa-file-' + file.icon + '-o'); } }); return rows; @@ -135,8 +158,8 @@ file = data.files[0]; $.post( createUrl, - { file: { name: file.name, size: file.size, type: file.type, lastModified: file.lastModified } }, - function(response) { + {file: {name: file.name, size: file.size, type: file.type, lastModified: file.lastModified}}, + function (response) { file.icon = response.icon; data.url = response.put_url + csrfQuery; data.delete_url = response.delete_url; @@ -144,7 +167,7 @@ data.jqXHR = $this.fileupload('send', data); } ) - .fail(function(jqXHR, textStatus, errorThrown) { + .fail(function (jqXHR, textStatus, errorThrown) { file.error = textStatus === "error" ? errorThrown : ('Error #' + jqXHR.status); data.files.error = true; showError(data.context, file.error); @@ -153,7 +176,7 @@ return false; }, progress: function (e, data) { - if(!data.context || e.isDefaultPrevented()) { + if (!data.context || e.isDefaultPrevented()) { return; } var percent = data.loaded / data.total * 100, @@ -162,21 +185,22 @@ var $this = $(data.context); $this.find('.progress').show(); $this.find('.progress-bar').css('width', percent + '%').attr('aria-valuenow', percentText); - $this.find('.progress-text').show().html(percentText + '% ('+formatBitrate(data.bitrate)+')'); + $this.find('.progress-text').show().html(percentText + '% (' + formatBitrate(data.bitrate) + ')'); }); }, - getFilesFromResponse: function(data) { + getFilesFromResponse: function (data) { var files = []; - $.each(data.files, function(index, file) { + $.each(data.files, function (index, file) { files.push($.extend(file, data.result.files[index])); }); return files; }, } )).bind({ - fileuploadfailed: function (e, data) { - if(data.delete_url) { - $.ajax(data.delete_url + csrfQuery, { type: data.delete_type }); + fileuploadfailed: function (event, data) { + if (data.delete_url) { + $.ajax(data.delete_url + csrfQuery, {type: data.delete_type}); + checkValidity(); } }, fileuploadadded: updateDisplay, @@ -185,10 +209,11 @@ fileuploadprocessalways: updateDisplay }); - if(options.disabled || options.readonly) { + if (options.disabled || options.readonly) { $button.fileupload('disable'); } + updateDisplay(); }; })(jQuery, Translator); diff --git a/Resources/views/Form/file_upload.html.twig b/Resources/views/Form/file_upload.html.twig index 5d32376d84b5ba05c742bbe0d7a11f9447e2f350..e59624b304a3b9018b340eb8c211dbdec6de3344 100644 --- a/Resources/views/Form/file_upload.html.twig +++ b/Resources/views/Form/file_upload.html.twig @@ -49,7 +49,7 @@ </div> <div class="fileinput-button btn btn-default btn-xs"> <span>{{ irstea_icon('upload') }} {% trans %}button.upload{% endtrans %}</span> - <input type="file" name="_hack_{{ full_name }}" + <input type="file" name="_hack_{{ full_name }}" data-map-errors-to="#{{ id }}" {%- if multiple %} multiple="multiple"{% endif -%} {%- if disabled or read_only %} disabled="disabled"{% endif -%} />