1/** 2 * Drag and drop jQuery plugin - Version: 1.0 3 * @copyright © 2005-2019 PHPBoost - 2019 babsolune 4 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU/GPL-3.0 5 * @author Sebastien LARTIGUE <[email protected]> 6 * @version PHPBoost 5.3 - last update: 2019 10 03 7 * @since PHPBoost 5.3 - 2019 09 23 8*/ 9 10(function($) { 11 12 $.fn.extend({ 13 dndfiles: function(options) { 14 // set the default parameters 15 var settings = { 16 filesNbr: '.files-nbr', // class to display the number of selected files 17 filesList: '.ulist', // class to display the list of selected files 18 multiple: false, // add or not 'multiple attribut to the input' 19 maxFileSize: '500000000', // weight max for one file 20 maxFilesSize: '-1', // weight max for all files (-1 = unlimited) 21 maxWidth: '-1', // max width for pictures (-1 = unlimited) 22 maxHeight: '-1', // max height for pictures (-1 = unlimited) 23 allowedExtensions: ['jpg', 'jpeg', 'png', 'gif', 'svg'], // allowed extensions 24 warningText: 'Upload have been disabled because of bad file:', // main warning text 25 warningExtension: 'bad extension <br />', 26 warningFileSize: 'Too large file <br />', 27 warningFilesNbr: 'The size of the allocated space is exceeded <br />', 28 warningFilesDim: 'The height or width of the picture exceeds the maximum allowed <br />', 29 }; 30 param = $.extend(settings, options); 31 32 // init vars 33 var $input = $(this), 34 extension, 35 fileSize, 36 fileName, 37 fileType, 38 fileWidth, 39 fileHeight; 40 41 if(param.multiple) { // if multiple parameter is true 42 $input.attr('multiple', 'multiple'); // set the attribute 'multiple' to the input 43 $(param.filesNbr).html('0'); // send '0' to the frontend icon displaying the number of selected files 44 } 45 46 // change design on drag or mouse hovering 47 $input.on('dragover mouseover', function() { $input.closest('.dnd-dropzone').addClass('dragover'); }); 48 $input.on('dragleave drop mouseleave', function() { $input.closest('.dnd-dropzone').removeClass('dragover'); }); 49 50 // turn file size into human readable 51 function formatBytes(a, b) { 52 if (0 == a) return "0 Bytes"; 53 var c = 1024, 54 d = b || 2, 55 e = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], 56 f = Math.floor(Math.log(a) / Math.log(c)); 57 return parseFloat((a / Math.pow(c, f)).toFixed(d)) + " " + e[f]; 58 } 59 60 $input.parent().on('change', function(e) { // when files are selected, the status of the input changes 61 // reset 62 if(param.multiple) $input.closest('.dnd-area').find(param.filesNbr).empty(); // if multiple is true => empty the display of number of files 63 $input.closest('.dnd-area').siblings(param.filesList).empty(); // empty the list of selected files 64 $input.closest('form').find('button[type="submit"]').prop("disabled", false); // remove the 'disabled' attribute of the upload button 65 $input.closest('.dnd-area').find('label p').html(''); // empty the warning texts 66 $input.closest('.dnd-area').find('label p').removeClass('message-helper warning small'); // remove the warning classes 67 $input.closest('.dnd-area').find('.upload-help').removeClass(' warning'); 68 69 // init vars 70 var filesNbr = $input[0].files.length, // count number of files 71 totalWeight = 0, 72 items = $input[0].files, 73 item = ''; 74 75 if ($input.attr('multiple')) { // if multiple parameter is true 76 $input.closest('.dnd-area').find(param.filesNbr).append(filesNbr); // send number of files to the icon and... 77 if(filesNbr > 0) $('.clear-list').show(); // if it's > 0 then show the 'clear list' button 78 } 79 80 // For each file selected 81 for(var i=0; i < filesNbr; i++) { 82 var warningClass = ''; 83 fileName = items[i].name; // get its name 84 fileSize = items[i].size; // get its weight 85 fileType = items[i].type; // get its mime type 86 extension = fileName.replace(/^.*\./, ''); // replace special characters in the name 87 if (extension == fileName) extension = ''; // look if extension exists 88 else extension = extension.toLowerCase(); // force extension to lowercase 89 if(fileType.indexOf('image/') === 0) { 90 var file = items[i]; 91 var img = new Image(); 92 img.onload = function() { 93 fileWidth = this.width; 94 fileHeight = this.height; 95 if((param.maxWidth > -1 && fileWidth > param.maxWidth) || (param.maxHeight > -1 && fileHeight > param.maxHeight)) 96 { 97 $input.closest('form').find('button[type="submit"]').attr('disabled', 'disabled'); // disable the upload button 98 $input.closest('.dnd-area').find('.upload-help').addClass(' warning'); 99 $input.closest('.dnd-area').find('label p').addClass('message-helper warning small').append(param.warningFileDim); 100 } 101 }; 102 img.src = URL.createObjectURL(file); 103 } 104 105 totalWeight += fileSize; // count weight of all files 106 107 // items list construction 108 109 // if an extension is not allowed or a file exceeds the max allowed or the number of files exceeds the max allowed (-1 = rights for admin = unlimited) 110 if(param.allowedExtensions.indexOf(extension) === -1 || fileSize > param.maxFileSize || (totalWeight > param.maxFilesSize && param.maxFilesSize > -1)) 111 { 112 warningClass = 'warning'; // set the warning class to the item in the list 113 $input.closest('form').find('button[type="submit"]').attr('disabled', 'disabled'); // disable the upload button 114 } 115 116 if(param.allowedExtensions.indexOf(extension) === -1) // if an extension is not allowed 117 $input.closest('.dnd-area').find('label p').append('<span class="filename">'+fileName+'</span>', param.warningExtension); // send the extension warning text 118 if(fileSize > param.maxFileSize) // if a file exceeds the max weight allowed 119 $input.closest('.dnd-area').find('label p').append('<span class="filename">'+fileName+'</span>', param.warningFileSize); // send the weight warning text 120 121 // set the appropriate html depending of the mime type 122 if(fileType.indexOf('image/') === 0) 123 item += '<li class="'+warningClass+'" data-file="'+fileName+'"><img src="' + URL.createObjectURL(items[i]) + '" /> '+fileName+' <sup>'+formatBytes(fileSize)+'</sup><span class="fa fa-times-circle fa-lg close-item"></span></li>'; 124 else if(fileType.indexOf('audio/') === 0) 125 item += '<li class="'+warningClass+'" data-file="'+fileName+'"><i class="far fa-file"></i> '+fileName+' <sup>'+formatBytes(fileSize)+'</sup><span class="fa fa-times-circle fa-lg close-item"></span></li>'; 126 else if(fileType.indexOf('video/') === 0) 127 item += '<li class="'+warningClass+'" data-file="'+fileName+'"><i class="far fa-file"></i> '+fileName+' <sup>'+formatBytes(fileSize)+'</sup><span class="fa fa-times-circle fa-lg close-item"></span></li>'; 128 else if(fileType.indexOf('application/zip') === 0) 129 item += '<li class="'+warningClass+'" data-file="'+fileName+'"><i class="far fa-file-archive"></i> '+fileName+' <sup>'+formatBytes(fileSize)+'</sup><span class="fa fa-times-circle fa-lg close-item"></span></li>'; 130 else if(fileType.indexOf('application/pdf') === 0) 131 item += '<li class="'+warningClass+'" data-file="'+fileName+'"><i class="far fa-file-pdf"></i> '+fileName+' <sup>'+formatBytes(fileSize)+'</sup><span class="fa fa-times-circle fa-lg close-item"></span></li>'; 132 else 133 item += '<li class="'+warningClass+'" data-file="'+fileName+'"><i class="far fa-file"></i> '+fileName+' <sup>'+formatBytes(fileSize)+'</sup><span class="fa fa-times-circle fa-lg close-item"></span></li>'; 134 } 135 $($input).closest('.dnd-area').siblings(param.filesList).append(item); // send the list to the page (bellow the dropzone) 136 137 if($input.closest('form').find('button[type="submit"]').attr('disabled')) // if there's a wrong file 138 { 139 $input.closest('.dnd-area').find('.upload-help').addClass(' warning'); 140 $input.closest('.dnd-area').find('label p').addClass('message-helper warning small'); // add warning classes 141 $input.closest('.dnd-area').find('label p').prepend(param.warningText); // add main warning text 142 } 143 if(totalWeight > param.maxFilesSize && param.maxFilesSize > -1) // if nbr of files exceeds max allowed 144 $input.closest('.dnd-area').find('label p').append(param.warningFilesNbr); // send the max file warning text 145 146 // next feature : possibility to delete only one file in the list 147 $(param.filesList).find('.close-item').each(function(){ 148 $(this).on('click', function(){
149 var itemNbr = $('.ulist li:not([value="0"])').length; 150 $(this).parent().empty().val('').hide(); 151 var newFilesNbr = itemNbr - 1; 152 $(param.filesNbr).empty().append(newFilesNbr); 153 }); 154 }); 155 156 if(param.multiple) { // if multiple is true 157 // reset all when clicking on the 'clear list' button 158 $('.clear-list').on('click', function(d) { 159 d.preventDefault(); // deactivate the default button behaviour 160 $input.val(''); // empty the input list of files 161 $input.closest('.dnd-area').find(param.filesNbr).html('0'); // reset the display of the number of files 162 $input.closest('.dnd-area').siblings(param.filesList).empty(); // empty the display of the list of files 163 $input.closest('form').find('button[type="submit"]').prop("disabled", false); // remove the 'disabled' attribute from the upload button 164 $input.closest('.dnd-area').find('label p').html(''); // remove the warning texts 165 $input.closest('.dnd-area').find('label p').removeClass('message-helper warning small'); // remove the warning classes 166 $input.closest('.dnd-area').find('.upload-help').removeClass(' warning'); 167 }); 168 } 169 170 }) 171 } 172 }); 173})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.