From 91490709254b549a78fbf880707b70974f0f2de7 Mon Sep 17 00:00:00 2001 From: Kartik Visweswaran Date: Thu, 20 Mar 2014 13:40:49 +0530 Subject: [PATCH] Update FileInput to v2 - wraps Krajee JQuery plugin --- CHANGE.md | 9 ++ README.md | 2 +- assets/css/fileinput.css | 98 ------------ assets/css/fileinput.min.css | 21 --- assets/js/fileinput.js | 195 ----------------------- assets/js/fileinput.min.js | 15 -- composer.json | 3 +- widgets/FileInput.php | 229 +++------------------------ widgets/FileInputAsset.php | 2 +- widgets/assets/css/fileinput.css | 87 ---------- widgets/assets/css/fileinput.min.css | 11 -- widgets/assets/js/fileinput.js | 193 ---------------------- widgets/assets/js/fileinput.min.js | 16 -- 13 files changed, 36 insertions(+), 845 deletions(-) create mode 100644 CHANGE.md delete mode 100755 assets/css/fileinput.css delete mode 100755 assets/css/fileinput.min.css delete mode 100755 assets/js/fileinput.js delete mode 100755 assets/js/fileinput.min.js delete mode 100644 widgets/assets/css/fileinput.css delete mode 100644 widgets/assets/css/fileinput.min.css delete mode 100644 widgets/assets/js/fileinput.js delete mode 100644 widgets/assets/js/fileinput.min.js diff --git a/CHANGE.md b/CHANGE.md new file mode 100644 index 0000000..5b0c048 --- /dev/null +++ b/CHANGE.md @@ -0,0 +1,9 @@ +version 1.0.0 +============= +Initial release + +version 2.0.0 +============= +[enh # 40] FileInput widget now wraps the enhanced [JQuery Bootstrap FileInput Plugin](http://github.com/kartik-v/bootstrap-fileinput). + +The fileinput routines and rendering have been enhanced and offers ability to configure most options, call events, and methods. \ No newline at end of file diff --git a/README.md b/README.md index 92b587c..605184b 100755 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ The TouchSpin widget is a Yii 2 wrapper for for the [bootstrap-touchspin](http:/ #### FileInput [```VIEW DEMO```](http://demos.krajee.com/widget-details/fileinput) -The FileInput widget is a customized file input widget based on HTML5 file input. The widget enhances the default HTML file input with various features including the following: +The FileInput widget is a customized file input widget based on Krajee's [Bootstrap FileInput JQuery Plugin](http://plugins.krajee.com/file-input). The widget enhances the default HTML file input with various features including the following: * Specially styled for Bootstrap 3.0 with customizable buttons, caption, and preview * Ability to select and preview multiple files diff --git a/assets/css/fileinput.css b/assets/css/fileinput.css deleted file mode 100755 index bc1eede..0000000 --- a/assets/css/fileinput.css +++ /dev/null @@ -1,98 +0,0 @@ -/*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2013 - * @package yii2-widgets - * @version 1.0.0 - * - * File input styling for Twitter Bootstrap 3.0 - * Built for Yii Framework 2.0 - * Author: Kartik Visweswaran - * Year: 2013 - * For more Yii related demos visit http://demos.krajee.com - */ -.btn-file { - position: relative; - overflow: hidden; -} - -.btn-file input[type=file] { - position: absolute; - top: 0; - right: 0; - min-width: 100%; - min-height: 100%; - font-size: 999px; - text-align: right; - filter: alpha(opacity=0); - opacity: 0; - background: red; - cursor: inherit; - display: block; -} - -.file-input .btn[disabled], .file-input .btn .disabled { - filter: alpha(opacity=65) !important; - opacity: .65 !important; -} - -.file-preview { - border-radius: 5px; - border: 1px solid #ddd; - padding: 5px; - width: 100%; - margin-bottom: 5px; -} - -.file-preview-frame { - display: table; - margin: 8px; - height: 160px; - border: 1px solid #ddd; - box-shadow: 1px 1px 5px 0px #a2958a; - padding: 6px; - float: left; - text-align: center; -} - -.file-preview-frame:hover { - background-color: #eee; - box-shadow: 2px 2px 5px 0px #333; -} - -.file-preview-image { - height: 150px; - vertical-align: text-center; -} - -.file-preview-text { - display: table-cell; - width: 150px; - height: 150px; - color: #428bca; - font-size: 11px; - vertical-align: middle; - text-align: center; -} - -.file-preview-other { - display: table-cell; - width: 150px; - height: 150px; - font-family: Monaco, Consolas, monospace; - font-size: 11px; - vertical-align: middle; - text-align: center; -} - -.file-input-new .file-preview, .file-input-new .close, .file-input-new .glyphicon-file, .file-input-new .fileinput-remove-button, .file-input-new .fileinput-upload-button { - display: none; -} - -.loading { - background: transparent url('../img/loading.gif') no-repeat scroll center center content-box !important; -} - -.wrap-indicator { - font-weight: bold; - color: #245269; - cursor: pointer; -} \ No newline at end of file diff --git a/assets/css/fileinput.min.css b/assets/css/fileinput.min.css deleted file mode 100755 index 47ec7ac..0000000 --- a/assets/css/fileinput.min.css +++ /dev/null @@ -1,21 +0,0 @@ -/*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2013 - * @package yii2-widgets - * @version 1.0.0 - * - * File input styling for Twitter Bootstrap 3.0 - * Built for Yii Framework 2.0 - * Author: Kartik Visweswaran - * Year: 2013 - * For more Yii related demos visit http://demos.krajee.com - *//*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2013 - * @package yii2-widgets - * @version 1.0.0 - * - * File input styling for Twitter Bootstrap 3.0 - * Built for Yii Framework 2.0 - * Author: Kartik Visweswaran - * Year: 2013 - * For more Yii related demos visit http://demos.krajee.com - */.btn-file{position:relative;overflow:hidden}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:999px;text-align:right;filter:alpha(opacity=0);opacity:0;background:red;cursor:inherit;display:block}.file-input .btn .disabled,.file-input .btn[disabled]{filter:alpha(opacity=65)!important;opacity:.65!important}.file-preview{border-radius:5px;border:1px solid #ddd;padding:5px;width:100%;margin-bottom:5px}.file-preview-frame{display:table;margin:8px;height:160px;border:1px solid #ddd;box-shadow:1px 1px 5px 0 #a2958a;padding:6px;float:left;text-align:center}.file-preview-frame:hover{background-color:#eee;box-shadow:2px 2px 5px 0 #333}.file-preview-image{height:150px;vertical-align:text-center}.file-preview-text{display:table-cell;width:150px;height:150px;color:#428bca;font-size:11px;vertical-align:middle;text-align:center}.file-preview-other{display:table-cell;width:150px;height:150px;font-family:Monaco,Consolas,monospace;font-size:11px;vertical-align:middle;text-align:center}.file-input-new .close,.file-input-new .file-preview,.file-input-new .fileinput-remove-button,.file-input-new .fileinput-upload-button,.file-input-new .glyphicon-file{display:none}.loading{background:transparent url(../img/loading.gif) no-repeat scroll center center content-box!important}.wrap-indicator{font-weight:700;color:#245269;cursor:pointer} \ No newline at end of file diff --git a/assets/js/fileinput.js b/assets/js/fileinput.js deleted file mode 100755 index f056168..0000000 --- a/assets/js/fileinput.js +++ /dev/null @@ -1,195 +0,0 @@ -/*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2013 - * @package yii2-widgets - * @version 1.0.0 - * - * File input styled for Twitter Bootstrap 3.0 that utilizes HTML5 File Input's - * advanced features. This plugin is inspired by the blog article at - * http://www.abeautifulsite.net/blog/2013/08/whipping-file-inputs-into-shape-with-bootstrap-3/ - * and Jasny's File Input plugin http://jasny.github.io/bootstrap/javascript/#fileinput - * - * Built for Yii Framework 2.0. But this is useful for various scenarios. - * Author: Kartik Visweswaran - * Copyright: 2013, Kartik Visweswaran, Krajee.com - * For more Yii related demos visit http://demos.krajee.com - */ -(function ($) { - var isEmpty = function (value, trim) { - return value === null || value === undefined || value == [] - || value === '' || trim && $.trim(value) === ''; - } - var getValue = function (options, param, value) { - return (isEmpty(options) || isEmpty(options[param])) ? value : options[param]; - } - var isImageFile = function (type, name) { - return (typeof type !== "undefined") ? type.match('image.*') : name.match(/\.(gif|png|jpe?g)$/i); - } - var isTextFile = function (type, name) { - return (typeof type !== "undefined") ? type.match('text.*') : name.match(/\.(txt|md|csv|htm|html|php|ini)$/i); - } - var FileInput = function (element, options) { - this.$element = $(element) - - /* Initialize plugin option parameters */ - this.$input = getValue(options, 'elInput', this.$element.find(':file')); - this.$caption = getValue(options, 'elCaptionText', this.$element.find('.file-caption-name')); - this.$previewContainer = getValue(options, 'elPreviewContainer', this.$element.find('.file-preview')); - this.$preview = getValue(options, 'elPreviewImage', this.$element.find('.file-preview-thumbnails')); - this.$previewStatus = getValue(options, 'elPreviewStatus', this.$element.find('.file-preview-status')); - this.$msgLoading = getValue(options, 'msgLoading', 'Loading …'); - this.$msgProgress = getValue(options, 'msgProgress', 'Loaded {percent}% of {file}'); - this.$msgSelected = getValue(options, 'msgSelected', '{n} files selected') - this.$previewFileType = getValue(options, 'previewFileType', 'image') - this.$wrapTextLength = getValue(options, 'wrapTextLength', 250) - this.$wrapIndicator = getValue(options, 'wrapIndicator', ' […]') - - if (this.$input.length === 0) { - return - } - this.$name = this.$input.attr('name') || options.name - this.$hidden = this.$element.find('input[type=hidden][name="' + this.$name + '"]') - this.$isIE == (window.navigator.appName == 'Microsoft Internet Explorer') - - if (this.$hidden.length === 0) { - this.$hidden = $('') - this.$element.prepend(this.$hidden) - } - this.original = { - preview: this.$preview.html(), - hiddenVal: this.$hidden.val() - } - this.listen() - } - - FileInput.prototype = { - constructor: FileInput, - listen: function () { - this.$input.on('change', $.proxy(this.change, this)) - $(this.$input[0].form).on('reset', $.proxy(this.reset, this)) - this.$element.find('.fileinput-remove').on('click', $.proxy(this.clear, this)) - }, - trigger: function (e) { - this.$input.trigger('click') - e.preventDefault() - }, - clear: function (e) { - if (e) { - e.preventDefault() - } - - this.$hidden.val('') - this.$hidden.attr('name', this.name) - this.$input.attr('name', '') - - if (this.$isIE) { - var inputClone = this.$input.clone(true); - this.$input.after(inputClone); - this.$input.remove(); - this.$input = inputClone; - } else { - this.$input.val('') - } - if (e !== false) { - this.$input.trigger('change') - this.$element.trigger('fileclear') - } - this.$preview.html('') - this.$caption.html('') - this.$element.removeClass('file-input-new').addClass('file-input-new') - }, - reset: function (e) { - this.clear(false) - this.$hidden.val(this.original.hiddenVal) - this.$preview.html(this.original.preview) - this.$element.find('.fileinput-filename').text('') - this.$element.trigger('filereset') - }, - change: function (e) { - var elem = this.$input, files = elem.get(0).files, numFiles = files ? files.length : 1, - label = elem.val().replace(/\\/g, '/').replace(/.*\//, ''), preview = this.$preview, - container = this.$previewContainer, status = this.$previewStatus, msgLoading = this.$msgLoading, - msgProgress = this.$msgProgress, msgSelected = this.$msgSelected, tfiles, - fileType = this.$previewFileType, wrapLen = parseInt(this.$wrapTextLength), - wrapInd = this.$wrapIndicator - - if (e.target.files === undefined) { - tfiles = e.target && e.target.value ? [ - {name: e.target.value.replace(/^.+\\/, '')} - ] : [] - } - else { - tfiles = e.target.files - } - if (tfiles.length === 0) { - return - } - preview.html('') - var total = tfiles.length - for (var i = 0; i < total; i++) { - (function (file) { - var caption = file.name - var isImg = isImageFile(file.type, file.name) - var isTxt = isTextFile(file.type, file.name) - - if (preview.length > 0 && (fileType == "any" ? (isImg || isTxt) : (fileType == "text" ? isTxt : isImg)) && typeof FileReader !== "undefined") { - var reader = new FileReader(); - status.html(msgLoading) - container.addClass('loading') - reader.onload = function (theFile) { - var content = '' - if (isTxt) { - var strText = theFile.target.result - if (strText.length > wrapLen) { - wrapInd = wrapInd.replace("{title}", strText) - strText = strText.substring(0, (wrapLen - 1)) + wrapInd - } - content = '
' + strText + '
'; - } - else { - content = '
' + caption + '
'; - } - preview.append("\n" + content) - if (i >= total - 1) { - container.removeClass('loading') - status.html('') - } - } - reader.onprogress = function (data) { - if (data.lengthComputable) { - var progress = parseInt(((data.loaded / data.total) * 100), 10); - var msg = msgProgress.replace('{percent}', progress).replace('{file}', file.name) - status.html(msg); - } - } - if (isTxt) { - reader.readAsText(file); - } - else { - reader.readAsDataURL(file); - } - } - else { - preview.append("\n" + '

' + caption + '
') - } - })(tfiles[i]); - } - var log = numFiles > 1 ? msgSelected.replace('{n}', numFiles) : label; - this.$caption.html(log) - this.$element.removeClass('file-input-new') - elem.trigger('fileselect', [numFiles, label]); - } - } - - $.fn.fileinput = function (options) { - return this.each(function () { - var $this = $(this), data = $this.data('fileinput') - if (!data) { - $this.data('fileinput', (data = new FileInput(this, options))) - } - if (typeof options == 'string') { - data[options]() - } - }) - }; - -})(window.jQuery); \ No newline at end of file diff --git a/assets/js/fileinput.min.js b/assets/js/fileinput.min.js deleted file mode 100755 index 3cda9e4..0000000 --- a/assets/js/fileinput.min.js +++ /dev/null @@ -1,15 +0,0 @@ -/*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2013 - * @package yii2-widgets - * @version 1.0.0 - * - * File input styled for Twitter Bootstrap 3.0 that utilizes HTML5 File Input's - * advanced features. This plugin is inspired by the blog article at - * http://www.abeautifulsite.net/blog/2013/08/whipping-file-inputs-into-shape-with-bootstrap-3/ - * and Jasny's File Input plugin http://jasny.github.io/bootstrap/javascript/#fileinput - * - * Built for Yii Framework 2.0. But this is useful for various scenarios. - * Author: Kartik Visweswaran - * Copyright: 2013, Kartik Visweswaran, Krajee.com - * For more Yii related demos visit http://demos.krajee.com - */(function(e){var t=function(t,n){return t===null||t===undefined||t==[]||t===""||n&&e.trim(t)===""};var n=function(e,n,r){return t(e)||t(e[n])?r:e[n]};var r=function(e,t){return typeof e!=="undefined"?e.match("image.*"):t.match(/\.(gif|png|jpe?g)$/i)};var i=function(e,t){return typeof e!=="undefined"?e.match("text.*"):t.match(/\.(txt|md|csv|htm|html|php|ini)$/i)};var s=function(t,r){this.$element=e(t);this.$input=n(r,"elInput",this.$element.find(":file"));this.$caption=n(r,"elCaptionText",this.$element.find(".file-caption-name"));this.$previewContainer=n(r,"elPreviewContainer",this.$element.find(".file-preview"));this.$preview=n(r,"elPreviewImage",this.$element.find(".file-preview-thumbnails"));this.$previewStatus=n(r,"elPreviewStatus",this.$element.find(".file-preview-status"));this.$msgLoading=n(r,"msgLoading","Loading …");this.$msgProgress=n(r,"msgProgress","Loaded {percent}% of {file}");this.$msgSelected=n(r,"msgSelected","{n} files selected");this.$previewFileType=n(r,"previewFileType","image");this.$wrapTextLength=n(r,"wrapTextLength",250);this.$wrapIndicator=n(r,"wrapIndicator",' […]');if(this.$input.length===0){return}this.$name=this.$input.attr("name")||r.name;this.$hidden=this.$element.find('input[type=hidden][name="'+this.$name+'"]');this.$isIE==(window.navigator.appName=="Microsoft Internet Explorer");if(this.$hidden.length===0){this.$hidden=e('');this.$element.prepend(this.$hidden)}this.original={preview:this.$preview.html(),hiddenVal:this.$hidden.val()};this.listen()};s.prototype={constructor:s,listen:function(){this.$input.on("change",e.proxy(this.change,this));e(this.$input[0].form).on("reset",e.proxy(this.reset,this));this.$element.find(".fileinput-remove").on("click",e.proxy(this.clear,this))},trigger:function(e){this.$input.trigger("click");e.preventDefault()},clear:function(e){if(e){e.preventDefault()}this.$hidden.val("");this.$hidden.attr("name",this.name);this.$input.attr("name","");if(this.$isIE){var t=this.$input.clone(true);this.$input.after(t);this.$input.remove();this.$input=t}else{this.$input.val("")}if(e!==false){this.$input.trigger("change");this.$element.trigger("fileclear")}this.$preview.html("");this.$caption.html("");this.$element.removeClass("file-input-new").addClass("file-input-new")},reset:function(e){this.clear(false);this.$hidden.val(this.original.hiddenVal);this.$preview.html(this.original.preview);this.$element.find(".fileinput-filename").text("");this.$element.trigger("filereset")},change:function(e){var t=this.$input,n=t.get(0).files,s=n?n.length:1,o=t.val().replace(/\\/g,"/").replace(/.*\//,""),u=this.$preview,f=this.$previewContainer,l=this.$previewStatus,h=this.$msgLoading,p=this.$msgProgress,d=this.$msgSelected,v,m=this.$previewFileType,g=parseInt(this.$wrapTextLength),y=this.$wrapIndicator;if(e.target.files===undefined){v=e.target&&e.target.value?[{name:e.target.value.replace(/^.+\\/,"")}]:[]}else{v=e.target.files}if(v.length===0){return}u.html("");var b=v.length;for(var w=0;w0&&(m=="any"?n||s:m=="text"?s:n)&&typeof FileReader!=="undefined"){var o=new FileReader;l.html(h);f.addClass("loading");o.onload=function(e){var n="";if(s){var r=e.target.result;if(r.length>g){y=y.replace("{title}",r);r=r.substring(0,g-1)+y}n='
'+r+"
"}else{n='
'+t+'
'}u.append("\n"+n);if(w>=b-1){f.removeClass("loading");l.html("")}};o.onprogress=function(t){if(t.lengthComputable){var n=parseInt(t.loaded/t.total*100,10);var r=p.replace("{percent}",n).replace("{file}",e.name);l.html(r)}};if(s){o.readAsText(e)}else{o.readAsDataURL(e)}}else{u.append('\n

'+t+"
")}})(v[w])}var E=s>1?d.replace("{n}",s):o;this.$caption.html(E);this.$element.removeClass("file-input-new");t.trigger("fileselect",[s,o])}};e.fn.fileinput=function(t){return this.each(function(){var n=e(this),r=n.data("fileinput");if(!r){n.data("fileinput",r=new s(this,t))}if(typeof t=="string"){r[t]()}})}})(window.jQuery) \ No newline at end of file diff --git a/composer.json b/composer.json index b3103f2..2cbe9cb 100755 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ "require": { "yiisoft/yii2": "dev-master", "yiisoft/yii2-bootstrap": "dev-master", - "kartik-v/bootstrap-star-rating": "dev-master" + "kartik-v/bootstrap-star-rating": "dev-master", + "kartik-v/bootstrap-fileinput": "dev-master" }, "autoload": { "psr-4": { diff --git a/widgets/FileInput.php b/widgets/FileInput.php index d94dec0..82fcf65 100755 --- a/widgets/FileInput.php +++ b/widgets/FileInput.php @@ -23,96 +23,20 @@ * versions IE9 and below, this widget will gracefully degrade to normal HTML * file input. * - * Bootstrap related file input styling inspired by the blog article at: - * http://www.abeautifulsite.net/blog/2013/08/whipping-file-inputs-into-shape-with-bootstrap-3/ - * and Jasny's File Input plugin at http://jasny.github.io/bootstrap/javascript/#fileinput + * Wrapper for the Bootstrap FileInput JQuery Plugin by Krajee + * + * @see http://plugins.krajee.com/bootstrap-fileinput + * @see https://github.com/kartik-v/bootstrap-fileinput * * @author Kartik Visweswaran - * @since 1.0 + * @since 2.0: C + * * @see http://twitter.github.com/typeahead.js/examples */ class FileInput extends InputWidget { - - /** - * @var array HTML attributes for the main widget container - */ - public $containerOptions = []; - - /** - * @var array HTML attributes for the file picker button. The following - * special options are additionally recognized: - * - icon: string the Bootstrap glyphicon suffix - * - label: the label for the button, this will be translated by Yii's i18n - */ - public $buttonOptions = []; - - /* - * @var array HTML attributes for the file removal/clearing button. The - * following special options are additionally recognized: - * - icon: string the Bootstrap glyphicon suffix - * - label: the label for the button, this will be translated by Yii's i18n - */ - public $removeOptions = []; - - /** - * @var array HTML attributes for the file upload button. The [[uploadRoute]] - * parameter if passed will be used as an action, else this button will - * default to a submit button. The following special options are additionally - * recognized: - * - icon: string the Bootstrap glyphicon suffix - * - label: the label for the button, this will be translated by Yii's i18n - */ - public $uploadOptions = []; - /** - * @var mixed The upload route/action url to process file upload when the - * upload button is clicked. If this variable is not set, the upload button - * action will default to a 'form submit'. This can be set to false to - * make the upload button behave like a normal HTML button without any action. - * This maybe useful for triggering customized javascript or ajax calls. - */ - public $uploadRoute; - - /* - * @var array HTML attributes for the file(s) preview container - */ - public $previewOptions = []; - - /** - * @var array HTML attributes for the bootstrap input group enclosing the - * file caption, file picker button, removal button, and the upload button - */ - public $groupOptions = []; - - /* - * @var array HTML attributes for the selected file(s) caption - */ - public $captionOptions = ['class' => 'form-control']; - - /** - * @var boolean whether to display the file caption. Defaults to true. - */ - public $showCaption = true; - - /** - * @var boolean whether to display the file preview. Defaults to true. - */ - public $showPreview = true; - - /** - * @var boolean whether to display the remove button. Defaults to true. - */ - public $showRemove = true; - - /* - * @var boolean whether to display the upload button. Defaults to true. - */ - public $showUpload = true; - - /** - * @var boolean whether to display a warning message for browsers running - * IE9 and below. Defaults to true. + * @var bool whether to show 'plugin unsupported' message for IE browser versions 9 & below */ public $showMessage = true; @@ -127,11 +51,6 @@ class FileInput extends InputWidget */ public $i18n = []; - /** - * @var boolean whether the widget is disabled - */ - private $_disabled = false; - /** * @var array initialize the FileInput widget */ @@ -145,44 +64,16 @@ public function init() 'basePath' => '@fileinput/messages' ]; } - $this->_disabled = (!empty($this->options['disabled']) && $this->options['disabled']); Yii::$app->i18n->translations['fileinput'] = $this->i18n; - Html::addCssClass($this->containerOptions, 'file-input file-input-new'); - if (empty($this->containerOptions['id'])) { - $this->containerOptions['id'] = $this->options['id'] . '-container'; - } - if (empty($this->buttonOptions['id'])) { - $this->buttonOptions['id'] = $this->options['id'] . '-button'; - } - if (empty($this->previewOptions['id'])) { - $this->previewOptions['id'] = $this->options['id'] . '-preview'; - } - if (empty($this->captionOptions['id'])) { - $this->captionOptions['id'] = $this->options['id'] . '-caption'; - } - $remove = ($this->showRemove) ? $this->renderRemove() . ' ' : ''; - $upload = ($this->showUpload) ? $this->renderUpload() . ' ' : ''; - $input = $remove . $upload . $this->renderInput(); - if ($this->showCaption) { - Html::addCssClass($this->groupOptions, 'input-group'); - $placement = ArrayHelper::remove($this->captionOptions, 'placement', 'before'); - $button = Html::tag('div', $input, ['class' => 'input-group-btn']); - $caption = $this->renderCaption(); - $content = ($placement == 'after') ? $button . $caption : $caption . $button; - $input = Html::tag('div', $content, $this->groupOptions); - } - if ($this->showPreview) { - $preview = $this->renderPreview(); - $input = $preview . "\n" . $input; - } $this->registerAssets(); + $input = $this->getInput('fileInput'); if ($this->showMessage) { - $validation = $this->showPreview ? 'file preview and multiple file upload' : 'multiple file upload'; + $validation = ArrayHelper::getValue($this->pluginOptions, 'showPreview', true) ? 'file preview and multiple file upload' : 'multiple file upload'; $message = '' . Yii::t('fileinput', 'Note:') . ' ' . Yii::t('fileinput', 'Your browser does not support {validation}. Try an alternative or more recent browser to access these features.', ['validation' => $validation]); $content = Html::tag('div', $message, $this->messageOptions); $input .= "\n
" . $this->validateIE($content); } - echo Html::tag('div', $input, $this->containerOptions); + echo $input; } /** @@ -198,92 +89,15 @@ protected function validateIE($content, $validation = 'lt IE 10') } /** - * Renders the file picker input - * - * @return string - */ - protected function renderInput() - { - $class = (empty($this->buttonOptions['class']) ? 'btn btn-primary btn-file' : 'btn-file'); - Html::addCssClass($this->buttonOptions, $class); - $label = ArrayHelper::remove($this->buttonOptions, 'label', Yii::t('fileinput', 'Browse') . '…'); - $icon = ArrayHelper::remove($this->buttonOptions, 'icon', 'folder-open'); - $label = ($label == false) ? '' : $label; - $icon = ($icon == false) ? '' : '  '; - if ($this->_disabled) { - $this->buttonOptions['disabled'] = 'disabled'; - } - $input = $this->getInput('fileInput'); - return Html::tag('div', $icon . $label . $input, $this->buttonOptions); - } - - /** - * Renders the file(s) removal button - * - * @return string - */ - protected function renderRemove() - { - $class = (empty($this->removeOptions['class']) ? 'btn btn-default fileinput-remove fileinput-remove-button' : 'fileinput-remove fileinput-remove-button'); - Html::addCssClass($this->removeOptions, $class); - $this->removeOptions['type'] = 'button'; - $label = ArrayHelper::remove($this->removeOptions, 'label', Yii::t('fileinput', 'Remove')); - $icon = ArrayHelper::remove($this->removeOptions, 'icon', 'ban-circle'); - $label = ($label == false) ? '' : $label; - $icon = ($icon == false) ? '' : '  '; - return Html::button($icon . $label, $this->removeOptions); - } - - /** - * Renders the file upload button - * - * @return string - */ - protected function renderUpload() - { - $class = (empty($this->uploadOptions['class']) ? 'btn btn-default fileinput-upload-button' : 'fileinput-upload-button'); - Html::addCssClass($this->uploadOptions, $class); - $label = ArrayHelper::remove($this->uploadOptions, 'label', Yii::t('fileinput', 'Upload')); - $icon = ArrayHelper::remove($this->uploadOptions, 'icon', 'upload'); - $label = ($label == false) ? '' : $label; - $icon = ($icon == false) ? '' : '  '; - if (isset($this->uploadRoute) && $this->uploadRoute != null) { - return Html::a($icon . $label, $this->uploadRoute, $this->uploadOptions); - } elseif ($this->uploadRoute === false) { - return Html::button($icon . $label, $this->uploadOptions); - } else { - return Html::submitButton($icon . $label, $this->uploadOptions); - } - } - - /** - * Renders the file caption - * - * @return string + * Set the default plugin option + * @param string $key the array key in [[pluginOptions]] + * @param string $value the value for the key in [[pluginOptions]] */ - protected function renderCaption() + private function setPluginDefault($key, $value) { - Html::addCssClass($this->captionOptions, 'file-caption'); - if ($this->_disabled) { - $this->captionOptions['disabled'] = 'disabled'; + if (empty($this->pluginOptions[$key])) { + $this->pluginOptions[$key] = $value; } - return Html::tag('div', ' ', $this->captionOptions); - } - - /** - * Renders the preview container for the selected file(s) - * - * @return string - */ - protected function renderPreview() - { - Html::addCssClass($this->previewOptions, 'file-preview'); - $previewProgress = "
\n"; - $previewContent = "
×
\n -
-
"; - $content = $previewProgress . "\n" . Html::tag('div', $previewContent, $this->previewOptions); - return $this->validateIE('') . $content; } /** @@ -293,15 +107,18 @@ public function registerAssets() { $view = $this->getView(); FileInputAsset::register($view); - /* - $view->registerJs('$(".wrap-indicator").popover({trigger: "hover"});'); - */ + + $this->setPluginDefault('browseLabel', Yii::t('fileinput', 'Browse') . '…'); + $this->setPluginDefault('uploadLabel', Yii::t('fileinput', 'Upload')); + $this->setPluginDefault('removeLabel', Yii::t('fileinput', 'Remove')); + foreach ($this->pluginOptions as $key => $value) { if (substr($key, 0, 2) === "el" && !($value instanceof JsExpression)) { $this->pluginOptions[$key] = new JsExpression($value); } } - $this->registerPlugin('fileinput', '$("#' . $this->containerOptions['id'] . '")'); + + $this->registerPlugin('fileinput'); } } \ No newline at end of file diff --git a/widgets/FileInputAsset.php b/widgets/FileInputAsset.php index dd44431..a2e59d6 100755 --- a/widgets/FileInputAsset.php +++ b/widgets/FileInputAsset.php @@ -19,7 +19,7 @@ class FileInputAsset extends AssetBundle public function init() { - $this->setSourcePath(__DIR__ . '/../assets'); + $this->setSourcePath('@vendor/kartik-v/bootstrap-fileinput'); $this->setupAssets('css', ['css/fileinput']); $this->setupAssets('js', ['js/fileinput']); parent::init(); diff --git a/widgets/assets/css/fileinput.css b/widgets/assets/css/fileinput.css deleted file mode 100644 index 08924aa..0000000 --- a/widgets/assets/css/fileinput.css +++ /dev/null @@ -1,87 +0,0 @@ -/*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2013 - * @package yii2-widgets - * @version 1.0.0 - * - * File input styling for Twitter Bootstrap 3.0 - * Built for Yii Framework 2.0 - * Author: Kartik Visweswaran - * Year: 2013 - * For more Yii related demos visit http://demos.krajee.com - */ -.btn-file { - position: relative; - overflow: hidden; -} -.btn-file input[type=file] { - position: absolute; - top: 0; - right: 0; - min-width: 100%; - min-height: 100%; - font-size: 999px; - text-align: right; - filter: alpha(opacity=0); - opacity: 0; - background: red; - cursor: inherit; - display: block; -} -.file-input .btn[disabled], .file-input .btn .disabled { - filter: alpha(opacity=65)!important; - opacity: .65!important; -} -.file-preview { - border-radius: 5px; - border: 1px solid #ddd; - padding: 5px; - width: 100%; - margin-bottom: 5px; -} -.file-preview-frame { - display:table; - margin: 8px; - height: 160px; - border: 1px solid #ddd; - box-shadow: 1px 1px 5px 0px #a2958a; - padding: 6px; - float: left; - text-align: center; -} -.file-preview-frame:hover { - background-color: #eee; - box-shadow: 2px 2px 5px 0px #333; -} -.file-preview-image { - height: 150px; - vertical-align: text-center; -} -.file-preview-text { - display: table-cell; - width: 150px; - height: 150px; - color: #428bca; - font-size: 11px; - vertical-align:middle; - text-align:center; -} -.file-preview-other { - display: table-cell; - width: 150px; - height: 150px; - font-family: Monaco, Consolas, monospace; - font-size: 11px; - vertical-align:middle; - text-align:center; -} -.file-input-new .file-preview, .file-input-new .close, .file-input-new .glyphicon-file, .file-input-new .fileinput-remove-button, .file-input-new .fileinput-upload-button { - display: none; -} -.loading { - background: transparent url('../img/loading.gif') no-repeat scroll center center content-box !important; -} -.wrap-indicator { - font-weight: bold; - color: #245269; - cursor: pointer; -} \ No newline at end of file diff --git a/widgets/assets/css/fileinput.min.css b/widgets/assets/css/fileinput.min.css deleted file mode 100644 index 5237cd4..0000000 --- a/widgets/assets/css/fileinput.min.css +++ /dev/null @@ -1,11 +0,0 @@ -/*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2013 - * @package yii2-widgets - * @version 1.0.0 - * - * File input styling for Twitter Bootstrap 3.0 - * Built for Yii Framework 2.0 - * Author: Kartik Visweswaran - * Year: 2013 - * For more Yii related demos visit http://demos.krajee.com - */.btn-file{position:relative;overflow:hidden}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:999px;text-align:right;filter:alpha(opacity=0);opacity:0;background:red;cursor:inherit;display:block}.file-input .btn[disabled],.file-input .btn .disabled{filter:alpha(opacity=65) !important;opacity:.65 !important}.file-preview{border-radius:5px;border:1px solid #ddd;padding:5px;width:100%;margin-bottom:5px}.file-preview-frame{display:table;margin:8px;height:160px;border:1px solid #ddd;box-shadow:1px 1px 5px 0 #a2958a;padding:6px;float:left;text-align:center}.file-preview-frame:hover{background-color:#eee;box-shadow:2px 2px 5px 0 #333}.file-preview-image{height:150px;vertical-align:text-center}.file-preview-text{display:table-cell;width:150px;height:150px;color:#428bca;font-size:11px;vertical-align:middle;text-align:center}.file-preview-other{display:table-cell;width:150px;height:150px;font-family:Monaco,Consolas,monospace;font-size:11px;vertical-align:middle;text-align:center}.file-input-new .file-preview,.file-input-new .close,.file-input-new .glyphicon-file,.file-input-new .fileinput-remove-button,.file-input-new .fileinput-upload-button{display:none}.loading{background:transparent url('../img/loading.gif') no-repeat scroll center center content-box !important}.wrap-indicator{font-weight:bold;color:#245269;cursor:pointer} \ No newline at end of file diff --git a/widgets/assets/js/fileinput.js b/widgets/assets/js/fileinput.js deleted file mode 100644 index a25581b..0000000 --- a/widgets/assets/js/fileinput.js +++ /dev/null @@ -1,193 +0,0 @@ -/*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2013 - * @package yii2-widgets - * @version 1.0.0 - * - * File input styled for Twitter Bootstrap 3.0 that utilizes HTML5 File Input's - * advanced features. This plugin is inspired by the blog article at - * http://www.abeautifulsite.net/blog/2013/08/whipping-file-inputs-into-shape-with-bootstrap-3/ - * and Jasny's File Input plugin http://jasny.github.io/bootstrap/javascript/#fileinput - * - * Built for Yii Framework 2.0. But this is useful for various scenarios. - * Author: Kartik Visweswaran - * Copyright: 2013, Kartik Visweswaran, Krajee.com - * For more Yii related demos visit http://demos.krajee.com - */ -(function($) { - var isEmpty = function(value, trim) { - return value === null || value === undefined || value == [] - || value === '' || trim && $.trim(value) === ''; - } - var getValue = function(options, param, value) { - return (isEmpty(options) || isEmpty(options[param])) ? value : options[param]; - } - var isImageFile = function(type, name) { - return (typeof type !== "undefined") ? type.match('image.*') : name.match(/\.(gif|png|jpe?g)$/i); - } - var isTextFile = function(type, name) { - return (typeof type !== "undefined") ? type.match('text.*') : name.match(/\.(txt|md|csv|htm|html|php|ini)$/i); - } - var FileInput = function(element, options) { - this.$element = $(element) - - /* Initialize plugin option parameters */ - this.$input = getValue(options, 'elInput', this.$element.find(':file')); - this.$caption = getValue(options, 'elCaptionText', this.$element.find('.file-caption-name')); - this.$previewContainer = getValue(options, 'elPreviewContainer', this.$element.find('.file-preview')); - this.$preview = getValue(options, 'elPreviewImage', this.$element.find('.file-preview-thumbnails')); - this.$previewStatus = getValue(options, 'elPreviewStatus', this.$element.find('.file-preview-status')); - this.$msgLoading = getValue(options, 'msgLoading', 'Loading …'); - this.$msgProgress = getValue(options, 'msgProgress', 'Loaded {percent}% of {file}'); - this.$msgSelected = getValue(options, 'msgSelected', '{n} files selected') - this.$previewFileType = getValue(options, 'previewFileType', 'image') - this.$wrapTextLength = getValue(options, 'wrapTextLength', 250) - this.$wrapIndicator = getValue(options, 'wrapIndicator', ' […]') - - if (this.$input.length === 0) { - return - } - this.$name = this.$input.attr('name') || options.name - this.$hidden = this.$element.find('input[type=hidden][name="' + this.$name + '"]') - this.$isIE == (window.navigator.appName == 'Microsoft Internet Explorer') - - if (this.$hidden.length === 0) { - this.$hidden = $('') - this.$element.prepend(this.$hidden) - } - this.original = { - preview: this.$preview.html(), - hiddenVal: this.$hidden.val() - } - this.listen() - } - - FileInput.prototype = { - constructor: FileInput, - listen: function() { - this.$input.on('change', $.proxy(this.change, this)) - $(this.$input[0].form).on('reset', $.proxy(this.reset, this)) - this.$element.find('.fileinput-remove').on('click', $.proxy(this.clear, this)) - }, - trigger: function(e) { - this.$input.trigger('click') - e.preventDefault() - }, - clear: function(e) { - if (e) { - e.preventDefault() - } - - this.$hidden.val('') - this.$hidden.attr('name', this.name) - this.$input.attr('name', '') - - if (this.$isIE) { - var inputClone = this.$input.clone(true); - this.$input.after(inputClone); - this.$input.remove(); - this.$input = inputClone; - } else { - this.$input.val('') - } - if (e !== false) { - this.$input.trigger('change') - this.$element.trigger('fileclear') - } - this.$preview.html('') - this.$caption.html('') - this.$element.removeClass('file-input-new').addClass('file-input-new') - }, - reset: function(e) { - this.clear(false) - this.$hidden.val(this.original.hiddenVal) - this.$preview.html(this.original.preview) - this.$element.find('.fileinput-filename').text('') - this.$element.trigger('filereset') - }, - change: function(e) { - var elem = this.$input, files = elem.get(0).files, numFiles = files ? files.length : 1, - label = elem.val().replace(/\\/g, '/').replace(/.*\//, ''), preview = this.$preview, - container = this.$previewContainer, status = this.$previewStatus, msgLoading = this.$msgLoading, - msgProgress = this.$msgProgress, msgSelected = this.$msgSelected, tfiles, - fileType = this.$previewFileType, wrapLen = parseInt(this.$wrapTextLength), - wrapInd = this.$wrapIndicator - - if (e.target.files === undefined) { - tfiles = e.target && e.target.value ? [{name: e.target.value.replace(/^.+\\/, '')}] : [] - } - else { - tfiles = e.target.files - } - if (tfiles.length === 0) { - return - } - preview.html('') - var total = tfiles.length - for (var i = 0; i < total; i++) { - (function(file) { - var caption = file.name - var isImg = isImageFile(file.type, file.name) - var isTxt = isTextFile(file.type, file.name) - - if (preview.length > 0 && (fileType == "any" ? (isImg || isTxt) : (fileType == "text" ? isTxt : isImg)) && typeof FileReader !== "undefined") { - var reader = new FileReader(); - status.html(msgLoading) - container.addClass('loading') - reader.onload = function(theFile) { - var content = '' - if (isTxt) { - var strText = theFile.target.result - if (strText.length > wrapLen) { - wrapInd = wrapInd.replace("{title}", strText) - strText = strText.substring(0, (wrapLen - 1)) + wrapInd - } - content = '
' + strText + '
'; - } - else { - content = '
' + caption + '
'; - } - preview.append("\n" + content) - if (i >= total - 1) { - container.removeClass('loading') - status.html('') - } - } - reader.onprogress = function(data) { - if (data.lengthComputable) { - var progress = parseInt(((data.loaded / data.total) * 100), 10); - var msg = msgProgress.replace('{percent}', progress).replace('{file}', file.name) - status.html(msg); - } - } - if (isTxt) { - reader.readAsText(file); - } - else { - reader.readAsDataURL(file); - } - } - else { - preview.append("\n" + '

' + caption + '
') - } - })(tfiles[i]); - } - var log = numFiles > 1 ? msgSelected.replace('{n}', numFiles) : label; - this.$caption.html(log) - this.$element.removeClass('file-input-new') - elem.trigger('fileselect', [numFiles, label]); - } - } - - $.fn.fileinput = function(options) { - return this.each(function() { - var $this = $(this), data = $this.data('fileinput') - if (!data) { - $this.data('fileinput', (data = new FileInput(this, options))) - } - if (typeof options == 'string') { - data[options]() - } - }) - }; - -})(window.jQuery); \ No newline at end of file diff --git a/widgets/assets/js/fileinput.min.js b/widgets/assets/js/fileinput.min.js deleted file mode 100644 index fcf032e..0000000 --- a/widgets/assets/js/fileinput.min.js +++ /dev/null @@ -1,16 +0,0 @@ -/*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2013 - * @package yii2-widgets - * @version 1.0.0 - * - * File input styled for Twitter Bootstrap 3.0 that utilizes HTML5 File Input's - * advanced features. This plugin is inspired by the blog article at - * http://www.abeautifulsite.net/blog/2013/08/whipping-file-inputs-into-shape-with-bootstrap-3/ - * and Jasny's File Input plugin http://jasny.github.io/bootstrap/javascript/#fileinput - * - * Built for Yii Framework 2.0. But this is useful for various scenarios. - * Author: Kartik Visweswaran - * Copyright: 2013, Kartik Visweswaran, Krajee.com - * For more Yii related demos visit http://demos.krajee.com - */ -(function(e){var f=function(h,g){return h===null||h===undefined||h==[]||h===""||g&&e.trim(h)===""};var b=function(g,i,h){return(f(g)||f(g[i]))?h:g[i]};var a=function(h,g){return(typeof h!=="undefined")?h.match("image.*"):g.match(/\.(gif|png|jpe?g)$/i)};var c=function(h,g){return(typeof h!=="undefined")?h.match("text.*"):g.match(/\.(txt|md|csv|htm|html|php|ini)$/i)};var d=function(h,g){this.$element=e(h);this.$input=b(g,"elInput",this.$element.find(":file"));this.$caption=b(g,"elCaptionText",this.$element.find(".file-caption-name"));this.$previewContainer=b(g,"elPreviewContainer",this.$element.find(".file-preview"));this.$preview=b(g,"elPreviewImage",this.$element.find(".file-preview-thumbnails"));this.$previewStatus=b(g,"elPreviewStatus",this.$element.find(".file-preview-status"));this.$msgLoading=b(g,"msgLoading","Loading …");this.$msgProgress=b(g,"msgProgress","Loaded {percent}% of {file}");this.$msgSelected=b(g,"msgSelected","{n} files selected");this.$previewFileType=b(g,"previewFileType","image");this.$wrapTextLength=b(g,"wrapTextLength",250);this.$wrapIndicator=b(g,"wrapIndicator",' […]');if(this.$input.length===0){return}this.$name=this.$input.attr("name")||g.name;this.$hidden=this.$element.find('input[type=hidden][name="'+this.$name+'"]');this.$isIE==(window.navigator.appName=="Microsoft Internet Explorer");if(this.$hidden.length===0){this.$hidden=e('');this.$element.prepend(this.$hidden)}this.original={preview:this.$preview.html(),hiddenVal:this.$hidden.val()};this.listen()};d.prototype={constructor:d,listen:function(){this.$input.on("change",e.proxy(this.change,this));e(this.$input[0].form).on("reset",e.proxy(this.reset,this));this.$element.find(".fileinput-remove").on("click",e.proxy(this.clear,this))},trigger:function(g){this.$input.trigger("click");g.preventDefault()},clear:function(h){if(h){h.preventDefault()}this.$hidden.val("");this.$hidden.attr("name",this.name);this.$input.attr("name","");if(this.$isIE){var g=this.$input.clone(true);this.$input.after(g);this.$input.remove();this.$input=g}else{this.$input.val("")}if(h!==false){this.$input.trigger("change");this.$element.trigger("fileclear")}this.$preview.html("");this.$caption.html("");this.$element.removeClass("file-input-new").addClass("file-input-new")},reset:function(g){this.clear(false);this.$hidden.val(this.original.hiddenVal);this.$preview.html(this.original.preview);this.$element.find(".fileinput-filename").text("");this.$element.trigger("filereset")},change:function(w){var x=this.$input,m=x.get(0).files,l=m?m.length:1,o=x.val().replace(/\\/g,"/").replace(/.*\//,""),s=this.$preview,r=this.$previewContainer,t=this.$previewStatus,j=this.$msgLoading,v=this.$msgProgress,k=this.$msgSelected,q,h=this.$previewFileType,p=parseInt(this.$wrapTextLength),g=this.$wrapIndicator;if(w.target.files===undefined){q=w.target&&w.target.value?[{name:w.target.value.replace(/^.+\\/,"")}]:[]}else{q=w.target.files}if(q.length===0){return}s.html("");var y=q.length;for(var u=0;u0&&(h=="any"?(C||B):(h=="text"?B:C))&&typeof FileReader!=="undefined"){var i=new FileReader();t.html(j);r.addClass("loading");i.onload=function(F){var E="";if(B){var D=F.target.result;if(D.length>p){g=g.replace("{title}",D);D=D.substring(0,(p-1))+g}E='
'+D+"
"}else{E='
'+z+'
'}s.append("\n"+E);if(u>=y-1){r.removeClass("loading");t.html("")}};i.onprogress=function(E){if(E.lengthComputable){var D=parseInt(((E.loaded/E.total)*100),10);var F=v.replace("{percent}",D).replace("{file}",A.name);t.html(F)}};if(B){i.readAsText(A)}else{i.readAsDataURL(A)}}else{s.append('\n

'+z+"
")}})(q[u])}var n=l>1?k.replace("{n}",l):o;this.$caption.html(n);this.$element.removeClass("file-input-new");x.trigger("fileselect",[l,o])}};e.fn.fileinput=function(g){return this.each(function(){var i=e(this),h=i.data("fileinput");if(!h){i.data("fileinput",(h=new d(this,g)))}if(typeof g=="string"){h[g]()}})}})(window.jQuery); \ No newline at end of file