Calendar.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. MWF.xDesktop.requireApp("process.Xform", "$Input", null, false);
  2. /** @class Calendar 日期组件。
  3. * @o2cn 日期选择
  4. * @example
  5. * //可以在脚本中获取该组件
  6. * //方法1:
  7. * var field = this.form.get("fieldId"); //获取组件对象
  8. * //方法2
  9. * var field = this.target; //在组件本身的脚本中获取,比如事件脚本、默认值脚本、校验脚本等等
  10. * @extends MWF.xApplication.process.Xform.$Input
  11. * @o2category FormComponents
  12. * @o2range {Process|CMS|Portal}
  13. * @hideconstructor
  14. */
  15. MWF.xApplication.process.Xform.Calendar = MWF.APPCalendar = new Class(
  16. /** @lends MWF.xApplication.process.Xform.Calendar# */
  17. {
  18. Implements: [Events],
  19. Extends: MWF.APP$Input,
  20. iconStyle: "calendarIcon",
  21. options: {
  22. /**
  23. * 日期选择完成时触发.
  24. * @event MWF.xApplication.process.Xform.Calendar#complete
  25. * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
  26. */
  27. /**
  28. * 日期选择器上点清空时触发.
  29. * @event MWF.xApplication.process.Xform.Calendar#clear
  30. * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
  31. */
  32. /**
  33. * 值改变时触发.
  34. * @event MWF.xApplication.process.Xform.Calendar#change
  35. * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
  36. */
  37. /**
  38. * 显示日期选择器时触发.
  39. * @event MWF.xApplication.process.Xform.Calendar#show
  40. * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
  41. */
  42. /**
  43. * 隐藏日期选择器时触发.
  44. * @event MWF.xApplication.process.Xform.Calendar#hide
  45. * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
  46. */
  47. "moduleEvents": ["queryLoad","postLoad","load","complete", "clear", "change","show","hide"]
  48. },
  49. _loadNode: function(){
  50. if (this.isReadonly()){
  51. this._loadNodeRead();
  52. }else{
  53. this._loadNodeEdit();
  54. var input = this.node.getFirst();
  55. input.set("readonly", true);
  56. }
  57. },
  58. setDescriptionEvent: function(){
  59. if (this.descriptionNode){
  60. this.descriptionNode.addEvents({
  61. "mousedown": function(){
  62. this.descriptionNode.setStyle("display", "none");
  63. //this.clickSelect();
  64. }.bind(this)
  65. });
  66. }
  67. },
  68. _getValueAg: function(value,isDate){
  69. if (value && value.isAG){
  70. return value.then(function(v){
  71. this._getValueAg(v, isDate);
  72. }.bind(this), function(){});
  73. }else{
  74. var d = (!!value) ? Date.parse(value) : "";
  75. if (isDate){
  76. return d || null;
  77. }else{
  78. return (d) ? d.format(this.json.format) : "";
  79. }
  80. }
  81. },
  82. getValue: function(isDate){
  83. if (this.moduleValueAG) return this.moduleValueAG;
  84. var value = this._getBusinessData();
  85. if( value && !isDate)return value;
  86. if (!value) value = this._computeValue();
  87. if (value && value.then) return value;
  88. var d = (!!value) ? Date.parse(value) : "";
  89. if (isDate){
  90. return d || null;
  91. }else{
  92. //if (d) value = Date.parse(value).format(this.json.format);
  93. return (d) ? d.format(this.json.format) : "";
  94. }
  95. return value || "";
  96. },
  97. getValueStr : function(){
  98. var value = this._getBusinessData();
  99. if (!value) value = this._computeValue();
  100. return value;
  101. },
  102. __setValue: function(value){
  103. var v;
  104. if( typeOf( value ) === "date" ){
  105. v = (value) ? ( Date.parse(value)).format(this.json.format) : "";
  106. }else{
  107. v = value;
  108. }
  109. this._setBusinessData(value);
  110. if (this.node.getFirst()) this.node.getFirst().set("value", v || "");
  111. if (this.isReadonly()) this.node.set("text", v);
  112. this.moduleValueAG = null;
  113. this.fieldModuleLoaded = true;
  114. return value;
  115. },
  116. _beforeReloaded: function(){
  117. this.calendar = null;
  118. },
  119. clickSelect: function(){
  120. var _self = this;
  121. if (!this.calendar){
  122. MWF.require("MWF.widget.Calendar", function(){
  123. var defaultView = "day";
  124. if( this.json.selectType === "month" )defaultView = "month";
  125. if( this.json.selectType === "year" )defaultView = "year";
  126. var options = {
  127. "style": o2.session.isMobile ? "xform_mobile" : "xform",
  128. "secondEnable" : this.json.isSelectSecond,
  129. "timeSelectType" : this.json.timeSelectType,
  130. "isTime": (this.json.selectType==="datetime" || this.json.selectType==="time"),
  131. "timeOnly": (this.json.selectType === "time"),
  132. "monthOnly" : (this.json.selectType === "month"),
  133. "yearOnly" : (this.json.selectType === "year"),
  134. "defaultView" : defaultView,
  135. //"target": this.form.node,
  136. "target": o2.session.isMobile ? $(document.body) : this.form.app.content,
  137. "format": this.json.format,
  138. "onComplate": function(formateDate, date){
  139. this.validationMode();
  140. if(this.validation()){
  141. var v = this.getInputData("change");
  142. this._setBusinessData(v);
  143. //this._setEnvironmentData(v);
  144. }
  145. this.fireEvent("complete");
  146. }.bind(this),
  147. "onChange": function(){
  148. this._setBusinessData(this.getInputData("change"));
  149. this.fireEvent("change");
  150. }.bind(this),
  151. "onClear": function(){
  152. this.validationMode();
  153. if(this.validation()){
  154. var v = this.getInputData("change");
  155. this._setBusinessData(v);
  156. //this._setEnvironmentData(v);
  157. }
  158. this.fireEvent("clear");
  159. if (!this.node.getFirst().get("value")) if (this.descriptionNode) this.descriptionNode.setStyle("display", "block");
  160. }.bind(this),
  161. "onShow": function(){
  162. if (_self.descriptionNode) _self.descriptionNode.setStyle("display", "none");
  163. if( o2.session.isMobile ){
  164. this.container.position({
  165. relativeTo: $(document.body),
  166. position: 'leftCenter',
  167. edge: 'leftCenter'
  168. //offset : { y : -25 }
  169. });
  170. }else{
  171. var parent = _self.node.getParent();
  172. while( parent ){
  173. var overflow = parent.getStyle("overflow");
  174. var overflowY = parent.getStyle("overflow-y");
  175. if( overflow === "auto" || overflow === "scroll" || overflowY === "auto" || overflowY === "scroll" ){
  176. _self.scrollFun = function( e ){
  177. // if (this.container.position && (!layout || !layout.userLayout || !layout.userLayout.scale || layout.userLayout.scale===1) ){
  178. if( this.postX === "right" ){
  179. if( this.postY === "bottom" ){
  180. this.container.position({
  181. relativeTo: this.node,
  182. position: 'bottomRight',
  183. edge: 'upperRight',
  184. allowNegative : true
  185. });
  186. }else{
  187. this.container.position({
  188. relativeTo: this.node,
  189. position: 'upperRight',
  190. edge: 'bottomRight',
  191. allowNegative : true
  192. });
  193. }
  194. }else{
  195. if( this.postY === "bottom" ) {
  196. this.container.position({
  197. relativeTo: this.node,
  198. position: 'bottomLeft',
  199. edge: 'upperLeft',
  200. allowNegative: true
  201. });
  202. }else{
  203. this.container.position({
  204. relativeTo: this.node,
  205. position: 'upperLeft',
  206. edge: 'bottomLeft',
  207. allowNegative: true
  208. });
  209. }
  210. }
  211. // }else{
  212. // var p = this.node.getPosition(this.options.target || null);
  213. // var size = this.node.getSize();
  214. // var containerSize = this.container.getSize();
  215. // var bodySize = (this.options.target) ? this.options.target.getSize() : $(document.body).getSize(); //$(document.body).getSize();
  216. //
  217. // bodySize.x = bodySize.x * layout.userLayout.scale;
  218. // bodySize.y = bodySize.y * layout.userLayout.scale;
  219. //
  220. // var left = p.x;
  221. // left = left * layout.userLayout.scale;
  222. // if ((left + containerSize.x + 40) > bodySize.x){
  223. // left = bodySize.x - containerSize.x - 40;
  224. // }
  225. //
  226. // var top = p.y+size.y+2;
  227. // top = top * layout.userLayout.scale;
  228. // if( top + containerSize.y > bodySize.y ){
  229. // top = bodySize.y - containerSize.y ;
  230. // }
  231. //
  232. // this.container.setStyle("top", top);
  233. // this.container.setStyle("left", left);
  234. // }
  235. }.bind(this);
  236. _self.scrollParentNode = parent;
  237. parent.addEvent( "scroll", _self.scrollFun );
  238. parent = null;
  239. }else{
  240. parent = parent.getParent();
  241. }
  242. }
  243. }
  244. _self.fireEvent("show");
  245. },
  246. "onHide": function(){
  247. if (!this.node.getFirst().get("value")) if (this.descriptionNode) this.descriptionNode.setStyle("display", "block");
  248. if( _self.scrollParentNode && _self.scrollFun ){
  249. _self.scrollParentNode.removeEvent("scroll", _self.scrollFun);
  250. }
  251. _self.fireEvent("hide");
  252. }.bind(this)
  253. };
  254. options.baseDate = this.getBaseDate();
  255. this.setRange( options );
  256. /**
  257. * @summary 日期弹出选择界面,只读情况下无此成员.
  258. * @member {MWF.widget.Calendar}
  259. * @example
  260. * var calendar = this.form.get("fieldId").calendar; //获取组件
  261. * if(calendar)calendar.show(); //弹出选择组件
  262. */
  263. this.calendar = new MWF.widget.Calendar(this.node.getFirst(), options);
  264. if( this.form.json && this.form.json.canlendarStyle && typeOf( this.form.json.canlendarStyle.zIndex ) !== "null" && typeOf( this.form.json.canlendarStyle.zIndex ) !== "undefined" ){
  265. this.calendar.container.setStyle("z-index", this.form.json.canlendarStyle.zIndex );
  266. }
  267. this.calendar.show();
  268. }.bind(this));
  269. }else{
  270. var options = {};
  271. options.baseDate = this.getBaseDate();
  272. this.calendar.setOptions(options);
  273. //this.calendar.show();
  274. this.node.getFirst().focus();
  275. }
  276. },
  277. getBaseDate : function(){
  278. var d;
  279. var value = this.getValue(true);
  280. if( value && value.getTime() > 10000 ){
  281. d = value;
  282. }else{
  283. var ud = Date.parse( this.unformatDate( this.getValueStr() ) );
  284. if( ud && ud.getTime() > 10000 ){
  285. d = ud;
  286. }else{
  287. d = new Date();
  288. }
  289. }
  290. return d;
  291. },
  292. setRange: function( options ){
  293. var r;
  294. switch ( this.json.rangeType ) {
  295. case "dateTime":
  296. if (this.json.dateTimeRangeScript && this.json.dateTimeRangeScript.code) {
  297. r = this.form.Macro.fire(this.json.dateTimeRangeScript.code, this);
  298. if (typeOf(r) === "array") options.datetimeRange = r;
  299. }
  300. break;
  301. case "dateAndTime":
  302. if (this.json.dateRangeScript && this.json.dateRangeScript.code) {
  303. r = this.form.Macro.fire(this.json.dateRangeScript.code, this);
  304. if (typeOf(r) === "array") options.dateRange = r;
  305. }
  306. if (this.json.timeRangeScript && this.json.timeRangeScript.code) {
  307. r = this.form.Macro.fire(this.json.timeRangeScript.code, this);
  308. if (typeOf(r) === "array") options.timeRange = r;
  309. }
  310. break;
  311. case "other":
  312. if (this.json.enableDate && this.json.enableDate.code) {
  313. options.enableDate = function (date) {
  314. var d = this.getPureDate( date );
  315. return this.form.Macro.fire(this.json.enableDate.code, this, {date: d});
  316. }.bind(this);
  317. }
  318. if (this.json.enableHours && this.json.enableHours.code) {
  319. options.enableHours = function (date) {
  320. var d = this.getPureDate( date );
  321. return this.form.Macro.fire(this.json.enableHours.code, this, {date: d});
  322. }.bind(this);
  323. }
  324. if (this.json.enableMinutes && this.json.enableMinutes.code) {
  325. options.enableMinutes = function (date, hour) {
  326. var d = this.getPureDate( date );
  327. return this.form.Macro.fire(this.json.enableMinutes.code, this, {date: d, hour: hour.toInt()});
  328. }.bind(this);
  329. }
  330. if (this.json.enableSeconds && this.json.enableSeconds.code) {
  331. options.enableSeconds = function (date, hour, minute) {
  332. var d = this.getPureDate( date );
  333. return this.form.Macro.fire(this.json.enableSeconds.code, this, {date: d, hour: hour.toInt(), minute: minute.toInt()});
  334. }.bind(this);
  335. }
  336. break;
  337. }
  338. },
  339. getPureDate: function (date) {
  340. var d;
  341. switch (typeOf(date)) {
  342. case "string": d = Date.parse(date); break;
  343. case "date": d = date.clone(); break;
  344. default: return null;
  345. }
  346. return d.clearTime();
  347. },
  348. unformatDate : function( dateStr ){
  349. var formatStr = this.json.format;
  350. var matchArr = [ "%Y", "%m", "%d", "%H", "%M", "%S", "%z", "%Z" ];
  351. var lengthArr = [ 4, 2, 2, 2, 2, 2, 5, 3];
  352. var indexArr = [ formatStr.indexOf("%Y"), formatStr.indexOf("%m"), formatStr.indexOf("%d"), formatStr.indexOf("%H"), formatStr.indexOf("%M"), formatStr.indexOf("%S"), formatStr.indexOf("%z"), formatStr.indexOf("%Z") ];
  353. var resultArr = [ null, null, null, null, null, null, null, null ];
  354. for( var i=0; i<matchArr.length; i++ ){
  355. if( indexArr[i] === -1 )continue;
  356. var leftLength = 0;
  357. var leftUnitLength = 0;
  358. Array.each( indexArr, function( n, k ){
  359. if( n === -1 )return;
  360. if( indexArr[i] > n ){
  361. leftLength += lengthArr[k];
  362. leftUnitLength += matchArr[k].length;
  363. }
  364. });
  365. resultArr[i] = dateStr.substr( indexArr[i] - leftUnitLength + leftLength, lengthArr[i] );
  366. }
  367. var now = new Date();
  368. for( var i=0; i < resultArr.length; i++ ){
  369. if( !resultArr[i] ){
  370. switch ( matchArr[i] ){
  371. case "%Y":
  372. case "%m":
  373. case "%d":
  374. resultArr[i] = now.format( matchArr[i] );
  375. break;
  376. case "%H":
  377. case "%M":
  378. case "%S":
  379. resultArr[i] = "00";
  380. break;
  381. case "%z":
  382. case "%Z":
  383. default:
  384. break;
  385. }
  386. }
  387. }
  388. return resultArr[0] + "-" + resultArr[1] + "-" + resultArr[2] + " " + resultArr[3]+":"+resultArr[4]+":"+resultArr[5];
  389. },
  390. getExcelData: function(){
  391. return this.getData();
  392. },
  393. setExcelData: function(d){
  394. var value = d.replace(/&#10;/g,""); //换行符&#10;
  395. this.excelData = value;
  396. var json = this.json;
  397. if( value && (new Date(value).isValid()) ){
  398. var format;
  399. if (!json.format){
  400. if (json.selectType==="datetime" || json.selectType==="time"){
  401. format = (json.selectType === "time") ? "%H:%M" : (Locale.get("Date").shortDate + " " + "%H:%M")
  402. }else{
  403. format = Locale.get("Date").shortDate;
  404. }
  405. }else{
  406. format = json.format;
  407. }
  408. value = Date.parse( value ).format( format );
  409. this.setData(value, true);
  410. }else{
  411. this.setData(value, true);
  412. }
  413. }
  414. });