angular ui-bootstrap的Datepicker Popup组件问题总结

转自:http://www.cnblogs.com/echo2016/p/5416572.html

http://www.cnblogs.com/pilixiami/p/5611346.html


使用angular框架的时候,之前用的时间控件是引入My97DatePicker组件实现的,但是因为

1.My97DatePicker样式不太好看以及偶尔会出现底部被遮盖的情况、点击不可编辑input框使用backspace按钮会出现格式不符合问题

2.angular-bootstrap 自带兼容第三方ui-date,并且是基于bootstrap改造的

所以决定调研ui-date是否符合产品需求:

条件1.开始时间和结束时间之间有某种关系:开始时间可范围最大值不超过结束时间值,结束时间可选最小值不小于开始时间值

条件2.有选择今天日期按钮

条件3.不能有清除日期按钮

条件4.必须汉化

在引入该文件的时候,angular版本是1.5.0,angular-ui-bootstrap版本是1.1.2,修改代码后为

1 <p class="input-group">
2    input type="text" class="form-control" uib-datepicker-popup readonly ng-model="dicQueryObj.startTime" is-open="startPopupOpened" min-date="minStartDate" max-date="maxStartDate" datepicker-options="dateOptions" ng-required="true" close-text="关闭" current-text="今天"/>
3    span ="input-group-btn"4      button ="button"="btn btn-default" ng-click="startOpen()"><i ="glyphicon glyphicon-calendar"></ibutton5    </span6p>
="dicQueryObj.endTime"="endPopupOpened"="minEndDate"="maxEndDate"="今天" 4 ="endOpen()"
//初始化查询条件
$scope.dicQueryObj = {
fileName: '',
startTime:new Date(CommonServ.getLastMonthDate()),
endTime: new Date(CommonServ.getCurDate()),
order: '0'
};
//时间选择器配置
$scope.minStartDate = 0; //开始时间的最小时间
$scope.maxStartDate = $scope.dicQueryObj.endTime; //开始时间的最大可选时间
$scope.minEndDate = $scope.dicQueryObj.startTime; //结束时间的最小可选时间要大于开始时间的设定值
$scope.maxEndDate = $scope.dicQueryObj.endTime; //结束时间的最大可选择时间不超过结束时间的设定值

$scope.$watch('dicQueryObj.startTime',function(v){
$scope.minEndDate = v;
});
$scope.$watch('dicQueryObj.endTime',function(v){
$scope.maxStartDate = v;
});
$scope.dateOptions = {
formatYear: 'yy',
maxDate: new Date(),
startingDay: 1
};
$scope.startOpen = function() {
$timeout(function() {
$scope.startPopupOpened = true;
});
};
$scope.endOpen = function() {
$timeout(function() {
$scope.endPopupOpened = true;
});
};
$scope.startPopupOpened = false;
$scope.endPopupOpened = false;

然后隐藏清除按钮:

/*ui-date样式*/
2 .uib-button-bar .btn-group button[ng-click^="select(null)"] {
3     display: none;
4 }

效果界面显示如下:

条件1、条件2、条件3都符合,然后被组内小伙伴测出来bug!!!
bug描述:因为设置了日期可选范围,界面确实对范围外的日期呈不可选状态,不可点击,然后顶部前后年份以及月份都可滑动,关键是每次切换月份,月份的1号都会被莫名的自动选中,导致我ng-model绑定的数据变化!!然而居然$watch不出来!!!我就纳闷了?
然后尝试看源码,然而各种看不懂啊。只有类似一句self.activeDate(year,mouth,1),然而各种注释都木有用,各种按照issue上面改代码,然而作者说版本更新已经不适用了。。。我就放弃了,再说改源码毕竟不好啊!
中途各种看issues(https://github.com/angular-ui/bootstrap/issues?utf8=%E2%9C%93)发现人家标为这是bug!!!

http://angular-ui.github.io/bootstrap/#/datepicker无奈研究了一下官网,他并没有出现我遇到的问题,查看他用的版本,发现人用的版本不一样啊!!!

然后重新下载版本bower install angular-bootstrap#1.3.2,引入解决了bug!

到目前为止就剩下条件4汉化了,查了一下issue,结果...

就在快要放弃的时候,大牛说是引入中文文件就OK,毕竟它改造之前是可以支持中文版本的,然后开始各种找,找到了i18n,bower install angular-i18n,下下来发现各种文件

然而查看发现

require('./angular-locale_zh-cn');
module.exports = 'ngLocale';

。。好吧 这个angular2.0的代码


但是ngLocale这个模块貌似就是汉化的重要线索,然后就找到这个了http://stackoverflow.com/questions/19671887/angularjs-angular-ui-bootstrap-changing-language-used-by-the-datepicker
里面提到解决方法,扒下来汉化文件https://github.com/angular/angular.js/blob/master/src/ngLocale/angular-locale_zh.js
然后引进项目中,完全汉化了!效果如下:

注意1:min-date以及max-date设置从html中转义至controller中的options设置

                >
                    ="newWordQueryObj.startTime"="startDateOptions"/>
                  >
                  >
                >

                ="newWordQueryObj.endTime"="endDateOptions" 
 

JS代码修改

1 //初始化查询条件 2 $scope.newWordQueryObj = { 3 fileName: '', 4 startTime: new Date(CommonServ.getLastMonthDate()),128)"> 5 endTime: new Date(CommonServ.getCurDate()),128)"> 6 order: '0' 7 }; 8 9 10 //时间选择器配置 11 //$scope.minStartDate = 0; //开始时间的最小时间 12 //$scope.maxStartDate = $scope.newWordQueryObj.endTime; //开始时间的最大可选时间 13 //$scope.minEndDate = $scope.newWordQueryObj.startTime; //结束时间的最小可选时间要大于开始时间的设定值 14 //$scope.maxEndDate = $scope.newWordQueryObj.endTime; //结束时间的最大可选择时间不超过结束时间的设定值 15 $scope.startDateOptions = { 16 formatYear: 'yy',128)">17 maxDate: $scope.newWordQueryObj.endTime,128)">18 startingDay: 1 19 }; 20 $scope.endDateOptions = { 21 formatYear: 'yy',128)">22 minDate: $scope.newWordQueryObj.startTime,128)">23 maxDate: new Date(),128)">24 startingDay: 1 25 }; 26 27 $scope.$watch('newWordQueryObj.startTime',function(newValue,oldValue){ 28 //$scope.minEndDate = newValue; 29 $scope.endDateOptions.minDate = newValue; 30 }); 31 $scope.$watch('newWordQueryObj.endTime',128)">32 //$scope.maxStartDate = newValue; 33 $scope.startDateOptions.maxDate = newValue; 34 }); 35 $scope.startOpen = function() { 36 $timeout(function() { 37 $scope.startPopupOpened = true; 38 }); 39 }; 40 $scope.endOpen = function() { 41 $timeout(function() { 42 $scope.endPopupOpened = true; 43 }); 44 }; 45 $scope.startPopupOpened = false; 46 $scope.endPopupOpened = false; 47


注意2:这时如果要隐藏clear清除按钮,css
代码得改变
.uib-button-bar .btn-group button[ng-click^="select(null,$event)"] { 完成~

接下来就可以重新测试一下了~

备注:
此时对accordion来说,如果自定义了templateUrl,此时templateUrl内需要添加一个属性uib-accordion-header
1 data-toggle="collapse" aria-expanded="{{isOpen}}" aria-controls="{{::panelId}}" tabindex="0"="accordion-toggle" uib-accordion-transclude="heading"ng-class="{'text-muted': isDisabled}" uib-accordion-header>{{heading}}>

其中最关键是这个:uib-datepicker-popup="{{format}}",uib-datepicker-popup支持多种格式化方式,以2016-6-23 17:35:08这个日期为例,格式化文本和格式化后的值是:

格式化文本 备注
yyyy 2016 4位数年份
yy 16 2位数年份
y 2016 1到4位数年份
MMMM 六月
MMM 6月
MM 06 2位数月份
M 6 1位数月份
M! 06 1位或2位数月份
dd 23 2位数日期
d 23 1位数日期
d! 23 1位数或2位数日期
EEEE 星期四
EEE 周四
HH 17 24小时制 小时
H 17
hh 05 12小时制 小时
h 5
mm 35 分钟
m 35
sss 196 毫秒
ss 08
s 8
a 下午 上午或下午
Z +0800 时区
ww 25 当年的第几周
w 25
G,GG,GGG,GGGG 公元 公元或公元前
fullDate 2016年6月23日星期四
longDate 2016年6月23日
medium 2016年6月23日 下午5:35:08
mediumDate 2016年6月23日
mediumTime 下午5:35:08
short 16/6/23 下午5:35
shortDate 16/6/23
shortTime 下午5:35

uib-datepicker-popup控件可以使用的属性有:

属性 默认值 备注
alt-input-formats [] 手动输入日期时可接受的格式
clear-text clear 清空按钮的文本
close-on-date-selection true 选择一个日期后是否关闭日期面板
close-text close 关闭按钮的文本
current-text today 今天按钮的文本
datepicker-append-to-body false 是否将日期面板放在body元素中
datepicker-options 对Datepicker控件的配置
datepicker-popup-template-url uib/template/datepickerPopup/popup.html
is-open false 是否显示日期面板
on-open-focus true 打开日期面板时是否获取焦点
show-button-bar true 是否在日期面板下方显示”今天”,”关闭”等按钮
type text 可以改为date|datetime-local|month,这样会改变日期面板的日期格式化。
popup-placement auto bottom-left 在位置前加一个auto,表示日期面板会定位在它最近一个可以滚动的父元素中.可以设置的位置有:top top-left top-right bottom bottom-left bottom-right left left-top left-bottom right right-top right-bottom
uib-datepicker-popup yyyy-MM-dd 显示日期的格式。可使用的格式见上面的列表。

对于datepicker-append-to-body属性,值为false时弹出面板的html会紧跟在input元素的后面,值为true时面板html会放在body元素中。如果要对面板的样式做特殊调整时,使用这个属性会比较方便(因为紧跟在input元素后面会继承父元素的样式,放在body元素中可以单独为这个面板设置样式)

对于type属性,个人感觉似乎没有什么用,因为在input元素上使用uib-datepicker-popup="{{format}}"时,改变type的值为date或datetime-local或month实际上是会报错的:“HTML5 date input types do not support custom formats”,在不使用uib-datepicker-popup="{{format}}"时,改变日期面板格式化是使用浏览器实现的HTML5日期格式化功能,相当于不使用uib-datepicker-popup控件,那就没有意义了。

因为uib-datepicker-popup扩展了Datepicker控件,所以uib-datepicker-popup可以使用Datepicker的配置,也就是datepicker-options,这是一个Json对象,可以设置的项有:

默认值 备注
customClass 一个可选的函数,设置日期面板中每个日期的样式。传入参数为一个json对象{date: obj1,mode: obj2},返回值为类的名字
dateDisabled 一个可选的函数,设置日期面板中每个日期是否可选。传入参数为一个json对象{date: obj1,mode: obj2},返回值为bool类型
datepickerMode day 可设置为day,month,year。表示控件的选择模式
formatDay dd 天数的格式化形式
formatMonth MMMM 月份的格式化形式
formatYear yyyy 年份的格式化形式
formatDayHeader EEE 星期的格式化形式
formatDayTitle MMMM yyyy 按天数选择日期时,面板中当前月份和年份的格式化形式(显示为:六月 2016 的地方)
formatMonthTitle yyyy 按月份选择日期时,面板中当前年份的格式化形式
initDate null 初始化日期
maxDate null 可选择的最大日期(必须是Javascript日期类型)
maxMode year 可选择的最大日期模式
minDate null 可选择的最小日期(必须是Javascript日期类型)
minMode day 可选择的最小日期模式
shortcutPropagation false 是否禁用键盘事件传播
showWeeks true 是否显示面板中的日期是当年的第几周
startingDay $locale.DATETIME_FORMATS.FIRSTDAYOFWEEK 一个星期从周几开始。可设置为0到6的数字,0表示周日,6表示周六
yearRows 4 选择年份时显示多少行
yearColumns 5 选择年份时显示多少列

相关文章

AngularJS 是一个JavaScript 框架。它可通过 注:建议把脚本放在 元素的底部。这会提高网页加载速度,因...
angluarjs中页面初始化的时候会出现语法{{}}在页面中问题,也即是页面闪烁问题。出现这个的原因是:由于...
AngularJS 通过被称为指令的新属性来扩展 HTML。AngularJS 指令AngularJS 指令是扩展的 HTML 属性,带有...
AngularJS 使用表达式把数据绑定到 HTML。AngularJS 表达式AngularJS 表达式写在双大括号内:{{ expres...
ng-repeat 指令可以完美的显示表格。在表格中显示数据 {{ x.Name }} {{ x.Country }} 使用 CSS 样式为了...
$http是 AngularJS 中的一个核心服务,用于读取远程服务器的数据。读取 JSON 文件下是存储在web服务器上...