SAP UI5应用DatePicker控件的设计明细
Recently in order to resolve customer incidents, I need to study more details about DatePicker control. I share what I have learned in this blog.
What does DatePicker look like
There is a small window icon, by clicking it, you can choose any date from popped up calendar.
How to define DatePicker in xml view
<caui:DatePicker id="td"
value="{path: 'vm>/ToDate', type:'sap.ui.model.type.Date', formatOptions: { style: 'long'}}"
change="onToDateChanged"></caui:DatePicker>
– namespace for caui: xmlns:caui=”sap.ca.ui” – onToDateChanged is event handler defined in application ( consumer ). The event name is: “change”.
Implementation of DatePicker.js
You can find source code via the path: sap/ca/ui/DatePicker.js.
By reading the source code, here are some keynotes:
(1) The DatePicker is a composite control, which holds a calendar control internally. This could be known by line 38 ( reference this._oCalendar points to the internal calendar control ).
(2) The DatePicker has sap.m.InputBase as its prototype ( line 34 ). (3) The DatePicker has two properties defined in metadata. To be exactly, there are three. The third is “Value” which comes from the prototype “sap.m.InputBase”.
properties: {
"firstDayOffset": {
type: "int",
group: "Data",
defaultValue: 0
},
"dateValue": {
type: "string",
group: "Misc",
defaultValue: null
}
}
(4) Whenever there is selection change in DatePicker, it will call fireChange and finally event “change” is issued. This is reason why you have to bind your event listener to “change” event in xml view. You can also find that two values ( newValue, newYyyymmdd) are passed to event listener as parameters. We will debug it later.
sap.ca.ui.DatePicker.prototype.fireChange = function(u) {
if (!this._dateType) {
this._setUpDateType();
}
var c = this.getValue();
var t = this._validateDate(c);
if (u || u === undefined) {
this.dateObj = t;
}
this.setDateValue(t);
var d = null ;
if (t) {
d = this._toDateStringYYYYMMDD(t);
}
this.fireEvent("change", {
newValue: c,
newYyyymmdd: d,
invalidValue: t ? false : true
});
return this;
}
Implementation of Calendar.js
Do Element inspection via Chrome development tool, for example inspect the UI area for Oct-16, you can find the area actually consists of a span node with value 16 and another hidden input with content “Fri Oct 16 2015”.
Scroll down and you can find more divs which represent the corresponding date in UI.
When and where are these divs generated?
(1) In the init function of DatePicker, it fetches the prefix for each day which is used to render the content of hidden input element as introduced before.
The same logic for month abbreviation name:
(2) When you click the small icon of DatePicker, the calendar is to be rendered. Thus the render function of CalendarRender.js is called. Here below is the logic to populate span node and hidden input node.
event design in Calendar.js
Source code of Calendar.js could be found here. There is event tapOnDate defined in its metadata, with one parameter “date”.
Event delegation in the runtime
(1) When a given date is selected by end user, a jQuery event is issued: The below screenshot indicates that I have selected “Oct-15”.
The private function _gestureSelect of Calendar.js is called: Inside this function, the selected date is returned:
And then raise the UI5 event “TapOnDate” with selected date:
(2) The event handler defined during the creation of internal Calendar control is called now. The passed in raw date “Thu Oct 15 2015” is formatted to “Oct 15 2015”, and then assigned to property “DateValue”.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z6gKUsYF-1596955587956)(https://upload-images.jianshu.io/upload_images/2085791-0d151a0bedc1b6cd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
Do you still remember another property “Value”? It will be filld by line 48: this.setProperty(“value”, t): Its value comes from the format result of date object:
after line 20 is executed, the formatted date is “October 15, 2015”:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QIQgIchW-1596955587961)(https://upload-images.jianshu.io/upload_images/2085791-15e4870bec63f65d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SQschacM-1596955587963)(https://upload-images.jianshu.io/upload_images/2085791-6ab573dc6d401e97.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
So which exactly line of code triggers the change of the DatePicker control display, from previous date to the selected date? For example, I have selected Oct-15 in UI, and after line 2732 below is executed, the field of DatePicker in UI will refresh correspondingly to October 15, 2015.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oVKNxPzQ-1596955587964)(https://upload-images.jianshu.io/upload_images/2085791-d01a794d4baa2079.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
Internally, it is because setValue of DatePicker is called:
The call is further delegated to prototype sap.m.InputBase:
Here the Dom value is changed, so UI is refreshed accordingly.
Then DatePicker.js again raises its change event to application ( consumer ) with the two parameters:
(3) Then the event handler defined in application xml view is called:
When does the formatOptions set in XML view take effect? In xml view, we have defined style long for DatePicker’s formatOptions.
In the runtime, this binding information is represented by an instance of PropertyBinding. The path, type and formatOptions configured in xml view become corresponding attributes of the instance as displayed below.
The date object “Thu Oct 15 2015 00:00:00 GMT+0800 (China Standard)” is converted to String “October 15, 2015” by line 20, which is the final content you see in UI.
- ASP.NET SignalR 2.0入门指南介绍SignalRSignalR和WebSocket传输和回滚HTML5 传输协议Comet transports传输协议选择过程监测传输指定传输协议连接
- ASP.NET5之客户端开发:Grunt和Gulp构建工具在Visual Studio 2015中的高效的应用Grunt和Gulp使用Grunt准备项目配置NPM配置Grunt集成起来监测文件变化与V
- 有趣的算法(三)——Hash算法
- JavaScript中的数据类型
- Logistic回归算法及Python实现
- <script>元素在XHTML中的用法
- 有趣的算法(四)——一致性Hash算法模拟redis集群
- ASP.NET5 中静态文件的各种使用方式服务端的静态文件开启目录浏览呈现默认文件使用UseFileServer方法文件类型基于IIS的考虑最佳实践
- 使用ASP.NET Identity以手机短信实现双重验证创建一个ASP.NET 5项目运行应用程序使用SMS短信进行双重验证开启双重验证使用双重验证登陆应用程序禁用账户来防止暴力破解
- ASP.NET 5 之 错误诊断和它的中间件们配置错误处理页面在Development阶段使用错误页面运行时信息页面欢迎页面
- 有趣的算法(五) ——Dijkstra双栈四则运算
- CSS深入理解学习笔记之float
- 轻松初探 Python 篇(五)—dict 和 set 知识汇总
- 全面解析C#中的异步编程为什么要异步过去糟糕的体验一个新的方式Tasks基于任务的异步编程模型Async和await时间处理程序和无返回值的异步方法结束语
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 猿实战12——类目属性之动态绑定
- 一个maskrcnn的目标检测和实例分割的小例子
- Nginx系列:Nginx自带后端健康检查
- 消息队列之推还是拉,RocketMQ 和 Kafka是如何做的?
- Nginx系列:root与alias指令用法的区别
- Redis系列:Linux下部署Redis 6.x 版本
- 分布式锁的封装也很有讲究呀
- PHP与SEO,应用curl及正则获取搜狗搜索相关关键词
- Kafka经典面试题,你都会吗?
- 提高单细胞分析准确度的工具之一:Self-assembling manifolds
- 一不小心肝出了4W字的Redis面试教程
- 双向LSTM-CRF模型用于序列标注
- 容器服务 TKE 上服务暴露的几种方式
- 【论文分享】ACL 2020 信息抽取任务中的新动向
- 工匠人iOS 代码规范