Browse Source

Fix #389: New templates and styling enhancements to caption and main buttons

Kartik Visweswaran 9 years ago
parent
commit
ba84b21c3d
6 changed files with 77 additions and 105 deletions
  1. 1 0
      CHANGE.md
  2. 18 1
      README.md
  3. 4 34
      css/fileinput.css
  4. 0 0
      css/fileinput.min.css
  5. 54 70
      js/fileinput.js
  6. 0 0
      js/fileinput.min.js

+ 1 - 0
CHANGE.md

@@ -14,6 +14,7 @@ Change Log: `bootstrap-fileinput`
 7. Update translations to include `fileActionSettings`.
 8. (enh #382): Better implementation for parsing text in `parseError` method.
 9. (enh #385): Updated Russian & Ukranian translations.
+10. (enh #389): New templates and styling enhancements to caption and main buttons.
 
 ## version 4.2.5
 

+ 18 - 1
README.md

@@ -437,6 +437,9 @@ The `layoutTemplates` if not set will default to:
         '   <span class="file-caption-ellipsis">&hellip;</span>\n' +
         '   <div class="file-caption-name"></div>\n' +
         '</div>',
+    btnDefault: '<button type="{type}" tabindex="500" title="{title}" class="{css}"{status}>{icon}{label}</button>',
+    btnLink: '<a href="{href}" tabindex="500" title="{title}" class="{css}"{status}>{icon}{label}</a>',
+    btnBrowse: '<div tabindex="500" class="{css}"{status}>{icon}{label}</div>',
     modal: '<div id="{id}" class="modal fade">\n' +
         '  <div class="modal-dialog modal-lg">\n' +
         '    <div class="modal-content">\n' +
@@ -502,7 +505,21 @@ The following tags will be parsed and replaced in each of the templates:
 - `{zoomInd}`: currently applicable only for text file previews. This will be replaced with the `zoomIndicator` property. This is the title that is displayed on hover of the zoom button (which on clicking will display the text file).
 - `{heading}`: currently applicable only for text file previews. This represents the modal dialog heading title. This will be replaced with the `msgZoomModalHeading` property. 
 
-As noted, if you are coming from an earlier release (before v2.4.0), all preview templates have now been combined into one property, instead of separate templates for image, text etc. 
+The following templates will be used in rendering the main buttons for upload, remove, cancel, and browse.
+
+- `btnDefault`: The template for upload, remove, and cancel buttons
+- `btnLink`: The template for upload button when used with ajax (i.e. when `uploadUrl` is set).
+- `btnBrowse`: The template for the browse button.
+
+The following tags will be parsed and auto replaced in the above button templates:
+
+- `{type}`: the HTML button type, defaults to `button` for most buttons and `submit` for form based uploads
+- `{title}`: the title to display on button hover.
+- `{css}`: the CSS class for the button. This is derived from settings for `uploadClass` or `removeClass` or `cancelClass` or `browseClass`.
+- `{status}`: the disabled status for the button if available (else will be blank).
+- `{icon}`: the button icon as identified by `uploadIcon` or `removeIcon` or `cancelIcon` or `browseIcon`.
+- `{label}`: the button label as identified by `uploadLabel` or `removeLabel` or `cancelLabel` or `browseLabel`.
+- `{href}`: applicable only for Upload button for ajax uploads and will be replaced with the `uploadUrl` property.
 
 The `previewTemplates` if not set will default to:
 

+ 4 - 34
css/fileinput.css

@@ -9,10 +9,6 @@
  * Year: 2015
  * For more Yii related demos visit http://demos.krajee.com
  */
-.file-input {
-    overflow-x: auto;
-}
-
 .file-loading {
     top: 0;
     right: 0;
@@ -43,47 +39,21 @@
     display: block;
 }
 
-.file-caption .glyphicon {
-    display: inline-block;
-    min-width: 18px;
-    margin-top: 2px;
-}
-
 .file-caption-name {
     display: inline-block;
     overflow: hidden;
-    padding-right: 10px;
+    height: 20px;
     word-break: break-all;
 }
 
-.file-caption-ellipsis {
-    position: absolute;
-    right: 10px;
-    margin-top: -6px;
-    font-size: 1.2em;
-    display: none;
-    font-weight: bold;
-    cursor: default;
+.input-group-lg .file-caption-name {
+    height: 25px;
 }
 
 .file-preview-detail-modal  {
     text-align: left;
 }
 
-.kv-has-ellipsis .file-caption-ellipsis {
-    display: inline;
-}
-
-.kv-has-ellipsis {
-    padding-right: 17px;
-}
-
-.kv-search-container .kv-search-clear {
-    position: absolute;
-    padding: 10px;
-    right: 0;
-}
-
 .file-error-message {
     background-color: #f2dede;
     color: #a94442;
@@ -248,6 +218,6 @@
     opacity: 0.6;
 }
 
-.file-input .btn[disabled], .file-input .btn .disabled, .file-input .btn[disabled] *, .file-input .btn .disabled * {
+.file-input .btn[disabled], .file-input .btn.disabled, .file-input .btn[disabled] *, .file-input .btn.disabled * {
     cursor: not-allowed;
 }

File diff suppressed because it is too large
+ 0 - 0
css/fileinput.min.css


+ 54 - 70
js/fileinput.js

@@ -249,10 +249,12 @@
             '    </div>\n' +
             '</div>',
         tIcon = '<span class="glyphicon glyphicon-file kv-caption-icon"></span>',
-        tCaption = '<div tabindex="-1" class="form-control file-caption {class}">\n' +
-            '   <span class="file-caption-ellipsis">&hellip;</span>\n' +
+        tCaption = '<div tabindex="500" class="form-control file-caption {class}">\n' +
             '   <div class="file-caption-name"></div>\n' +
-            '</div>',
+            '</div>\n',
+        tBtnDefault = '<button type="{type}" tabindex="500" title="{title}" class="{css}"{status}>{icon}{label}</button>',
+        tBtnLink = '<a href="{href}" tabindex="500" title="{title}" class="{css}"{status}>{icon}{label}</a>',
+        tBtnBrowse = '<div tabindex="500" class="{css}"{status}>{icon}{label}</div>',
         tModal = '<div id="{id}" class="file-preview-detail-modal modal fade" tabindex="-1">\n' +
             '  <div class="modal-dialog modal-lg">\n' +
             '    <div class="modal-content">\n' +
@@ -359,7 +361,10 @@
             footer: tFooter,
             actions: tActions,
             actionDelete: tActionDelete,
-            actionUpload: tActionUpload
+            actionUpload: tActionUpload,
+            btnDefault: tBtnDefault,
+            btnLink: tBtnLink,
+            btnBrowse: tBtnBrowse
         },
         defaultPreviewTemplates = {
             generic: tGeneric,
@@ -517,7 +522,7 @@
                 self.refreshContainer();
             }
             self.$progress = self.$container.find('.kv-upload-progress');
-            self.$btnUpload = self.$container.find('.kv-fileinput-upload');
+            self.$btnUpload = self.$container.find('.fileinput-upload');
             self.$captionContainer = getElement(options, 'elCaptionContainer', self.$container.find('.file-caption'));
             self.$caption = getElement(options, 'elCaptionText', self.$container.find('.file-caption-name'));
             self.$previewContainer = getElement(options, 'elPreviewContainer', self.$container.find('.file-preview'));
@@ -543,7 +548,6 @@
             t = self.getLayoutTemplate('progress');
             self.progressTemplate = t.replace('{class}', self.progressClass);
             self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass);
-            self.setEllipsis();
         },
         parseError: function (jqXHR, errorThrown, fileName) {
             var self = this, errMsg = $.trim(errorThrown + ''),
@@ -642,23 +646,10 @@
                 jqXHR: jqXHR
             };
         },
-        setEllipsis: function () {
-            var self = this, $capCont = self.$captionContainer, $cap = self.$caption,
-                $div = $cap.clone().css('height', 'auto').hide();
-            $capCont.parent().before($div);
-            $capCont.removeClass('kv-has-ellipsis');
-            if ($div.outerWidth() > $cap.outerWidth()) {
-                $capCont.addClass('kv-has-ellipsis');
-            }
-            $div.remove();
-        },
         listen: function () {
             var self = this, $el = self.$element, $cap = self.$captionContainer, $btnFile = self.$btnFile,
                 $form = $el.closest('form'), $cont = self.$container;
             handler($el, 'change', $.proxy(self.change, self));
-            handler($(window), 'resize', function () {
-                self.setEllipsis();
-            });
             handler($btnFile, 'click', function () {
                 self.raise('filebrowse');
                 if (self.isError && !self.isUploadable) {
@@ -675,7 +666,7 @@
             if (!self.isUploadable) {
                 handler($form, 'submit', $.proxy(self.submitForm, self));
             }
-            handler(self.$container.find('.kv-fileinput-upload'), 'click', function (e) {
+            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') {
@@ -1178,7 +1169,6 @@
             if (self.hasInitialPreview()) {
                 self.showFileIcon();
                 self.resetPreview();
-                self.setEllipsis();
                 self.initPreviewDeletes();
                 self.$container.removeClass('file-input-new');
             } else {
@@ -1191,7 +1181,6 @@
                 self.$preview.html('');
                 cap = (!self.overwriteInitial && self.initialCaption.length > 0) ? self.initialCaption : '';
                 self.setCaption(cap);
-                self.setEllipsis();
                 self.$caption.attr('title', '');
                 addCss(self.$container, 'file-input-new');
             }
@@ -1199,7 +1188,6 @@
                 if (!self.initCaption()) {
                     self.$captionContainer.find('.kv-caption-icon').hide();
                 }
-                self.setEllipsis();
             }
             self.hideFileIcon();
             self.raise('filecleared');
@@ -1236,7 +1224,6 @@
         reset: function () {
             var self = this;
             self.resetPreview();
-            self.setEllipsis();
             self.$container.find('.fileinput-filename').text('');
             self.raise('filereset');
             addCss(self.$container, 'file-input-new');
@@ -1253,7 +1240,7 @@
             self.raise('filedisabled');
             self.$element.attr('disabled', 'disabled');
             self.$container.find(".kv-fileinput-caption").addClass("file-caption-disabled");
-            self.$container.find(".btn-file, .fileinput-remove, .kv-fileinput-upload, .file-preview-frame button").attr("disabled",
+            self.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").attr("disabled",
                 true);
             self.initDragDrop();
         },
@@ -1263,7 +1250,7 @@
             self.raise('fileenabled');
             self.$element.removeAttr('disabled');
             self.$container.find(".kv-fileinput-caption").removeClass("file-caption-disabled");
-            self.$container.find(".btn-file, .fileinput-remove, .kv-fileinput-upload, .file-preview-frame button").removeAttr("disabled");
+            self.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").removeAttr("disabled");
             self.initDragDrop();
         },
         getThumbs: function (css) {
@@ -2017,7 +2004,6 @@
                     self.isError = throwError(msg, null, null, null);
                     self.$captionContainer.find('.kv-caption-icon').hide();
                     self.setCaption('', true);
-                    self.setEllipsis();
                     self.$container.removeClass('file-input-new file-input-ajax-new');
                     return;
                 }
@@ -2108,7 +2094,6 @@
             self.$caption.html(out);
             self.$caption.attr('title', title);
             self.$captionContainer.find('.file-caption-ellipsis').attr('title', title);
-            self.setEllipsis();
         },
         initBrowse: function ($container) {
             var self = this;
@@ -2139,50 +2124,49 @@
             return self.mainTemplate.replace(/\{class\}/g, self.mainClass)
                 .replace(/\{preview\}/g, preview)
                 .replace(/\{caption\}/g, caption)
-                .replace(/\{upload\}/g, self.renderUpload())
-                .replace(/\{remove\}/g, self.renderRemove())
-                .replace(/\{cancel\}/g, self.renderCancel())
-                .replace(/\{browse\}/g, self.renderBrowse());
-        },
-        renderBrowse: function () {
-            var self = this, css = self.browseClass + ' btn-file', status = '';
-            if (self.isDisabled) {
-                status = ' disabled ';
-            }
-            return '<div class="' + css + '"' + status + '> ' + self.browseIcon + self.browseLabel + ' </div>';
-        },
-        renderRemove: function () {
-            var self = this, css = self.removeClass + ' fileinput-remove fileinput-remove-button', status = '';
-            if (!self.showRemove) {
-                return '';
-            }
-            if (self.isDisabled) {
-                status = ' disabled ';
-            }
-            return '<button type="button" title="' + self.removeTitle + '" class="' + css + '"' + status + '>' + self.removeIcon + self.removeLabel + '</button>';
-        },
-        renderCancel: function () {
-            var self = this, css = self.cancelClass + ' fileinput-cancel fileinput-cancel-button';
-            if (!self.showCancel) {
-                return '';
+                .replace(/\{upload\}/g, self.renderButton('upload'))
+                .replace(/\{remove\}/g, self.renderButton('remove'))
+                .replace(/\{cancel\}/g, self.renderButton('cancel'))
+                .replace(/\{browse\}/g, self.renderButton('browse'));
+        },
+        renderButton: function(type) {
+            var self = this, tmplt = self.getLayoutTemplate('btnDefault'), css = self[type + 'Class'],
+                status = self.isDisabled ? ' disabled' : '', title = self[type + 'Title'],
+                icon = self[type + 'Icon'], label = self[type + 'Label'], btnType = 'button';
+            switch (type) {
+                case 'remove':
+                    if (!self.showRemove) {
+                        return '';
+                    }
+                    break;
+                case 'cancel':
+                    if (!self.showCancel) {
+                        return '';
+                    }
+                    css += ' hide';
+                    break;
+                case 'upload':
+                    if (!self.showUpload) {
+                        return '';
+                    }
+                    if (self.isUploadable && !self.isDisabled) {
+                        tmplt = self.getLayoutTemplate('btnLink').replace('{href}', self.uploadUrl);
+                    } else {
+                        btnType = 'submit';
+                    }
+                    break;
+                case 'browse':
+                    tmplt = self.getLayoutTemplate('btnBrowse');
+                    break;
             }
-            return '<button type="button" title="' + self.cancelTitle + '" class="hide ' + css + '">' + self.cancelIcon + self.cancelLabel + '</button>';
+            css += type === 'browse' ? ' btn-file' : ' fileinput-' + type + ' fileinput-' + type + '-button';
+            return tmplt.replace('{type}', btnType)
+                .replace('{css}', css)
+                .replace('{title}', title)
+                .replace('{status}', status)
+                .replace('{icon}', icon)
+                .replace('{label}', label);
         },
-        renderUpload: function () {
-            var self = this, css = self.uploadClass + ' kv-fileinput-upload fileinput-upload-button', content = '', status = '';
-            if (!self.showUpload) {
-                return '';
-            }
-            if (self.isDisabled) {
-                status = ' disabled ';
-            }
-            if (!self.isUploadable || self.isDisabled) {
-                content = '<button type="submit" title="' + self.uploadTitle + '"class="' + css + '"' + status + '>' + self.uploadIcon + self.uploadLabel + '</button>';
-            } else {
-                content = '<a href="' + self.uploadUrl + '" title="' + self.uploadTitle + '" class="' + css + '"' + status + '>' + self.uploadIcon + self.uploadLabel + '</a>';
-            }
-            return content;
-        }
     };
 
     //FileInput plugin definition

File diff suppressed because it is too large
+ 0 - 0
js/fileinput.min.js


Some files were not shown because too many files changed in this diff