diff --git a/DependencyInjection/IrsteaFileUploadExtension.php b/DependencyInjection/IrsteaFileUploadExtension.php index 88a22fa4a2e9e99d063ef878ed77a8bccc19df1e..5e64c37458f254607c5a4db8c94b78026e6782f5 100644 --- a/DependencyInjection/IrsteaFileUploadExtension.php +++ b/DependencyInjection/IrsteaFileUploadExtension.php @@ -48,6 +48,7 @@ class IrsteaFileUploadExtension extends Extension implements PrependExtensionInt 'inputs' => [ "$pluginDir/css/jquery.fileupload.css", "$pluginDir/css/jquery.fileupload-ui.css", + '@IrsteaFileUploadBundle/Resources/less/file_upload.less' ], ], ], diff --git a/Resources/js/widget/file_upload.js b/Resources/js/widget/file_upload.js index cf0aa4d2e12b9caf88b742f05f4c4b663c14171f..0b7ee4c46bb0163b803779ba548fdab911eb7657 100644 --- a/Resources/js/widget/file_upload.js +++ b/Resources/js/widget/file_upload.js @@ -4,22 +4,25 @@ */ (function($) { - var formatSize = function(size) { + var formatFileSize = function(size) { if(size > 1000000000) { - return (size/1000000000).toFixed(2) + ' Gio'; + return (size/1000000000).toFixed(2) + ' Gio'; } if(size > 1000000) { - return (size/1000000).toFixed(2) + ' Mio'; + return (size/1000000).toFixed(2) + ' Mio'; } if(size > 1000) { - return (size/1000).toFixed(2)+ ' Kio'; + return (size/1000).toFixed(2)+ ' Kio'; } - return size + ' o'; + return size + ' o'; }, formatBitrate = function(rate) { - return formatSize(rate) + '/s'; + return formatFileSize(rate) + '/s'; }; + $.blueimp.fileupload.prototype._formatFileSize = formatFileSize; + $.blueimp.fileupload.prototype._formatBitrate = formatBitrate; + /** Plugin irsteaFileUpload. */ $.fn.irsteaFileUpload = function(options) { @@ -39,17 +42,23 @@ options.acceptFileTypes = new RegExp('^' + options.acceptFileTypes + '$'); } - var updateButtonVisibility = function() { - if($entries.children().length > 0 && !options.multiple) { - $button.hide(); - } else { - $button.show(); - } + var updateDisplay = function() { + var hasEntry = false; + $entries.find('.fileinput-entry').each(function() { + var data = $(this).data('data'), + inError = !!(data && data.files.error); + $(this).toggleClass('alert alert-danger', inError); + $(this).find('.error').toggle(inError); + hasEntry = true; + }); + $button.toggle(options.multiple || !hasEntry); }; - $this.find('.template-download .size').each(function() { $(this).html(formatSize($(this).text())); }); + $this.find('.template-download .size').each(function() { + $(this).text(formatFileSize($(this).text())); + }); - updateButtonVisibility(); + updateDisplay(); // Activation $button.fileupload($.extend( @@ -67,7 +76,7 @@ $.each(data.files, function (index, file) { var row = $(uploadPrototype); row.find('.name').text(file.name); - row.find('.size').html(formatSize(file.size)); + row.find('.size').text(formatFileSize(file.size)); if (file.error) { row.find('.error').text(file.error); } @@ -79,7 +88,7 @@ var rows = $(); $.each(data.files, function (index, file) { var row = $(downloadPrototype); - row.find('.size').html(formatSize(file.size)); + row.find('.size').text(formatFileSize(file.size)); if (file.error) { row.find('.name').text(file.name); row.find('.error').text(file.error); @@ -125,8 +134,9 @@ var percent = data.loaded / data.total * 100, percentText = percent.toFixed(1); data.context.each(function () { - $this.find('.progress').show().attr('aria-valuenow', percentText); - $this.find('.progress-bar').css('width', percent + '%'); + 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)+')'); }); } @@ -137,10 +147,10 @@ $.ajax(data.delete_url, { type: data.delete_type }); } }, - fileuploadadded: updateButtonVisibility, - fileuploadfinished: updateButtonVisibility, - fileuploaddestroyed: updateButtonVisibility, - fileuploadprocessalways: updateButtonVisibility + fileuploadadded: updateDisplay, + fileuploadfinished: updateDisplay, + fileuploaddestroyed: updateDisplay, + fileuploadprocessalways: updateDisplay }); if(options.disabled || options.readonly) { diff --git a/Resources/less/file_upload.less b/Resources/less/file_upload.less new file mode 100644 index 0000000000000000000000000000000000000000..b7820928bcfc58affcedf896ea4abb63c95579c1 --- /dev/null +++ b/Resources/less/file_upload.less @@ -0,0 +1,33 @@ +/* +Copyright (C) 2015 IRSTEA +All rights reserved. +*/ + +@import "variables.less"; +@import "bootstrap/less/mixins.less"; + +.fileinput-entry { + .cancel, .delete { + margin-left: 0.5em; + } + .progress { + height: (@line-height-computed / 2); + margin: (@line-height-computed / 4) 0; + } + .progress-text { + float: right; + } + &.alert { + padding: @padding-xs-vertical @padding-xs-horizontal; + margin-bottom: 0; + } +} + +.fileinput-multiple .fileinput-entry { + margin-bottom: (@line-height-computed / 2); +} + +.fileinput-multiple, .fileinput-single { + height: auto !important; + min-height: @input-height-base; +} diff --git a/Resources/views/Form/file_upload.html.twig b/Resources/views/Form/file_upload.html.twig index 15323aa6d0c9601cf9422703b390d928e1e7f7d0..dcfea721d10a5a7f957f2708476a6810410e4417 100644 --- a/Resources/views/Form/file_upload.html.twig +++ b/Resources/views/Form/file_upload.html.twig @@ -1,21 +1,37 @@ {% block file_upload_progress_prototype %} - <div class="template-upload"> - <p> - <span class="progress-text pull-right" style="display: none"></span> - <button class="btn btn-xs btn-danger cancel" title="{% trans %}button.cancel{% endtrans %}"> - {{ irstea_icon('remove') }} - </button> <span class="name"></span> (<span class="size"></span>) - <span class="error danger"></span> - </p> - <p class="progress" style="display: none"> - <div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100"></div> - </p> + <div class="template-upload fileinput-entry"> + <div class="progress-text" style="display: none"></div> + <span class="name">Monfichier.com</span> (<span class="size">1.5 Gio</span>) + <span class="error" style="display: none"></span> + <a href="#" class="danger cancel" title="{% trans %}button.cancel{% endtrans %}"> + {{- irstea_icon('remove') -}} + </a> + <div class="progress" style="display: none"> + <div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div> + </div> </div> {% endblock %} +{%- block file_upload_entry_prototype %} + {%- set file = file|default([]) %} + <div class="template-download fileinput-entry"> + <input type="hidden" name="{{ full_name }}{% if multiple %}[]{% endif %}" value="{{ file.id|default }}"/> + <span class="name"> + <a{% if file %} href="{{ path('file_upload_get_content', {id: file.id, token: csrfToken}) }}"{% endif %}>{{ file.originalFilename|default }}</a> + </span> + (<span class="size"> + {{- file.size|default -}} + </span>) + <span class="error danger" style="display: none">ERROR</span> + <a href="#" class="danger delete {%- if disabled or read_only %} disabled{% endif -%}" title="{% trans %}button.delete{% endtrans %}"> + {{- irstea_icon('remove') -}} + </a> + </div> +{% endblock -%} + {% block file_upload_widget %} - <div id="{{ id }}" {{ block('widget_container_attributes') }} {{ block('widget_only_attributes') }} + <div id="{{ id }}" class="form-control fileinput-{{ multiple ? "multiple" : "single" }}" {{ block('widget_container_attributes') }} {{ block('widget_only_attributes') }} data-download-prototype="{{ block('file_upload_entry_prototype')|e }}" data-upload-prototype="{{ block('file_upload_progress_prototype')|e }}" {% if disabled %}data-disabled="disabled"{% endif -%} @@ -29,29 +45,16 @@ {% endfor %} {%- else %} {%- set file = value %} - {%- block file_upload_entry_prototype %} - {%- set file = file|default([]) %} - <p class="template-download"> - <input type="hidden" name="{{ full_name }}{% if multiple %}[]{% endif %}" value="{{ file.id|default }}"/> - <button class="btn btn-xs btn-danger delete" title="{% trans %}button.delete{% endtrans %}" {%- if disabled or read_only %} disabled="disabled"{% endif -%}> - {{- irstea_icon('trash') -}} - </button> <span class="name"> - <a{% if file %} href="{{ path('file_upload_get_content', {id: file.id, token: csrfToken}) }}"{% endif %}>{{ file.originalFilename|default }}</a> - </span> (<span class="size"> - {{- file.size|default -}} - </span>) - <span class="error danger"></span> - </p> - {% endblock -%} + {{- block('file_upload_entry_prototype') -}} {% endif -%} {% endif -%} </div> - <span class="btn btn-primary fileinput-button"> + <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 }}" {%- if multiple %} multiple="multiple"{% endif -%} {%- if disabled or read_only %} disabled="disabled"{% endif -%} /> - </span> + </div> </div> {% endblock file_upload_widget %}