`
xinklabi
  • 浏览: 1562218 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
文章分类
社区版块
存档分类
最新评论

Modal,Popover,Tooltip,Typeahead,DatePicker,TimePicker,Jquery fileupload用法

 
阅读更多

1. Modal

$modal是一个可以迅速创建模态窗口的服务,创建部分页,控制器,并关联他们

$modal仅有一个方法open(options)

  • templateUrl:模态窗口的地址
  • template:用于显示html标签
  • scope:一个作用域为模态的内容使用(事实上,$modal会创建一个当前作用域的子作用域)默认为$rootScope
  • controller:为$modal指定的控制器,初始化$scope,该控制器可用$modalInstance注入
  • resolve:定义一个成员并将他传递给$modal指定的控制器,相当于routes的一个reslove属性,如果需要传递一个objec对象,需要使用angular.copy()
  • backdrop:控制背景,允许的值:true(默认),false(无背景),static - 背景是存在的,但点击模态窗口之外时,模态窗口不关闭
  • keyboard:当按下Esc时,模态对话框是否关闭,默认为ture
  • windowClass:指定一个class并被添加到模态窗口中

open方法返回一个模态实例,该实例有如下属性

  • close(result):关闭模态窗口并传递一个结果
  • dismiss(reason):撤销模态方法并传递一个原因
  • result:一个契约,当模态窗口被关闭或撤销时传递
  • opened:一个契约,当模态窗口打开并且加载完内容时传递的变量

另外,$modalInstance扩展了两个方法$close(result)$dismiss(reason),这些方法很容易关闭窗口并且不需要额外的控制器

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <!DOCTYPE html>  
  2. <html ng-app="ModalDemo">  
  3. <head>  
  4.     <title></title>  
  5.     <link href="lib/bootstrap/css/bootstrap.min.css" rel="stylesheet">  
  6.     <script src="lib/angular/angular.min.js"></script>  
  7.     <script src="lib/bootstrap-gh-pages/ui-bootstrap-tpls-0.7.0.min.js"></script>  
  8.     <script src="lib/angular/i18n/angular-locale_zh-cn.js"></script>  
  9. </head>  
  10. <body>  
  11. <div ng-controller="ModalDemoCtrl">  
  12.     <script type="text/ng-template" id="myModalContent.html">  
  13.         <div class="modal-header">  
  14.             <h3>I'm a modal!</h3>  
  15.         </div>  
  16.         <div class="modal-body">  
  17.             <ul>  
  18.                 <li ng-repeat="item in items">  
  19.                     <a ng-click="selected.item = item">{{ item }}</a>  
  20.                 </li>  
  21.             </ul>  
  22.             Selected: <b>{{ selected.item }}</b>  
  23.         </div>  
  24.         <div class="modal-footer">  
  25.             <button class="btn btn-primary" ng-click="ok()">OK</button>  
  26.             <button class="btn btn-warning" ng-click="cancel()">Cancel</button>  
  27.         </div>  
  28.     </script>  
  29.     <button class="btn" ng-click="open()">Open me!</button>  
  30. </div>  
  31. <script>  
  32.     var ModalDemo = angular.module('ModalDemo', ['ui.bootstrap']);  
  33.     var ModalDemoCtrl = function ($scope, $modal, $log) {  
  34.         $scope.items = ['item1', 'item2', 'item3'];  
  35.         $scope.open = function () {  
  36.             var modalInstance = $modal.open({  
  37.                 templateUrl: 'myModalContent.html',  
  38.                 controller: ModalInstanceCtrl,  
  39.                 resolve: {  
  40.                     items: function () {  
  41.                         return $scope.items;  
  42.                     }  
  43.                 }  
  44.             });  
  45.             modalInstance.opened.then(function(){//模态窗口打开之后执行的函数  
  46.                 console.log('modal is opened');  
  47.             });  
  48.             modalInstance.result.then(function (result) {  
  49.                  console.log(result);  
  50.             }, function (reason) {  
  51.                 console.log(reason);//点击空白区域,总会输出backdrop click,点击取消,则会暑促cancel  
  52.                 $log.info('Modal dismissed at: ' + new Date());  
  53.             });  
  54.         };  
  55.     };  
  56.     var ModalInstanceCtrl = function ($scope, $modalInstance, items) {  
  57.         $scope.items = items;  
  58.         $scope.selected = {  
  59.             item: $scope.items[0]  
  60.         };  
  61.         $scope.ok = function () {  
  62.             $modalInstance.close($scope.selected);  
  63.         };  
  64.         $scope.cancel = function () {  
  65.             $modalInstance.dismiss('cancel');  
  66.         };  
  67.     };  
  68. </script>  
  69. </body>  
  70. </html>  

Popover

  • popover-title:显示的标题
  • popover-placement:默认为top,其他为"bottom", "left", "right"
  • popover-animation:是否有fade in和fade out的动画效果,默认为true
  • popover-popup-delay:鼠标放置多少毫秒之后才会显示内容,默认为0
  • popover-trigger:何种方式触发提示,mouseenter,focus,详见tooltip
  • popover-append-to-body:是否追加至$body

 

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <!DOCTYPE html>  
  2. <html ng-app="Demo">  
  3. <head>  
  4.     <title></title>  
  5.     <link href="lib/bootstrap/css/bootstrap.min.css" rel="stylesheet">  
  6.     <script src="lib/angular/angular.min.js"></script>  
  7.     <script src="lib/jquery/jquery-1.10.2.min.js"></script>  
  8.     <script src="lib/bootstrap-gh-pages/ui-bootstrap-tpls-0.7.0.min.js"></script>  
  9.     <script src="lib/angular/i18n/angular-locale_zh-cn.js"></script>  
  10. </head>  
  11. <body>  
  12. <div ng-controller="PopoverDemoCtrl">  
  13.     <div class="well">  
  14.         <div>  
  15.             <h4>Dynamic</h4>  
  16.             <div>Dynamic Popover : <input type="text" ng-model="dynamicPopoverText"></div>  
  17.             <div>Dynamic Popover Popup Text: <input type="text" ng-model="dynamicPopover"></div>  
  18.             <div>Dynamic Popover Popup Title: <input type="text" ng-model="dynamicPopoverTitle"></div>  
  19.             <div><button popover="{{dynamicPopover}}" popover-title="{{dynamicPopoverTitle}}" class="btn">{{dynamicPopoverText}}</button></div>  
  20.         </div>  
  21.         <div>  
  22.             <h4>Positional</h4>  
  23.             <button popover-placement="top" popover="On the Top!" class="btn">Top</button>  
  24.             <button popover-placement="left" popover="On the Left!" class="btn">Left</button>  
  25.             <button popover-placement="right" popover="On the Right!" class="btn">Right</button>  
  26.             <button popover-placement="bottom" popover="On the Bottom!" class="btn">Bottom</button>  
  27.         </div>  
  28.         <div>  
  29.             <h4>Triggers</h4>  
  30.             <button popover="I appeared on mouse enter!" popover-trigger="mouseenter" class="btn">Mouseenter</button>  
  31.             <input type="text" value="Click me!"  
  32.                    popover="I appeared on focus! Click away and I'll vanish..."  
  33.                    popover-trigger="focus" />  
  34.         </div>  
  35.         <div>  
  36.             <h4>Other</h4>  
  37.             <button Popover-animation="true" popover="I fade in and out!" class="btn">fading</button>  
  38.             <button popover="I have a title!" popover-title="The title." class="btn">title</button>  
  39.         </div>  
  40.     </div>  
  41. </div>  
  42. <script>  
  43.     var Demo = angular.module('Demo', ['ui.bootstrap']);  
  44.     var PopoverDemoCtrl = function ($scope) {  
  45.         $scope.dynamicPopover = "Hello, World!";  
  46.         $scope.dynamicPopoverText = "dynamic";  
  47.         $scope.dynamicPopoverTitle = "Title";  
  48.     };  
  49. </script>  
  50. </body>  
  51. </html>  



Tooltip

 

两个版本:tooltiptooltip-html-unsafe

  • tooltip-placement
  • tooltip-animation
  • tooltip-popup-delay
  • tooltip-triggermouseentermouseleaveclickfocusblur
  • tooltip-append-to-body

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <!DOCTYPE html>  
  2. <html ng-app="Demo">  
  3. <head>  
  4.     <title></title>  
  5.     <link href="lib/bootstrap/css/bootstrap.css" rel="stylesheet">  
  6.     <script src="lib/angular/angular.min.js"></script>  
  7.     <script src="lib/jquery/jquery-1.10.2.min.js"></script>  
  8.     <script src="lib/bootstrap-gh-pages/ui-bootstrap-tpls-0.7.0.min.js"></script>  
  9.     <script src="lib/angular/i18n/angular-locale_zh-cn.js"></script>  
  10. </head>  
  11. <body>  
  12. <div ng-controller="TooltipDemoCtrl">  
  13.     <div class="well">  
  14.         <div>Dynamic Tooltip Text: <input type="text" ng-model="dynamicTooltipText"></div>  
  15.         <div>Dynamic Tooltip Popup Text: <input type="text" ng-model="dynamicTooltip"></div>  
  16.         <p>  
  17.             Pellentesque <a><span tooltip="{{dynamicTooltip}}">{{dynamicTooltipText}}</span></a>,  
  18.             sit amet venenatis urna cursus eget nunc scelerisque viverra mauris, in  
  19.             aliquam. Tincidunt lobortis feugiat vivamus at  
  20.             <a><span tooltip-placement="left" tooltip="On the Left!">left</span></a> eget  
  21.             arcu dictum varius duis at consectetur lorem. Vitae elementum curabitur  
  22.             <a><span tooltip-placement="right" tooltip="On the Right!">right</span></a>  
  23.             nunc sed velit dignissim sodales ut eu sem integer vitae. Turpis egestas  
  24.             <a><span tooltip-placement="bottom" tooltip="On the Bottom!">bottom</span></a>  
  25.             pharetra convallis posuere morbi leo urna,  
  26.             <a><span tooltip-animation="false" tooltip="I don't fade. :-(">fading</span></a>  
  27.             at elementum eu, facilisis sed odio morbi quis commodo odio. In cursus  
  28.             <a><span tooltip-popup-delay='1000' tooltip='appears with delay'>delayed</span></a> turpis massa tincidunt  
  29.             dui ut.  
  30.         </p>  
  31.         <p>  
  32.             I can even contain HTML. <a><span tooltip-html-unsafe="{{htmlTooltip}}">Check me out!</span></a>  
  33.         </p>  
  34.         <p>  
  35.             Or use custom triggers, like focus:  
  36.             <input type="text" value="Click me!"  
  37.                    tooltip="See? Now click away..."  
  38.                    tooltip-trigger="mouseleave"  
  39.                    tooltip-placement="right"/>  
  40.         </p>  
  41.         <form name="myForm" >  
  42.             <div>  
  43.                 here  
  44.                 <input  
  45.                         class="span2"  
  46.                         name="input1id"  
  47.                         type="text"  
  48.                         ng-model="input1"  
  49.                         required  
  50.                         tooltip="See? Now click away..."  
  51.                         tooltip-placement="bottom"  
  52.                         tooltip-trigger="{{{true: 'mouseenter', false: 'never'}[myForm.input1id.$invalid]}}"  
  53.                         />  
  54.             </div>  
  55.             <pre>myForm.input1id.$invalid: {{myForm.input1id.$invalid}}</pre>  
  56.     </div>  
  57. </div>  
  58. <script>  
  59.     var Demo = angular.module('Demo', ['ui.bootstrap']);  
  60.     Demo.config(['$tooltipProvider', function ($tooltipProvider) {  
  61.         $tooltipProvider.options({  
  62.             placement: 'right',  
  63.             animation: true,  
  64.             popupDelay: 0,  
  65.             appendToBody: false  
  66.         });  
  67.     }]);  
  68.     var TooltipDemoCtrl = function ($scope) {  
  69.         $scope.dynamicTooltip = "Hello, World!";  
  70.         $scope.dynamicTooltipText = "dynamic";  
  71.         $scope.htmlTooltip = "I've been made <h6>bold</h6>!";  
  72.     };  
  73. </script>  
  74. </body>  
  75. </html>  

 

Typeahead

  • $viewValue:用户输入的值
  • ng-model:对应的模型绑定
  • typeahead:对应的表达式,类似于select
  • typeahead-editable:是否允许不从提示中选择,默认为ture,设置为false时,如果不是从提示中选择,该input的验证为false
  • typeahead-input-formatter:选中之后格式化显示
  • typeahead-loading:指定一个模型,当查询时,该模型为ture
  • typeahead-min-length:输入最少数量的字符时出现提示
  • typeahead-on-select:选择选项时的回调函数,默认为空
  • typeahead-template-url:自定义内容的url
  • typeahead-wait-ms:键入最后一个字符时的等待时间,默认为0

 

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <!DOCTYPE html>  
  2. <html ng-app="Demo">  
  3. <head>  
  4.     <title></title>  
  5.     <link href="lib/bootstrap/css/bootstrap.css" rel="stylesheet">  
  6.     <script src="lib/angular/angular.min.js"></script>  
  7.     <script src="lib/jquery/jquery-1.10.2.min.js"></script>  
  8.     <script src="lib/bootstrap-gh-pages/ui-bootstrap-tpls-0.7.0.min.js"></script>  
  9.     <script src="lib/angular/i18n/angular-locale_zh-cn.js"></script>  
  10. </head>  
  11. <body>  
  12. <div class='container-fluid' ng-controller="TypeaheadCtrl">  
  13.     <pre>Model: {{selected | json}}</pre>  
  14.     <form name="myForm">  
  15.         <input type="text" ng-model="selected" name="selected"  
  16.                typeahead="state.id as state.name for state in states | filter:{ name : $viewValue }"  
  17.                typeahead-editable="false"  
  18.                typeahead-input-formatter="formatInput($model)">  
  19.         <input type="text" ng-model="search"  
  20.                typeahead="result for result in lookup($viewValue)"  
  21.                typeahead-loading="isLoading" />  
  22.     </form>  
  23.     {{myForm.selected.$valid}}  
  24. </div>  
  25.   
  26. <script>  
  27.     var Demo = angular.module('Demo', ['ui.bootstrap']);  
  28.     function TypeaheadCtrl($scope,$filter) {  
  29.         $scope.selected=3;  
  30.         $scope.states = [  
  31.             {id:1,name:"Alabama"},  
  32.             {id:2,name:"Montana"},  
  33.             {id:3,name:"Arkansas"}  
  34.         ];  
  35.         $scope.formatInput = function($model) {  
  36.             return $filter('filter')($scope.states,{id:$model})[0].name;  
  37.         }  
  38.         $scope.lookup = function() {  
  39.             console.log("isLoading is " + $scope.isLoading);  
  40.             return [];  
  41.         }  
  42.     }  
  43. </script>  
  44. </body>  
  45. </html>  

Datepicker Settings

  • show-weeks:是否显示每月的第几周,默认为ture
  • starting-day:日历显示的时间的第一个日期,默认为0,(0=Sunday, ..., 6=Saturday)
  • min:定义最小的显示时间,默认为空
  • max:定义最大的显示时间,默认为空
  • date-disabled (date, mode) (Default: null) : An optional expression to disable visible options based on passing date and current mode(day|month|year).
  • day-format:日期的格式,即每月的中的当前日期,默认dd
  • month-format:默认为MMMM
  • year-format:默认为yyyy
  • year-range:时间的选择范围,默认为20
  • day-header-format(Default: 'EEE') : Format of day in week header.
  • day-title-format(Default: 'MMMM yyyy') : Format of title when selecting day.
  • month-title-format(Default: 'yyyy') : Format of title when selecting month.

 

Popup Settings

 

通过datepicker-options来设置,格式为json

弹出的具体设置如下:

  • datepicker-popup:显示日期的格式,默认为yyyy-MM-dd
  • current-text :选择当天的按钮的显示文本,默认为Today
  • toggle-weeks-text:默认为Weeks
  • clear-text:默认为Clear
  • close-text:默认为Done
  • close-on-date-selection:默认为true,选择日期后是否关闭
  • datepicker-append-to-body

注:如果需要中文,可以引入i18n/angular-locale_zh-cn.js

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <!DOCTYPE html>  
  2. <html ng-app="Demo">  
  3. <head>  
  4.     <title></title>  
  5.     <link href="lib/bootstrap/css/bootstrap.min.css" rel="stylesheet">  
  6.     <script src="lib/angular/angular.min.js"></script>  
  7.     <script src="lib/jquery/jquery-1.10.2.min.js"></script>  
  8.     <script src="lib/bootstrap-gh-pages/ui-bootstrap-tpls-0.7.0.min.js"></script>  
  9.     <script src="lib/angular/i18n/angular-locale_zh-cn.js"></script>  
  10. </head>  
  11. <body>  
  12. <div ng-controller="DatepickerDemoCtrl">  
  13.     <pre>Selected date is: <em>{{dt | date:'fullDate' }}</em></pre>  
  14.   
  15.     <h4>Inline</h4>  
  16.     <div class="well well-small" ng-model="dt" style="display:inline-block;">  
  17.         <datepicker min="minDate" show-weeks="showWeeks"></datepicker>  
  18.     </div>  
  19.   
  20.     <h4>Popup</h4>  
  21.     <div class="form-horizontal">  
  22.         <p>  
  23.             <input type="text" datepicker-popup="{{format}}" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />  
  24.             <button class="btn" ng-click="open()"><i class="icon-calendar"></i></button>  
  25.         </p>  
  26.         <p><i>Format options:</i> <select ng-model="format" ng-options="f for f in formats"><option></option></select></p>  
  27.     </div>  
  28.   
  29.     <hr />  
  30.     <button class="btn btn-small btn-inverse" ng-click="today()">Today</button>  
  31.     <button class="btn btn-small btn-inverse" ng-click="dt = '2009-08-24'">2009-08-24</button>  
  32.     <button class="btn btn-small btn-success" ng-click="toggleWeeks()" tooltip="For inline datepicker">Toggle Weeks</button>  
  33.     <button class="btn btn-small btn-danger" ng-click="clear()">Clear</button>  
  34.     <button class="btn btn-small" ng-click="toggleMin()" tooltip="After today restriction">Min date</button>  
  35. </div>  
  36. <script>  
  37.     var Demo = angular.module('Demo', ['ui.bootstrap']);  
  38.     var DatepickerDemoCtrl = function ($scope, $timeout) {  
  39.         $scope.today = function() {  
  40.             $scope.dt = new Date();  
  41.         };  
  42.         $scope.today();  
  43.         $scope.showWeeks = true;  
  44.         $scope.toggleWeeks = function () {  
  45.             $scope.showWeeks = ! $scope.showWeeks;  
  46.         };  
  47.         $scope.clear = function () {  
  48.             $scope.dt = null;  
  49.         };  
  50.         // Disable weekend selection  
  51.         $scope.disabled = function(date, mode) {  
  52.             return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );  
  53.         };  
  54.         $scope.toggleMin = function() {  
  55.             $scope.minDate = ( $scope.minDate ) ? null : new Date();  
  56.         };  
  57.         $scope.toggleMin();  
  58.         $scope.open = function() {  
  59.             $timeout(function() {  
  60.                 $scope.opened = true;  
  61.             });  
  62.         };  
  63.         $scope.dateOptions = {  
  64.             'year-format': "'yy'",  
  65.             'starting-day': 1  
  66.         };  
  67.         $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'shortDate'];  
  68.         $scope.format = $scope.formats[0];  
  69.     };  
  70. </script>  
  71. </body>  
  72. </html>  

 

 

Timepicker

 

  • hour-step:时间变化的步长,默认为1
  • minute-step:分钟变化的步长,默认为1
  • show-meridian:是否显示am、pm切换,默认为true
  • meridians :切换am、pm的文本,默认为['AM','PM']
  • readonly-input:是否允许用户输入,默认为false
  • mousewheel:当输入框获得焦点时,是否允许用户用滚滑轮变化数值大小,默认为ture

 

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <!DOCTYPE html>  
  2. <html ng-app="Demo">  
  3. <head>  
  4.     <title></title>  
  5.     <link href="lib/bootstrap/css/bootstrap.min.css" rel="stylesheet">  
  6.     <script src="lib/angular/angular.min.js"></script>  
  7.     <script src="lib/jquery/jquery-1.10.2.min.js"></script>  
  8.     <script src="lib/bootstrap-gh-pages/ui-bootstrap-tpls-0.7.0.min.js"></script>  
  9.     <script src="lib/angular/i18n/angular-locale_zh-cn.js"></script>  
  10. </head>  
  11. <body>  
  12. <div ng-controller="TimepickerDemoCtrl">  
  13.     <div ng-model="mytime" ng-change="changed()" class="well well-small" style="display:inline-block;">  
  14.         <timepicker hour-step="hstep" minute-step="mstep" show-meridian="ismeridian"></timepicker>  
  15.     </div>  
  16.   
  17.     <pre>Time is: {{mytime | date:'shortTime' }}</pre>  
  18.   
  19.     <div>Hours step is: <select ng-model="hstep" ng-options="opt for opt in options.hstep"></select></div>  
  20.     <div>Minutes step is: <select ng-model="mstep" ng-options="opt for opt in options.mstep"></select></div>  
  21.   
  22.     <button class="btn" ng-click="toggleMode()">12H / 24H</button>  
  23.     <button class="btn" ng-click="update()">Set to 14:00</button>  
  24.     <button class="btn btn-danger" ng-click="clear()">Clear</button>  
  25. </div>  
  26. <script>  
  27.     var Demo = angular.module('Demo', ['ui.bootstrap']);  
  28.     var TimepickerDemoCtrl = function ($scope) {  
  29.         $scope.mytime = new Date();  
  30.         $scope.hstep = 1;  
  31.         $scope.mstep = 15;  
  32.         $scope.options = {  
  33.             hstep: [1, 2, 3],  
  34.             mstep: [1, 5, 10, 15, 25, 30]  
  35.         };  
  36.         $scope.ismeridian = true;  
  37.         $scope.toggleMode = function() {  
  38.             $scope.ismeridian = ! $scope.ismeridian;  
  39.         };  
  40.         $scope.update = function() {  
  41.             var d = new Date();  
  42.             d.setHours( 14 );  
  43.             d.setMinutes( 0 );  
  44.             $scope.mytime = d;  
  45.         };  
  46.         $scope.changed = function () {  
  47.             console.log('Time changed to: ' + $scope.mytime);  
  48.         };  
  49.         $scope.clear = function() {  
  50.             $scope.mytime = null;  
  51.         };  
  52.     };  
  53. </script>  
  54. </body>  
  55. </html>  

jQuery File Upload的最简模型

jQuery File Upload包含了一堆文件,首先需要弄清楚的是最核心的部分是哪些,根据官方的例子可以知道,一个最简单的jQuery File Upload上传组件,必须包括以下文件:

  • jQuery核心库,建议使用jQuery 1.8以上版本
  • js/vendor/jquery.ui.widget.js : jQuery UI Widget
  • js/jquery.iframe-transport.js : 扩展iframe数据传输
  • js/jquery.fileupload.js : jQuery File Upload核心类
  • js/cors/jquery.xdr-transport.js 在IE下应载入此文件解决跨域问题

此时只需要加载一个上传按钮

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <input id="fileupload" type="file" name="files[]" data-url="server/php/" multiple>  


以及一行代码

 

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. $('#fileupload').fileupload();  

 

 

就完成了一个最基本的上传组件。这个最简单的上传组件可以将选中的文件以表单形式提交到data-url约定的URL,同时提供了足够多的设置和基础事件可供扩展。

jQuery File Upload的简单扩展

对于最简模型,稍加扩展就可以实现一些比较常用的功能,比如可以在上传完毕后可以显示一个简单的结果:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. $('#fileupload').fileupload({  
  2.     done: function (e, data) {  
  3.         $.each(data.result, function (index, file) {  
  4.             $('<p/>').text(file.name + ' uploaded').appendTo($("body"));  
  5.         });  
  6.     }  
  7. });  


或者显示上传进度,配合一些进度条组件就可以构成一个上传进度条

 

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. $('#fileupload').fileupload('option', {  
  2.     progressall: function (e, data) {  
  3.         var progress = parseInt(data.loaded / data.total * 100, 10);  
  4.         console.log(progress + '%');  
  5.     }  
  6. });  

 

 

等等。只要多阅读手册就可以配合项目做更具体的扩展开发。

XHR响应为Json时IE的下载BUG

这里需要特别注意的是,由于jQuery File Upload都是采用XHR在传递数据,服务器端返回的通常是JSON格式的响应,但是IE会将这些JSON响应误认为是文件传输,然后直接弹出下载框询问是否需要下载。

解决这个问题的方法是必须将相应的Http Head从

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. Content-Type: application/json  


更改为

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. Content-Type: text/plain  


具体的实现根据服务端不同有所区别,比如ZF2中可以在Controller中这样写:

 

 

[php] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. $this->getServiceLocator()->get('Application')->getEventManager()->attach(\Zend\Mvc\MvcEvent::EVENT_RENDER, function($event){  
  2.     $event->getResponse()->getHeaders()->addHeaderLine('Content-Type''text/plain');  
  3. }, -10000);  

 

 

这也是我在stackoverflow上的对ZF2更改最终响应类型的一个回答

jQuery File Upload UI的构成与说明

为了引入更多功能,jQuery File Upload在上面最简模型的基础上又实现了一套jQuery File Upload UI,也就是官方给出的最终Demo,这套UI额外提供了以下功能:

  • 最大/最小文件限定 Options.maxFileSize / Options.mixFileSize
  • 文件类型限定,通过正则表达式检测文件名实现 Options.acceptFileTypes
  • 选择文件后自动上传 Options.autoUpload
  • 上传文件数量限制,通过上传后将选择文件按钮置为Disabled实现 Options.maxNumberOfFiles
  • 上传模板,就是选择文件后显示预览的html代码 Options.uploadTemplate
  • 下载模板,当文件上传完毕后显示的html代码 Options.downloadTemplate

等等,同时还增加了一系列新的接口和事件,具体都可以查阅官方手册。

具体对应到文件为:

  • JavaScript-Templates : JS模板引擎
  • JavaScript-Load-Image : 图片预览功能
  • js/jquery.fileupload-ui.js & css/jquery.fileupload-ui.css : UI核心类,CSS可以替换旧式的上传控件为统一的按钮
  • js/jquery.fileupload-fp.js:进度条扩展功能

也许正是因为附加功能太多,各功能之间耦合非常重,jQuery File Upload UI显得不够友好,主要体现在:

  • 上述功能均无法拆分,必须统一全部加载
  • 各功能需要界面存在相应元素,如果缺少某些元素,包括JS模板内的元素,整个UI无法正常工作
  • JS模板引擎对标签配对非常严格,标签如果遗漏也有可能引起UI无法正常工作

所以经验之谈是,在定制jQuery File Upload UI时,如果UI无法工作。首先检查js文件是否全部加载,然后检查页面元素是否齐全,再次检查JS模板标签是否严格配对,最后还可以查看页面是否有重复调用fileupload()方法。

jQuery File Upload UI构成元素

UI的部件都是硬编码的HTML class,无法更改。核心的几个部件为

全局控制按钮 (必须)

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <div class="fileupload-buttonbar">  
  2.         <span class="fileinput-button"><input type="file" name="files[]" multiple></span>  
  3.         <button type="submit" class="start">Start upload</button>  
  4.         <button type="reset" class="cancel">Cancel upload</button>  
  5.         <button type="button" class="delete">Delete</button>  
  6.         <input type="checkbox" class="toggle">  
  7. </div>  


最外层容器为.fileupload-buttonbar,内部包含

  • 文件选择按钮 .fileinput-button (必须),内部必须包裹一个input:file
  • 开始上传按钮 .start
  • 取消上传按钮 .cancel
  • 删除按钮 .delete
  • 文件勾选按钮 .toggle

整体上传进度 (可选)

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <div class="fileupload-progress">  
  2.     <div class="progress">  
  3.         <div class="bar" style="width:0%;"></div>  
  4.     </div>  
  5.     <div class="progress-extended"></div>  
  6. </div>  

最外层容器为.fileupload-progress,内部包含

 

  • 上传进度条容器.progress
  • 上传进度条 .bar
  • 上传进度文本 .progress-extended

文件显示容器 (必须)

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <div class="files"></div>  


.file容器是最重要的UI部件,上传时的文件预览模板以及上传完毕后的文件显示模板都将显示在这里。

文件预览模板 (必须)

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <script id="template-upload" type="text/x-tmpl">  
  2. {% for (var i=0, file; file=o.files[i]; i++) { %}  
  3. <div class="template-upload">  
  4.     {% if (file.error) { %}  
  5.         <div class="error">{%=file.error%}</div>  
  6.     {% } else { %}  
  7.     <div class="preview"><span class="fade"></span></div>  
  8.     <div class="name"><span>{%=file.name%}</span></div>  
  9.     <div class="size"><span>{%=o.formatFileSize(file.size)%}</span></div>  
  10.     <div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" style="height:5px;"><div class="bar" style="width:0%;"></div></div>  
  11.     <span class="start">  
  12.         {% if (!o.options.autoUpload) { %}  
  13.             <button>Start Upload</button>  
  14.         {% } %}  
  15.     </span>  
  16.     {% } %}  
  17.     <span class="cancel"><button>Cancel</button></span>  
  18. </div>  
  19. {% } %}  
  20. </script>  


这部分逻辑不难读懂,由于文件选择是多选的,所以被选择文件一开始以数组方式存放,循环输出。即使我们加入最大文件只能上传一个,这里得到的仍然是数组形式。

当文件有任何错误时,如文件类型被禁止,文件大小不符合约定,会得到file.error。文件检测没有问题,则可以用以下元素控制当前文件:

  • 开始上传当前文件按钮.start (必须)
  • 取消上传当前文件按钮.cancel (可选)
  • 当前文件上传进度.progress (可选)

上传后文件回调显示模板 (必须)

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <script id="template-download" type="text/x-tmpl">  
  2. {% for (var i=0, file; file=o.files[i]; i++) { %}  
  3. <div class="template-download">  
  4.     {% if (file.error) { %}  
  5.         <div class="error">{%=file.error%}</div>  
  6.         <span class="cancel"><button class="btn btn-block"><i class="icon-ban-circle"></i>Cancel</span>  
  7.     {% } else { %}  
  8.     <div class="preview"><img src="{%=file.thumbnail_url%}"></div>  
  9.     <div class="name"><span>{%=file.name%}</span></div>  
  10.     <div class="size"><span>{%=o.formatFileSize(file.size)%}</span></div>  
  11.     <div class="delete"><button data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">Delete</button>  
  12.     </div>  
  13.     {% } %}  
  14. </div>  
  15. {% } %}  
  16. </script>  

这一部分的o.files完全来自服务器端的json响应,所以模板内容可以自由发挥。唯一被定制的元素为删除按钮.delete。 点击这个按钮会向按钮中指定的url发送请求,比如

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <div class="delete"><button data-type="DELETE" data-url="/file/1">Delete</button></div>  

点击后则会用DELETE方式发送HTTP请求

 

 

DELETE /file/1

jQuery File Upload UI工作流程

 

有了上面罗列的UI元素,就可以拼凑出一个简单的jQuery File Upload UI工作流程:

  1. 用户点击.fileinput-button选择要上传的文件(多个)
  2. 文件选择后,文件信息被整理为数组置入文件预览模板#template-upload
  3. 模板引擎循环处理文件信息并生成模板.template-upload
  4. 每生成一个模板,模板就被插入到文件显示容器.files的最后。
  5. 用户点击上传按钮.start上传,文件信息被转换为XHR请求至服务器端
  6. UI获得服务器端生成JSON响应文件
  7. JSON响应信息也被整理成数组置入回调显示模板#template-download
  8. 模板引擎循环处理文件信息并生成模板.template-download
  9. 每生成一个模板,会将此模板替换对应的.template-upload部分

定制过程

有了上面的基础,要个性化的定制jQuery File Upload就简单了很多:

限制文件类型

由于没有使用Flash空间,上传的文件选择框是无法限制文件类型的,所以所谓的限制文件类型,只能让用户选择文件之后,用file.error显示一个错误信息。例如本次需要限定可上传的文件为图片,那么Options指定:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. acceptFileTypes:  /(\.|\/)(gif|jpe?g|png)$/i  


即可。

在Google Chrome浏览器中,可以用input:file原生支持文件类型限定,可以配合使用:

<input type="file" name="upload[]"  accept="image/png, image/gif, image/jpg, image/jpeg">

不过在客户端做再多的限定也只是提升用户体验,不能真正保证安全性,所以不要忘记了在服务器端做同样的类型检测。

文件数量限制

只需在Options指定

maxNumberOfFiles : 1

即可。jQuery File Upload UI的处理方式是当用户上传一个文件后,文件选择按钮被置为Disabled。

这同样只是客户端的小把戏,真正想要严格的约束用户只能上传一个文件还是需要在服务器端通过Session做更加复杂的控制。

文件大小限制

Options中指定

maxFileSize: 5000000

即只允许单文件最大5MB。

Firefox disable bug

在Firefox环境下测试是,发现如果将文件数量限制为1,选择一次文件,刷新页面之后文件选择按钮会莫名其妙的被加上一个Disabled属性,导致无法点击。所以最终我们的初始化代码为:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. var uploader = $("#fileupload");  
  2. uploader.fileupload({  
  3.     dataType: 'json',  
  4.     autoUpload: false,  
  5.     acceptFileTypes:  /(\.|\/)(gif|jpe?g|png)$/i,  
  6.     maxNumberOfFiles : 1,  
  7.     maxFileSize: 5000000   
  8. });  
  9. uploader.find("input:file").removeAttr('disabled');  


最后就是界面的一些调整,完整代码在EvaEngine的File模块下,点击查看.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics