Quellcode durchsuchen

Update to release v4.2.9 fix #534, fix #535, fix #545

Kartik Visweswaran vor 9 Jahren
Ursprung
Commit
2f8765f587
3 geänderte Dateien mit 151 neuen und 130 gelöschten Zeilen
  1. 4 2
      CHANGE.md
  2. 142 122
      js/fileinput.js
  3. 5 6
      js/fileinput.min.js

+ 4 - 2
CHANGE.md

@@ -3,13 +3,15 @@ Change Log: `bootstrap-fileinput`
 
 ## version 4.2.9
 
-**Date:** 19-Jan-2016
+**Date:** 20-Jan-2016
 
 1. (enh #521): Update Dutch Translations.
 2. (enh #523): Add new branch `sass` for `bootstrap-sass-official` support.
 3. (enh #530): Error alert box and preview thumbnail styling enhancements.
 4. (enh #531): Enhance/Fix typos of Arabic translation.
-5. (enh #541): Improve default slug callback to accept most characters.
+5. (enh #534, enh #535): Ability to remove errored file thumbnails via `removeFromPreviewOnError`.
+6. (enh #541): Improve default slug callback to accept most characters.
+7. (enh #545): Refactor code to deep extend options correctly.
 
 ## version 4.2.8
 

+ 142 - 122
js/fileinput.js

@@ -2,13 +2,12 @@
  * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2015
  * @version 4.2.9
  *
- * File input styled for Bootstrap 3.0 that utilizes HTML5 File Input's advanced 
- * features including the FileReader API. 
+ * File input styled for Bootstrap 3.0 that utilizes HTML5 File Input's advanced features including the FileReader API.
  * 
- * The plugin drastically enhances the HTML file input to preview multiple files on the client before
- * upload. In addition it provides the ability to preview content of images, text, videos, audio, html, 
- * flash and other objects. It also offers the ability to upload and delete files using AJAX, and add 
- * files in batches (i.e. preview, append, or remove before upload).
+ * The plugin drastically enhances the HTML file input to preview multiple files on the client before upload. In
+ * addition it provides the ability to preview content of images, text, videos, audio, html, flash and other objects.
+ * It also offers the ability to upload and delete files using AJAX, and add files in batches (i.e. preview, append,
+ * or remove before upload).
  * 
  * Author: Kartik Visweswaran
  * Copyright: 2015, Kartik Visweswaran, Krajee.com
@@ -40,8 +39,9 @@
         tCaption, tBtnDefault, tBtnLink, tBtnBrowse, tModal, tProgress, tFooter, tActions, tActionDelete, tActionUpload,
         tZoom, tGeneric, tHtml, tImage, tText, tVideo, tAudio, tFlash, tObject, tOther, defaultLayoutTemplates,
         defaultPreviewTemplates, defaultPreviewTypes, defaultPreviewSettings, defaultFileTypeSettings, isEmpty, isArray,
-        isSet, getElement, uniqId, htmlEncode, replaceTags, objUrl, FileInput;
+        isSet, getElement, uniqId, htmlEncode, replaceTags, objUrl, FileInput, NAMESPACE;
 
+    NAMESPACE = '.fileinput';
     isIE = function (ver) {
         // check for IE versions < 11
         if (navigator.appName !== 'Microsoft Internet Explorer') {
@@ -61,7 +61,7 @@
         return new RegExp('Edge\/[0-9]+', 'i').test(navigator.userAgent);
     };
     handler = function ($el, event, callback, skipNS) {
-        var ev = skipNS ? event : event + '.fileinput';
+        var ev = skipNS ? event : event.split(' ').join(NAMESPACE + ' ') + NAMESPACE;
         $el.off(ev).on(ev, callback);
     };
     previewCache = {
@@ -246,7 +246,7 @@
         return isNaN(num) ? def : num;
     };
     hasFileAPISupport = function () {
-        return window.File && window.FileReader;
+        return !!(window.File && window.FileReader);
     };
     hasDragDropSupport = function () {
         var div = document.createElement('div');
@@ -604,6 +604,7 @@
             } else {
                 self.refreshContainer();
             }
+            self.$dropZone = self.$container.find('.file-drop-zone');
             self.$progress = self.$container.find('.kv-upload-progress');
             self.$btnUpload = self.$container.find('.fileinput-upload');
             self.$captionContainer = getElement(options, 'elCaptionContainer', self.$container.find('.file-caption'));
@@ -617,7 +618,7 @@
                 addCss(self.$errorContainer, self.msgErrorClass);
             }
             self.$errorContainer.hide();
-            self.fileActionSettings = $.extend(defaultFileActionSettings, options.fileActionSettings);
+            self.fileActionSettings = $.extend(true, defaultFileActionSettings, options.fileActionSettings);
             self.previewInitId = "preview-" + uniqId();
             self.id = self.$element.attr('id');
             previewCache.init(self);
@@ -631,6 +632,7 @@
             }
         },
         parseError: function (jqXHR, errorThrown, fileName) {
+            /** @namespace jqXHR.responseJSON */
             var self = this, errMsg = $.trim(errorThrown + ''),
                 dot = errMsg.slice(-1) === '.' ? '' : '.',
                 text = jqXHR.responseJSON !== undefined && jqXHR.responseJSON.error !== undefined ?
@@ -737,43 +739,91 @@
             };
         },
         listen: function () {
-            var self = this, $el = self.$element, $cap = self.$captionContainer, $btnFile = self.$btnFile,
-                $form = $el.closest('form'), $cont = self.$container;
+            var self = this, $el = self.$element, $form = $el.closest('form'), $cont = self.$container;
             handler($el, 'change', $.proxy(self.change, self));
-            handler($btnFile, 'click', function () {
-                self.raise('filebrowse');
-                if (self.isError && !self.isUploadable) {
-                    self.clear();
-                }
-                $cap.focus();
-            });
+            handler(self.$btnFile, 'click', $.proxy(self.browse, self));
             handler($form, 'reset', $.proxy(self.reset, self));
             handler($cont.find('.fileinput-remove:not([disabled])'), 'click', $.proxy(self.clear, self));
             handler($cont.find('.fileinput-cancel'), 'click', $.proxy(self.cancel, self));
-            if (self.isUploadable && self.dropZoneEnabled && self.showPreview) {
-                self.initDragDrop();
-            }
+            self.initDragDrop();
             if (!self.isUploadable) {
                 handler($form, 'submit', $.proxy(self.submitForm, self));
             }
-            handler(self.$container.find('.fileinput-upload'), 'click', function (e) {
-                var $btn = $(this), $form, isEnabled = !$btn.hasClass('disabled') && isEmpty($btn.attr('disabled'));
-                if (!self.isUploadable) {
-                    if (isEnabled && $btn.attr('type') !== 'submit') {
-                        $form = $btn.closest('form');
-                        // downgrade to normal form submit if possible
-                        if ($form.length) {
-                            $form.trigger('submit');
-                        }
-                        e.preventDefault();
+            handler(self.$container.find('.fileinput-upload'), 'click', $.proxy(self.uploadClick, self));
+        },
+        zoneDragDropInit: function (e) {
+            e.stopPropagation();
+            e.preventDefault();
+        },
+        zoneDragEnter: function (e) {
+            var self = this, hasFiles = $.inArray('Files', e.originalEvent.dataTransfer.types) > -1;
+            self.zoneDragDropInit(e);
+            if (self.isDisabled || !hasFiles) {
+                e.originalEvent.dataTransfer.effectAllowed = 'none';
+                e.originalEvent.dataTransfer.dropEffect = 'none';
+                return;
+            }
+            addCss(self.$dropZone, 'file-highlighted');
+        },
+        zoneDragLeave: function (e) {
+            var self = this;
+            self.zoneDragDropInit(e);
+            if (self.isDisabled) {
+                return;
+            }
+            self.$dropZone.removeClass('file-highlighted');
+        },
+        zoneDrop: function (e) {
+            var self = this;
+            e.preventDefault();
+            /** @namespace e.originalEvent.dataTransfer */
+            if (self.isDisabled || isEmpty(e.originalEvent.dataTransfer.files)) {
+                return;
+            }
+            self.change(e, 'dragdrop');
+            self.$dropZone.removeClass('file-highlighted');
+        },
+        initDragDrop: function () {
+            var self = this, $zone = self.$dropZone;
+            if (self.isUploadable && self.dropZoneEnabled && self.showPreview) {
+                handler($zone, 'dragenter dragover', $.proxy(self.zoneDragEnter, self));
+                handler($zone, 'dragleave', $.proxy(self.zoneDragLeave, self));
+                handler($zone, 'drop', $.proxy(self.zoneDrop, self));
+                handler($zone, 'dragenter dragover drop', self.zoneDragDropInit);
+            }
+        },
+        browse: function (e) {
+            var self = this;
+            self.raise('filebrowse');
+            if (e && e.isDefaultPrevented()) {
+                return;
+            }
+            if (self.isError && !self.isUploadable) {
+                self.clear();
+            }
+            self.$captionContainer.focus();
+        },
+        uploadClick: function (e) {
+            var self = this, $btn = self.$container.find('.fileinput-upload'), $form,
+                isEnabled = !$btn.hasClass('disabled') && isEmpty($btn.attr('disabled'));
+            if (e && e.isDefaultPrevented()) {
+                return;
+            }
+            if (!self.isUploadable) {
+                if (isEnabled && $btn.attr('type') !== 'submit') {
+                    $form = $btn.closest('form');
+                    // downgrade to normal form submit if possible
+                    if ($form.length) {
+                        $form.trigger('submit');
                     }
-                    return;
+                    e.preventDefault();
                 }
-                e.preventDefault();
-                if (isEnabled) {
-                    self.upload();
-                }
-            });
+                return;
+            }
+            e.preventDefault();
+            if (isEnabled) {
+                self.upload();
+            }
         },
         submitForm: function () {
             var self = this, $el = self.$element, files = $el.get(0).files;
@@ -786,7 +836,7 @@
         abort: function (params) {
             var self = this, data;
             if (self.ajaxAborted && typeof self.ajaxAborted === "object" && self.ajaxAborted.message !== undefined) {
-                data = $.extend(self.getOutData(), params);
+                data = $.extend(true, {}, self.getOutData(), params);
                 data.abortData = self.ajaxAborted.data || {};
                 data.abortMessage = self.ajaxAborted.message;
                 self.cancel();
@@ -874,54 +924,18 @@
         destroy: function () {
             var self = this, $cont = self.$container;
             $cont.find('.file-drop-zone').off();
-            self.$element.insertBefore($cont).off('.fileinput').removeData();
+            self.$element.insertBefore($cont).off(NAMESPACE).removeData();
             $cont.off().remove();
         },
         refresh: function (options) {
             var self = this, $el = self.$element;
-            options = options ? $.extend(self.options, options) : self.options;
+            options = options ? $.extend(true, {}, self.options, options) : self.options;
             self.destroy();
             $el.fileinput(options);
             if ($el.val()) {
                 $el.trigger('change.fileinput');
             }
         },
-        initDragDrop: function () {
-            var self = this, $zone = self.$container.find('.file-drop-zone'),
-                allEvents = 'dragenter.fileinput dragover.fileinput drop.fileinput';
-            handler($zone, 'dragenter.fileinput dragover.fileinput', function (e) {
-                var hasFiles = $.inArray('Files', e.originalEvent.dataTransfer.types) > -1;
-                e.stopPropagation();
-                e.preventDefault();
-                if (self.isDisabled || !hasFiles) {
-                    e.originalEvent.dataTransfer.effectAllowed = 'none';
-                    e.originalEvent.dataTransfer.dropEffect = 'none';
-                    return;
-                }
-                addCss($(this), 'file-highlighted');
-            }, true);
-            handler($zone, 'dragleave', function (e) {
-                e.stopPropagation();
-                e.preventDefault();
-                if (self.isDisabled) {
-                    return;
-                }
-                $(this).removeClass('file-highlighted');
-            });
-            handler($zone, 'drop', function (e) {
-                e.preventDefault();
-                /** @namespace e.originalEvent.dataTransfer */
-                if (self.isDisabled || isEmpty(e.originalEvent.dataTransfer.files)) {
-                    return;
-                }
-                self.change(e, 'dragdrop');
-                $(this).removeClass('file-highlighted');
-            });
-            handler($(document), allEvents, function (e) {
-                e.stopPropagation();
-                e.preventDefault();
-            }, true);
-        },
         setFileDropZoneTitle: function () {
             var self = this, $zone = self.$container.find('.file-drop-zone');
             $zone.find('.' + self.dropZoneTitleClass).remove();
@@ -1071,11 +1085,11 @@
                     extraData = extraData();
                 }
                 params = {id: $el.attr('id'), key: vKey, extra: extraData};
-                settings = $.extend({
+                settings = $.extend(true, {}, {
                     url: vUrl,
                     type: 'POST',
                     dataType: 'json',
-                    data: $.extend({key: vKey}, extraData),
+                    data: $.extend(true, {}, {key: vKey}, extraData),
                     beforeSend: function (jqXHR) {
                         self.ajaxAborted = false;
                         self.raise('filepredelete', [vKey, jqXHR, extraData]);
@@ -1382,7 +1396,7 @@
             var self = this, settings;
             self.raise('filepreajax', [previewId, index]);
             self.uploadExtra(previewId, index);
-            settings = $.extend({
+            settings = $.extend(true, {}, {
                 xhr: function () {
                     var xhrobj = $.ajaxSettings.xhr();
                     return self.initXhr(xhrobj, previewId, self.getFileStack().length);
@@ -1537,7 +1551,7 @@
                     self.lock();
                 }
                 self.raise('filepreupload', [outData, previewId, i]);
-                params = $.extend(params, outData);
+                $.extend(true, params, outData);
                 if (self.abort(params)) {
                     jqXHR.abort();
                     self.setProgress(100);
@@ -1545,7 +1559,7 @@
             };
             fnSuccess = function (data, textStatus, jqXHR) {
                 outData = self.getOutData(jqXHR, data);
-                params = $.extend(params, outData);
+                $.extend(true, params, outData);
                 setTimeout(function () {
                     if (isEmpty(data) || isEmpty(data.error)) {
                         if (self.showPreview) {
@@ -1560,8 +1574,8 @@
                             updateUploadLog(i, previewId);
                         }
                     } else {
-                        self.setThumbStatus($thumb, 'Error');
                         self.showUploadError(data.error, params);
+                        self.setPreviewError($thumb, i);
                         if (allFiles) {
                             updateUploadLog(i, previewId);
                         }
@@ -1591,8 +1605,8 @@
                         updateUploadLog(i, previewId);
                     }
                     self.uploadStatus[previewId] = 100;
-                    self.setThumbStatus($thumb, 'Error');
-                    params = $.extend(params, self.getOutData(jqXHR));
+                    self.setPreviewError($thumb, i);
+                    $.extend(true, params, self.getOutData(jqXHR));
                     self.showUploadError(errMsg, params);
                 }, 100);
             };
@@ -1601,9 +1615,9 @@
             self.ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, previewId, i);
         },
         uploadBatch: function () {
-            var self = this, files = self.filestack, total = files.length, params = {},
-                hasPostData = self.filestack.length > 0 || !$.isEmptyObject(self.uploadExtraData),
-                setAllUploaded, fnBefore, fnSuccess, fnComplete, fnError;
+            var self = this, files = self.filestack, total = files.length, params = {}, fnBefore, fnSuccess, fnError,
+                fnComplete, hasPostData = self.filestack.length > 0 || !$.isEmptyObject(self.uploadExtraData),
+                setAllUploaded;
             self.formdata = new FormData();
             if (total === 0 || !hasPostData || self.abort(params)) {
                 return;
@@ -1663,11 +1677,11 @@
                             $btnUpload.removeAttr('disabled');
                             $btnDelete.removeAttr('disabled');
                             if (keys.length === 0) {
-                                self.setThumbStatus($thumb, 'Error');
+                                self.setPreviewError($thumb);
                                 return;
                             }
                             if ($.inArray(key, keys) !== -1) {
-                                self.setThumbStatus($thumb, 'Error');
+                                self.setPreviewError($thumb);
                             } else {
                                 $thumb.find('.kv-file-upload').hide();
                                 self.setThumbStatus($thumb, 'Success');
@@ -1698,7 +1712,7 @@
                     var $thumb = $(this), key = $thumb.attr('data-fileindex');
                     $thumb.removeClass('file-uploading');
                     if (self.filestack[key] !== undefined) {
-                        self.setThumbStatus($thumb, 'Error');
+                        self.setPreviewError($thumb);
                     }
                 });
                 self.getThumbs().removeClass('file-uploading');
@@ -1861,7 +1875,7 @@
             var self = this, $error = self.$errorContainer;
             if (msg && $error.length) {
                 $error.html(self.errorCloseButton + msg);
-                $error.find('.kv-error-close').off('click').on('click', function () {
+                handler($error.find('.kv-error-close'), 'click', function () {
                     $error.fadeOut('slow');
                 });
             }
@@ -2017,7 +2031,7 @@
             }
         },
         slugDefault: function (text) {
-            return isEmpty(text) ? '' : String(text).replace(/[\-\[\]\/\{}\(\)\*\+\?\\\^\$\|<>&"']/g, '_');
+            return isEmpty(text) ? '' : String(text).replace(/[\-\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g, '_');
         },
         readFiles: function (files) {
             this.reader = new FileReader();
@@ -2026,14 +2040,17 @@
                 msgProgress = self.msgProgress, previewInitId = self.previewInitId, numFiles = files.length,
                 settings = self.fileTypeSettings, ctr = self.filestack.length, readFile,
                 throwError = function (msg, file, previewId, index) {
-                    var p1 = $.extend(self.getOutData({}, {}, files), {id: previewId, index: index}),
+                    var p1 = $.extend(true, {}, self.getOutData({}, {}, files), {id: previewId, index: index}),
                         p2 = {id: previewId, index: index, file: file, files: files};
                     self.previewDefault(file, previewId, true);
                     if (self.isUploadable) {
-                        self.pushStack(undefined);
+                        self.addToStack(undefined);
                     }
                     setTimeout(readFile(index + 1), 100);
                     self.initFileActions();
+                    if (self.removeFromPreviewOnError) {
+                        $('#' + previewId).remove();
+                    }
                     return self.isUploadable ? self.showUploadError(msg, p1) : self.showError(msg, p2);
                 };
 
@@ -2041,9 +2058,7 @@
             self.totalImagesCount = 0;
 
             $.each(files, function (key, file) {
-                var cat = 'image',
-                    func = isSet(cat,
-                        self.fileTypeSettings) ? self.fileTypeSettings[cat] : defaultFileTypeSettings[cat];
+                var func = self.fileTypeSettings.image || defaultFileTypeSettings.image;
                 if (func && func(file.type)) {
                     self.totalImagesCount++;
                 }
@@ -2103,7 +2118,7 @@
                     }
                 }
                 if (!self.showPreview) {
-                    self.pushStack(file);
+                    self.addToStack(file);
                     setTimeout(readFile(i + 1), 100);
                     self.raise('fileloaded', [file, previewId, i, reader]);
                     return;
@@ -2153,7 +2168,7 @@
                     }, 100);
                     self.raise('fileloaded', [file, previewId, i, reader]);
                 }
-                self.pushStack(file);
+                self.addToStack(file);
             };
 
             readFile(0);
@@ -2161,10 +2176,9 @@
         },
         updateFileDetails: function (numFiles) {
             var self = this, $el = self.$element, fileStack = self.getFileStack(),
-                name = $el.val() || (fileStack.length && fileStack[0].name) || '', label = self.slug(name),
-                n = self.isUploadable ? fileStack.length : numFiles,
-                nFiles = previewCache.count(self.id) + n,
-                log = n > 1 ? self.getMsgSelected(nFiles) : label;
+                name = $el[0].files[0].name || (fileStack.length && fileStack[0].name) || '',
+                label = self.slug(name), n = self.isUploadable ? fileStack.length : numFiles,
+                nFiles = previewCache.count(self.id) + n, log = n > 1 ? self.getMsgSelected(nFiles) : label;
             if (self.isError) {
                 self.$previewContainer.removeClass('file-thumb-loading');
                 self.$previewStatus.html('');
@@ -2204,13 +2218,11 @@
                 return;
             }
             self.fileInputCleared = false;
-            var tfiles, msg, total, isDragDrop = arguments.length > 1,
-                files = isDragDrop ? e.originalEvent.dataTransfer.files : $el.get(0).files,
-                isSingleUpload = isEmpty($el.attr('multiple')), i = 0, f, n, folders = 0,
-                ctr = self.filestack.length, isAjaxUpload = self.isUploadable, len,
-                flagSingle = (isSingleUpload && ctr > 0),
+            var tfiles, msg, total, isDragDrop = arguments.length > 1, isAjaxUpload = self.isUploadable, i = 0, f, n, len,
+                files = isDragDrop ? e.originalEvent.dataTransfer.files : $el.get(0).files, ctr = self.filestack.length,
+                isSingleUpload = isEmpty($el.attr('multiple')), flagSingle = (isSingleUpload && ctr > 0), folders = 0,
                 throwError = function (mesg, file, previewId, index) {
-                    var p1 = $.extend(self.getOutData({}, {}, files), {id: previewId, index: index}),
+                    var p1 = $.extend(true, {}, self.getOutData({}, {}, files), {id: previewId, index: index}),
                         p2 = {id: previewId, index: index, file: file, files: files};
                     return self.isUploadable ? self.showUploadError(mesg, p1) : self.showError(mesg, p2);
                 };
@@ -2309,11 +2321,22 @@
             self.filestack[i] = file;
             self.filenames[i] = self.getFileName(file);
         },
-        pushStack: function (file) {
+        addToStack: function (file) {
             var self = this;
             self.filestack.push(file);
             self.filenames.push(self.getFileName(file));
         },
+        setPreviewError: function ($thumb, i, val) {
+            var self = this;
+            if (i) {
+                self.updateStack(i, val);
+            }
+            if (self.removeFromPreviewOnError) {
+                $thumb.remove();
+            } else {
+                self.setThumbStatus($thumb, 'Error');
+            }
+        },
         checkDimensions: function (i, chk, $img, $thumb, fname, type, params) {
             var self = this, msg, dim, tag = chk === 'Small' ? 'min' : 'max',
                 limit = self[tag + 'Image' + type], $imgEl, isValid;
@@ -2328,8 +2351,7 @@
             }
             msg = self['msgImage' + type + chk].replace('{name}', fname).replace('{size}', limit);
             self.showUploadError(msg, params);
-            self.setThumbStatus($thumb, 'Error');
-            self.updateStack(i, null);
+            self.setPreviewError($thumb, i, null);
         },
         validateImage: function (i, previewId, fname, ftype) {
             var self = this, $preview = self.$preview, params, w1, w2,
@@ -2377,8 +2399,7 @@
                 params = {id: pid, 'index': ind};
                 if (!self.getResizedImage($img[0], config.typ, pid, ind)) {
                     errFunc(self.msgImageResizeError, params, 'fileimageresizeerror');
-                    self.setThumbStatus($thumb, 'Error');
-                    self.updateStack(ind, undefined);
+                    self.setPreviewError($thumb, ind);
                 }
             }
             self.raise('fileimagesresized');
@@ -2535,13 +2556,14 @@
         args.shift();
         this.each(function () {
             var self = $(this), data = self.data('fileinput'), options = typeof option === 'object' && option,
-                lang = options.language || self.data('language') || 'en', config = $.fn.fileinput.defaults;
+                lang = options.language || self.data('language') || 'en', loc = {}, opts;
 
             if (!data) {
                 if (lang !== 'en' && !isEmpty($.fn.fileinputLocales[lang])) {
-                    $.extend(config, $.fn.fileinputLocales[lang]);
+                    loc = $.fn.fileinputLocales[lang];
                 }
-                data = new FileInput(this, $.extend(config, options, self.data()));
+                opts = $.extend(true, {}, $.fn.fileinput.defaults, $.fn.fileinputLocales.en, loc, options, self.data());
+                data = new FileInput(this, opts);
                 self.data('fileinput', data);
             }
 
@@ -2580,6 +2602,7 @@
         initialPreviewThumbTags: [],
         previewThumbTags: {},
         initialPreviewShowDelete: true,
+        removeFromPreviewOnError: true,
         deleteUrl: '',
         deleteExtraData: {},
         overwriteInitial: true,
@@ -2685,13 +2708,10 @@
         dropZoneTitle: 'Drag & drop files here &hellip;'
     };
 
-    $.extend($.fn.fileinput.defaults, $.fn.fileinputLocales.en);
-
     $.fn.fileinput.Constructor = FileInput;
 
     /**
-     * Convert automatically file inputs with class 'file'
-     * into a bootstrap fileinput control.
+     * Convert automatically file inputs with class 'file' into a bootstrap fileinput control.
      */
     $(document).ready(function () {
         var $input = $('input.file[type=file]');

Datei-Diff unterdrückt, da er zu groß ist
+ 5 - 6
js/fileinput.min.js


Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.