Date3.html 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-picker-Date'>/**
  19. </span> * A date picker. This class is used by the Ext.form.field.Date field to allow browsing and selection of valid
  20. * dates in a popup next to the field, but may also be used with other components.
  21. *
  22. * Typically you will need to implement a handler function to be notified when the user chooses a date from the picker;
  23. * you can register the handler using the {@link #select} event, or by implementing the {@link #handler} method.
  24. *
  25. * By default the user will be allowed to pick any date; this can be changed by using the {@link #minDate},
  26. * {@link #maxDate}, {@link #disabledDays}, {@link #disabledDatesRE}, and/or {@link #disabledDates} configs.
  27. *
  28. * All the string values documented below may be overridden by including an Ext locale file in your page.
  29. *
  30. * @example
  31. * Ext.create('Ext.panel.Panel', {
  32. * title: 'Choose a future date:',
  33. * width: 200,
  34. * bodyPadding: 10,
  35. * renderTo: Ext.getBody(),
  36. * items: [{
  37. * xtype: 'datepicker',
  38. * minDate: new Date(),
  39. * handler: function(picker, date) {
  40. * // do something with the selected date
  41. * }
  42. * }]
  43. * });
  44. */
  45. Ext.define('Ext.picker.Date', {
  46. extend: 'Ext.Component',
  47. requires: [
  48. 'Ext.XTemplate',
  49. 'Ext.button.Button',
  50. 'Ext.button.Split',
  51. 'Ext.util.ClickRepeater',
  52. 'Ext.util.KeyNav',
  53. 'Ext.EventObject',
  54. 'Ext.fx.Manager',
  55. 'Ext.picker.Month'
  56. ],
  57. alias: 'widget.datepicker',
  58. alternateClassName: 'Ext.DatePicker',
  59. childEls: [
  60. 'innerEl', 'eventEl', 'prevEl', 'nextEl', 'middleBtnEl', 'footerEl'
  61. ],
  62. border: true,
  63. renderTpl: [
  64. '&lt;div id=&quot;{id}-innerEl&quot; role=&quot;grid&quot;&gt;',
  65. '&lt;div role=&quot;presentation&quot; class=&quot;{baseCls}-header&quot;&gt;',
  66. '&lt;div class=&quot;{baseCls}-prev&quot;&gt;&lt;a id=&quot;{id}-prevEl&quot; href=&quot;#&quot; role=&quot;button&quot; title=&quot;{prevText}&quot;&gt;&lt;/a&gt;&lt;/div&gt;',
  67. '&lt;div class=&quot;{baseCls}-month&quot; id=&quot;{id}-middleBtnEl&quot;&gt;{%this.renderMonthBtn(values, out)%}&lt;/div&gt;',
  68. '&lt;div class=&quot;{baseCls}-next&quot;&gt;&lt;a id=&quot;{id}-nextEl&quot; href=&quot;#&quot; role=&quot;button&quot; title=&quot;{nextText}&quot;&gt;&lt;/a&gt;&lt;/div&gt;',
  69. '&lt;/div&gt;',
  70. '&lt;table id=&quot;{id}-eventEl&quot; class=&quot;{baseCls}-inner&quot; cellspacing=&quot;0&quot; role=&quot;presentation&quot;&gt;',
  71. '&lt;thead role=&quot;presentation&quot;&gt;&lt;tr role=&quot;presentation&quot;&gt;',
  72. '&lt;tpl for=&quot;dayNames&quot;&gt;',
  73. '&lt;th role=&quot;columnheader&quot; title=&quot;{.}&quot;&gt;&lt;span&gt;{.:this.firstInitial}&lt;/span&gt;&lt;/th&gt;',
  74. '&lt;/tpl&gt;',
  75. '&lt;/tr&gt;&lt;/thead&gt;',
  76. '&lt;tbody role=&quot;presentation&quot;&gt;&lt;tr role=&quot;presentation&quot;&gt;',
  77. '&lt;tpl for=&quot;days&quot;&gt;',
  78. '{#:this.isEndOfWeek}',
  79. '&lt;td role=&quot;gridcell&quot; id=&quot;{[Ext.id()]}&quot;&gt;',
  80. '&lt;a role=&quot;presentation&quot; href=&quot;#&quot; hidefocus=&quot;on&quot; class=&quot;{parent.baseCls}-date&quot; tabIndex=&quot;1&quot;&gt;',
  81. '&lt;em role=&quot;presentation&quot;&gt;&lt;span role=&quot;presentation&quot;&gt;&lt;/span&gt;&lt;/em&gt;',
  82. '&lt;/a&gt;',
  83. '&lt;/td&gt;',
  84. '&lt;/tpl&gt;',
  85. '&lt;/tr&gt;&lt;/tbody&gt;',
  86. '&lt;/table&gt;',
  87. '&lt;tpl if=&quot;showToday&quot;&gt;',
  88. '&lt;div id=&quot;{id}-footerEl&quot; role=&quot;presentation&quot; class=&quot;{baseCls}-footer&quot;&gt;{%this.renderTodayBtn(values, out)%}&lt;/div&gt;',
  89. '&lt;/tpl&gt;',
  90. '&lt;/div&gt;',
  91. {
  92. firstInitial: function(value) {
  93. return Ext.picker.Date.prototype.getDayInitial(value);
  94. },
  95. isEndOfWeek: function(value) {
  96. // convert from 1 based index to 0 based
  97. // by decrementing value once.
  98. value--;
  99. var end = value % 7 === 0 &amp;&amp; value !== 0;
  100. return end ? '&lt;/tr&gt;&lt;tr role=&quot;row&quot;&gt;' : '';
  101. },
  102. renderTodayBtn: function(values, out) {
  103. Ext.DomHelper.generateMarkup(values.$comp.todayBtn.getRenderTree(), out);
  104. },
  105. renderMonthBtn: function(values, out) {
  106. Ext.DomHelper.generateMarkup(values.$comp.monthBtn.getRenderTree(), out);
  107. }
  108. }
  109. ],
  110. //&lt;locale&gt;
  111. <span id='Ext-picker-Date-cfg-todayText'> /**
  112. </span> * @cfg {String} todayText
  113. * The text to display on the button that selects the current date
  114. */
  115. todayText : 'Today',
  116. //&lt;/locale&gt;
  117. //&lt;locale&gt;
  118. <span id='Ext-picker-Date-cfg-ariaTitle'> /**
  119. </span> * @cfg {String} ariaTitle
  120. * The text to display for the aria title
  121. */
  122. ariaTitle: 'Date Picker: {0}',
  123. //&lt;/locale&gt;
  124. //&lt;locale&gt;
  125. <span id='Ext-picker-Date-cfg-ariaTitleDateFormat'> /**
  126. </span> * @cfg {String} ariaTitleDateFormat
  127. * The date format to display for the current value in the {@link #ariaTitle}
  128. */
  129. ariaTitleDateFormat: 'F d, Y',
  130. //&lt;/locale&gt;
  131. <span id='Ext-picker-Date-cfg-handler'> /**
  132. </span> * @cfg {Function} handler
  133. * Optional. A function that will handle the select event of this picker. The handler is passed the following
  134. * parameters:
  135. *
  136. * - `picker` : Ext.picker.Date
  137. *
  138. * This Date picker.
  139. *
  140. * - `date` : Date
  141. *
  142. * The selected date.
  143. */
  144. <span id='Ext-picker-Date-cfg-scope'> /**
  145. </span> * @cfg {Object} scope
  146. * The scope (`this` reference) in which the `{@link #handler}` function will be called.
  147. *
  148. * Defaults to this DatePicker instance.
  149. */
  150. //&lt;locale&gt;
  151. <span id='Ext-picker-Date-cfg-todayTip'> /**
  152. </span> * @cfg {String} todayTip
  153. * A string used to format the message for displaying in a tooltip over the button that selects the current date.
  154. * The `{0}` token in string is replaced by today's date.
  155. */
  156. todayTip : '{0} (Spacebar)',
  157. //&lt;/locale&gt;
  158. //&lt;locale&gt;
  159. <span id='Ext-picker-Date-cfg-minText'> /**
  160. </span> * @cfg {String} minText
  161. * The error text to display if the minDate validation fails.
  162. */
  163. minText : 'This date is before the minimum date',
  164. //&lt;/locale&gt;
  165. //&lt;locale&gt;
  166. <span id='Ext-picker-Date-cfg-maxText'> /**
  167. </span> * @cfg {String} maxText
  168. * The error text to display if the maxDate validation fails.
  169. */
  170. maxText : 'This date is after the maximum date',
  171. //&lt;/locale&gt;
  172. <span id='Ext-picker-Date-cfg-format'> /**
  173. </span> * @cfg {String} format
  174. * The default date format string which can be overriden for localization support. The format must be valid
  175. * according to {@link Ext.Date#parse} (defaults to {@link Ext.Date#defaultFormat}).
  176. */
  177. //&lt;locale&gt;
  178. <span id='Ext-picker-Date-cfg-disabledDaysText'> /**
  179. </span> * @cfg {String} disabledDaysText
  180. * The tooltip to display when the date falls on a disabled day.
  181. */
  182. disabledDaysText : 'Disabled',
  183. //&lt;/locale&gt;
  184. //&lt;locale&gt;
  185. <span id='Ext-picker-Date-cfg-disabledDatesText'> /**
  186. </span> * @cfg {String} disabledDatesText
  187. * The tooltip text to display when the date falls on a disabled date.
  188. */
  189. disabledDatesText : 'Disabled',
  190. //&lt;/locale&gt;
  191. <span id='Ext-picker-Date-cfg-monthNames'> /**
  192. </span> * @cfg {String[]} monthNames
  193. * An array of textual month names which can be overriden for localization support (defaults to Ext.Date.monthNames)
  194. */
  195. <span id='Ext-picker-Date-cfg-dayNames'> /**
  196. </span> * @cfg {String[]} dayNames
  197. * An array of textual day names which can be overriden for localization support (defaults to Ext.Date.dayNames)
  198. */
  199. //&lt;locale&gt;
  200. <span id='Ext-picker-Date-cfg-nextText'> /**
  201. </span> * @cfg {String} nextText
  202. * The next month navigation button tooltip
  203. */
  204. nextText : 'Next Month (Control+Right)',
  205. //&lt;/locale&gt;
  206. //&lt;locale&gt;
  207. <span id='Ext-picker-Date-cfg-prevText'> /**
  208. </span> * @cfg {String} prevText
  209. * The previous month navigation button tooltip
  210. */
  211. prevText : 'Previous Month (Control+Left)',
  212. //&lt;/locale&gt;
  213. //&lt;locale&gt;
  214. <span id='Ext-picker-Date-cfg-monthYearText'> /**
  215. </span> * @cfg {String} monthYearText
  216. * The header month selector tooltip
  217. */
  218. monthYearText : 'Choose a month (Control+Up/Down to move years)',
  219. //&lt;/locale&gt;
  220. //&lt;locale&gt;
  221. <span id='Ext-picker-Date-cfg-monthYearFormat'> /**
  222. </span> * @cfg {String} monthYearFormat
  223. * The date format for the header month
  224. */
  225. monthYearFormat: 'F Y',
  226. //&lt;/locale&gt;
  227. //&lt;locale&gt;
  228. <span id='Ext-picker-Date-cfg-startDay'> /**
  229. </span> * @cfg {Number} [startDay=undefined]
  230. * Day index at which the week should begin, 0-based.
  231. *
  232. * Defaults to `0` (Sunday).
  233. */
  234. startDay : 0,
  235. //&lt;/locale&gt;
  236. //&lt;locale&gt;
  237. <span id='Ext-picker-Date-cfg-showToday'> /**
  238. </span> * @cfg {Boolean} showToday
  239. * False to hide the footer area containing the Today button and disable the keyboard handler for spacebar that
  240. * selects the current date.
  241. */
  242. showToday : true,
  243. //&lt;/locale&gt;
  244. <span id='Ext-picker-Date-cfg-minDate'> /**
  245. </span> * @cfg {Date} [minDate=null]
  246. * Minimum allowable date (JavaScript date object)
  247. */
  248. <span id='Ext-picker-Date-cfg-maxDate'> /**
  249. </span> * @cfg {Date} [maxDate=null]
  250. * Maximum allowable date (JavaScript date object)
  251. */
  252. <span id='Ext-picker-Date-cfg-disabledDays'> /**
  253. </span> * @cfg {Number[]} [disabledDays=null]
  254. * An array of days to disable, 0-based. For example, [0, 6] disables Sunday and Saturday.
  255. */
  256. <span id='Ext-picker-Date-cfg-disabledDatesRE'> /**
  257. </span> * @cfg {RegExp} [disabledDatesRE=null]
  258. * JavaScript regular expression used to disable a pattern of dates. The {@link #disabledDates}
  259. * config will generate this regex internally, but if you specify disabledDatesRE it will take precedence over the
  260. * disabledDates value.
  261. */
  262. <span id='Ext-picker-Date-cfg-disabledDates'> /**
  263. </span> * @cfg {String[]} disabledDates
  264. * An array of 'dates' to disable, as strings. These strings will be used to build a dynamic regular expression so
  265. * they are very powerful. Some examples:
  266. *
  267. * - ['03/08/2003', '09/16/2003'] would disable those exact dates
  268. * - ['03/08', '09/16'] would disable those days for every year
  269. * - ['^03/08'] would only match the beginning (useful if you are using short years)
  270. * - ['03/../2006'] would disable every day in March 2006
  271. * - ['^03'] would disable every day in every March
  272. *
  273. * Note that the format of the dates included in the array should exactly match the {@link #format} config. In order
  274. * to support regular expressions, if you are using a date format that has '.' in it, you will have to escape the
  275. * dot when restricting dates. For example: ['03\\.08\\.03'].
  276. */
  277. <span id='Ext-picker-Date-cfg-disableAnim'> /**
  278. </span> * @cfg {Boolean} disableAnim
  279. * True to disable animations when showing the month picker.
  280. */
  281. disableAnim: false,
  282. <span id='Ext-picker-Date-cfg-baseCls'> /**
  283. </span> * @cfg {String} [baseCls='x-datepicker']
  284. * The base CSS class to apply to this components element.
  285. */
  286. baseCls: Ext.baseCSSPrefix + 'datepicker',
  287. <span id='Ext-picker-Date-cfg-selectedCls'> /**
  288. </span> * @cfg {String} [selectedCls='x-datepicker-selected']
  289. * The class to apply to the selected cell.
  290. */
  291. <span id='Ext-picker-Date-cfg-disabledCellCls'> /**
  292. </span> * @cfg {String} [disabledCellCls='x-datepicker-disabled']
  293. * The class to apply to disabled cells.
  294. */
  295. //&lt;locale&gt;
  296. <span id='Ext-picker-Date-cfg-longDayFormat'> /**
  297. </span> * @cfg {String} longDayFormat
  298. * The format for displaying a date in a longer format.
  299. */
  300. longDayFormat: 'F d, Y',
  301. //&lt;/locale&gt;
  302. <span id='Ext-picker-Date-cfg-keyNavConfig'> /**
  303. </span> * @cfg {Object} keyNavConfig
  304. * Specifies optional custom key event handlers for the {@link Ext.util.KeyNav} attached to this date picker. Must
  305. * conform to the config format recognized by the {@link Ext.util.KeyNav} constructor. Handlers specified in this
  306. * object will replace default handlers of the same name.
  307. */
  308. <span id='Ext-picker-Date-cfg-focusOnShow'> /**
  309. </span> * @cfg {Boolean} focusOnShow
  310. * True to automatically focus the picker on show.
  311. */
  312. focusOnShow: false,
  313. // private
  314. // Set by other components to stop the picker focus being updated when the value changes.
  315. focusOnSelect: true,
  316. width: 178,
  317. // default value used to initialise each date in the DatePicker
  318. // (note: 12 noon was chosen because it steers well clear of all DST timezone changes)
  319. initHour: 12, // 24-hour format
  320. numDays: 42,
  321. // private, inherit docs
  322. initComponent : function() {
  323. var me = this,
  324. clearTime = Ext.Date.clearTime;
  325. me.selectedCls = me.baseCls + '-selected';
  326. me.disabledCellCls = me.baseCls + '-disabled';
  327. me.prevCls = me.baseCls + '-prevday';
  328. me.activeCls = me.baseCls + '-active';
  329. me.nextCls = me.baseCls + '-prevday';
  330. me.todayCls = me.baseCls + '-today';
  331. me.dayNames = me.dayNames.slice(me.startDay).concat(me.dayNames.slice(0, me.startDay));
  332. me.listeners = Ext.apply(me.listeners||{}, {
  333. mousewheel: {
  334. element: 'eventEl',
  335. fn: me.handleMouseWheel,
  336. scope: me
  337. },
  338. click: {
  339. element: 'eventEl',
  340. fn: me.handleDateClick,
  341. scope: me,
  342. delegate: 'a.' + me.baseCls + '-date'
  343. }
  344. });
  345. this.callParent();
  346. me.value = me.value ?
  347. clearTime(me.value, true) : clearTime(new Date());
  348. me.addEvents(
  349. <span id='Ext-picker-Date-event-select'> /**
  350. </span> * @event select
  351. * Fires when a date is selected
  352. * @param {Ext.picker.Date} this DatePicker
  353. * @param {Date} date The selected date
  354. */
  355. 'select'
  356. );
  357. me.initDisabledDays();
  358. },
  359. beforeRender: function () {
  360. /*
  361. * days array for looping through 6 full weeks (6 weeks * 7 days)
  362. * Note that we explicitly force the size here so the template creates
  363. * all the appropriate cells.
  364. */
  365. var me = this,
  366. days = new Array(me.numDays),
  367. today = Ext.Date.format(new Date(), me.format);
  368. // If there's a Menu among our ancestors, then add the menu class.
  369. // This is so that the MenuManager does not see a mousedown in this Component as a document mousedown, outside the Menu
  370. if (me.up('menu')) {
  371. me.addCls(Ext.baseCSSPrefix + 'menu');
  372. }
  373. me.monthBtn = new Ext.button.Split({
  374. ownerCt: me,
  375. ownerLayout: me.getComponentLayout(),
  376. text: '',
  377. tooltip: me.monthYearText,
  378. listeners: {
  379. click: me.showMonthPicker,
  380. arrowclick: me.showMonthPicker,
  381. scope: me
  382. }
  383. });
  384. if (this.showToday) {
  385. me.todayBtn = new Ext.button.Button({
  386. ownerCt: me,
  387. ownerLayout: me.getComponentLayout(),
  388. text: Ext.String.format(me.todayText, today),
  389. tooltip: Ext.String.format(me.todayTip, today),
  390. tooltipType: 'title',
  391. handler: me.selectToday,
  392. scope: me
  393. });
  394. }
  395. me.callParent();
  396. Ext.applyIf(me, {
  397. renderData: {}
  398. });
  399. Ext.apply(me.renderData, {
  400. dayNames: me.dayNames,
  401. showToday: me.showToday,
  402. prevText: me.prevText,
  403. nextText: me.nextText,
  404. days: days
  405. });
  406. },
  407. // Do the job of a container layout at this point even though we are not a Container.
  408. // TODO: Refactor as a Container.
  409. finishRenderChildren: function () {
  410. var me = this;
  411. me.callParent();
  412. me.monthBtn.finishRender();
  413. if (me.showToday) {
  414. me.todayBtn.finishRender();
  415. }
  416. },
  417. // private, inherit docs
  418. onRender : function(container, position){
  419. var me = this;
  420. me.callParent(arguments);
  421. me.el.unselectable();
  422. me.cells = me.eventEl.select('tbody td');
  423. me.textNodes = me.eventEl.query('tbody td span');
  424. },
  425. // private, inherit docs
  426. initEvents: function(){
  427. var me = this,
  428. eDate = Ext.Date,
  429. day = eDate.DAY;
  430. me.callParent();
  431. me.prevRepeater = new Ext.util.ClickRepeater(me.prevEl, {
  432. handler: me.showPrevMonth,
  433. scope: me,
  434. preventDefault: true,
  435. stopDefault: true
  436. });
  437. me.nextRepeater = new Ext.util.ClickRepeater(me.nextEl, {
  438. handler: me.showNextMonth,
  439. scope: me,
  440. preventDefault:true,
  441. stopDefault:true
  442. });
  443. me.keyNav = new Ext.util.KeyNav(me.eventEl, Ext.apply({
  444. scope: me,
  445. left : function(e){
  446. if(e.ctrlKey){
  447. me.showPrevMonth();
  448. }else{
  449. me.update(eDate.add(me.activeDate, day, -1));
  450. }
  451. },
  452. right : function(e){
  453. if(e.ctrlKey){
  454. me.showNextMonth();
  455. }else{
  456. me.update(eDate.add(me.activeDate, day, 1));
  457. }
  458. },
  459. up : function(e){
  460. if(e.ctrlKey){
  461. me.showNextYear();
  462. }else{
  463. me.update(eDate.add(me.activeDate, day, -7));
  464. }
  465. },
  466. down : function(e){
  467. if(e.ctrlKey){
  468. me.showPrevYear();
  469. }else{
  470. me.update(eDate.add(me.activeDate, day, 7));
  471. }
  472. },
  473. pageUp : me.showNextMonth,
  474. pageDown : me.showPrevMonth,
  475. enter : function(e){
  476. e.stopPropagation();
  477. return true;
  478. }
  479. }, me.keyNavConfig));
  480. if (me.showToday) {
  481. me.todayKeyListener = me.eventEl.addKeyListener(Ext.EventObject.SPACE, me.selectToday, me);
  482. }
  483. me.update(me.value);
  484. },
  485. <span id='Ext-picker-Date-method-initDisabledDays'> /**
  486. </span> * Setup the disabled dates regex based on config options
  487. * @private
  488. */
  489. initDisabledDays : function(){
  490. var me = this,
  491. dd = me.disabledDates,
  492. re = '(?:',
  493. len,
  494. d, dLen, dI;
  495. if(!me.disabledDatesRE &amp;&amp; dd){
  496. len = dd.length - 1;
  497. dLen = dd.length;
  498. for (d = 0; d &lt; dLen; d++) {
  499. dI = dd[d];
  500. re += Ext.isDate(dI) ? '^' + Ext.String.escapeRegex(Ext.Date.dateFormat(dI, me.format)) + '$' : dI;
  501. if (d != len) {
  502. re += '|';
  503. }
  504. }
  505. me.disabledDatesRE = new RegExp(re + ')');
  506. }
  507. },
  508. <span id='Ext-picker-Date-method-setDisabledDates'> /**
  509. </span> * Replaces any existing disabled dates with new values and refreshes the DatePicker.
  510. * @param {String[]/RegExp} disabledDates An array of date strings (see the {@link #disabledDates} config for
  511. * details on supported values), or a JavaScript regular expression used to disable a pattern of dates.
  512. * @return {Ext.picker.Date} this
  513. */
  514. setDisabledDates : function(dd){
  515. var me = this;
  516. if(Ext.isArray(dd)){
  517. me.disabledDates = dd;
  518. me.disabledDatesRE = null;
  519. }else{
  520. me.disabledDatesRE = dd;
  521. }
  522. me.initDisabledDays();
  523. me.update(me.value, true);
  524. return me;
  525. },
  526. <span id='Ext-picker-Date-method-setDisabledDays'> /**
  527. </span> * Replaces any existing disabled days (by index, 0-6) with new values and refreshes the DatePicker.
  528. * @param {Number[]} disabledDays An array of disabled day indexes. See the {@link #disabledDays} config for details
  529. * on supported values.
  530. * @return {Ext.picker.Date} this
  531. */
  532. setDisabledDays : function(dd){
  533. this.disabledDays = dd;
  534. return this.update(this.value, true);
  535. },
  536. <span id='Ext-picker-Date-method-setMinDate'> /**
  537. </span> * Replaces any existing {@link #minDate} with the new value and refreshes the DatePicker.
  538. * @param {Date} value The minimum date that can be selected
  539. * @return {Ext.picker.Date} this
  540. */
  541. setMinDate : function(dt){
  542. this.minDate = dt;
  543. return this.update(this.value, true);
  544. },
  545. <span id='Ext-picker-Date-method-setMaxDate'> /**
  546. </span> * Replaces any existing {@link #maxDate} with the new value and refreshes the DatePicker.
  547. * @param {Date} value The maximum date that can be selected
  548. * @return {Ext.picker.Date} this
  549. */
  550. setMaxDate : function(dt){
  551. this.maxDate = dt;
  552. return this.update(this.value, true);
  553. },
  554. <span id='Ext-picker-Date-method-setValue'> /**
  555. </span> * Sets the value of the date field
  556. * @param {Date} value The date to set
  557. * @return {Ext.picker.Date} this
  558. */
  559. setValue : function(value){
  560. this.value = Ext.Date.clearTime(value, true);
  561. return this.update(this.value);
  562. },
  563. <span id='Ext-picker-Date-method-getValue'> /**
  564. </span> * Gets the current selected value of the date field
  565. * @return {Date} The selected date
  566. */
  567. getValue : function(){
  568. return this.value;
  569. },
  570. //&lt;locale type=&quot;function&quot;&gt;
  571. <span id='Ext-picker-Date-method-getDayInitial'> /**
  572. </span> * Gets a single character to represent the day of the week
  573. * @return {String} The character
  574. */
  575. getDayInitial: function(value){
  576. return value.substr(0,1);
  577. },
  578. //&lt;/locale&gt;
  579. // private
  580. focus : function(){
  581. this.update(this.activeDate);
  582. },
  583. // private, inherit docs
  584. onEnable: function(){
  585. this.callParent();
  586. this.setDisabledStatus(false);
  587. this.update(this.activeDate);
  588. },
  589. // private, inherit docs
  590. onDisable : function(){
  591. this.callParent();
  592. this.setDisabledStatus(true);
  593. },
  594. <span id='Ext-picker-Date-method-setDisabledStatus'> /**
  595. </span> * Set the disabled state of various internal components
  596. * @private
  597. * @param {Boolean} disabled
  598. */
  599. setDisabledStatus : function(disabled){
  600. var me = this;
  601. me.keyNav.setDisabled(disabled);
  602. me.prevRepeater.setDisabled(disabled);
  603. me.nextRepeater.setDisabled(disabled);
  604. if (me.showToday) {
  605. me.todayKeyListener.setDisabled(disabled);
  606. me.todayBtn.setDisabled(disabled);
  607. }
  608. },
  609. <span id='Ext-picker-Date-method-getActive'> /**
  610. </span> * Get the current active date.
  611. * @private
  612. * @return {Date} The active date
  613. */
  614. getActive: function(){
  615. return this.activeDate || this.value;
  616. },
  617. <span id='Ext-picker-Date-method-runAnimation'> /**
  618. </span> * Run any animation required to hide/show the month picker.
  619. * @private
  620. * @param {Boolean} isHide True if it's a hide operation
  621. */
  622. runAnimation: function(isHide){
  623. var picker = this.monthPicker,
  624. options = {
  625. duration: 200,
  626. callback: function(){
  627. if (isHide) {
  628. picker.hide();
  629. } else {
  630. picker.show();
  631. }
  632. }
  633. };
  634. if (isHide) {
  635. picker.el.slideOut('t', options);
  636. } else {
  637. picker.el.slideIn('t', options);
  638. }
  639. },
  640. <span id='Ext-picker-Date-method-hideMonthPicker'> /**
  641. </span> * Hides the month picker, if it's visible.
  642. * @param {Boolean} [animate] Indicates whether to animate this action. If the animate
  643. * parameter is not specified, the behavior will use {@link #disableAnim} to determine
  644. * whether to animate or not.
  645. * @return {Ext.picker.Date} this
  646. */
  647. hideMonthPicker : function(animate){
  648. var me = this,
  649. picker = me.monthPicker;
  650. if (picker) {
  651. if (me.shouldAnimate(animate)) {
  652. me.runAnimation(true);
  653. } else {
  654. picker.hide();
  655. }
  656. }
  657. return me;
  658. },
  659. <span id='Ext-picker-Date-method-showMonthPicker'> /**
  660. </span> * Show the month picker
  661. * @param {Boolean} [animate] Indicates whether to animate this action. If the animate
  662. * parameter is not specified, the behavior will use {@link #disableAnim} to determine
  663. * whether to animate or not.
  664. * @return {Ext.picker.Date} this
  665. */
  666. showMonthPicker : function(animate){
  667. var me = this,
  668. picker;
  669. if (me.rendered &amp;&amp; !me.disabled) {
  670. picker = me.createMonthPicker();
  671. picker.setValue(me.getActive());
  672. picker.setSize(me.getSize());
  673. picker.setPosition(-1, -1);
  674. if (me.shouldAnimate(animate)) {
  675. me.runAnimation(false);
  676. } else {
  677. picker.show();
  678. }
  679. }
  680. return me;
  681. },
  682. <span id='Ext-picker-Date-method-shouldAnimate'> /**
  683. </span> * Checks whether a hide/show action should animate
  684. * @private
  685. * @param {Boolean} [animate] A possible animation value
  686. * @return {Boolean} Whether to animate the action
  687. */
  688. shouldAnimate: function(animate){
  689. return Ext.isDefined(animate) ? animate : !this.disableAnim;
  690. },
  691. <span id='Ext-picker-Date-method-createMonthPicker'> /**
  692. </span> * Create the month picker instance
  693. * @private
  694. * @return {Ext.picker.Month} picker
  695. */
  696. createMonthPicker: function(){
  697. var me = this,
  698. picker = me.monthPicker;
  699. if (!picker) {
  700. me.monthPicker = picker = new Ext.picker.Month({
  701. renderTo: me.el,
  702. floating: true,
  703. shadow: false,
  704. small: me.showToday === false,
  705. listeners: {
  706. scope: me,
  707. cancelclick: me.onCancelClick,
  708. okclick: me.onOkClick,
  709. yeardblclick: me.onOkClick,
  710. monthdblclick: me.onOkClick
  711. }
  712. });
  713. if (!me.disableAnim) {
  714. // hide the element if we're animating to prevent an initial flicker
  715. picker.el.setStyle('display', 'none');
  716. }
  717. me.on('beforehide', Ext.Function.bind(me.hideMonthPicker, me, [false]));
  718. }
  719. return picker;
  720. },
  721. <span id='Ext-picker-Date-method-onOkClick'> /**
  722. </span> * Respond to an ok click on the month picker
  723. * @private
  724. */
  725. onOkClick: function(picker, value){
  726. var me = this,
  727. month = value[0],
  728. year = value[1],
  729. date = new Date(year, month, me.getActive().getDate());
  730. if (date.getMonth() !== month) {
  731. // 'fix' the JS rolling date conversion if needed
  732. date = Ext.Date.getLastDateOfMonth(new Date(year, month, 1));
  733. }
  734. me.update(date);
  735. me.hideMonthPicker();
  736. },
  737. <span id='Ext-picker-Date-method-onCancelClick'> /**
  738. </span> * Respond to a cancel click on the month picker
  739. * @private
  740. */
  741. onCancelClick: function(){
  742. // update the selected value, also triggers a focus
  743. this.selectedUpdate(this.activeDate);
  744. this.hideMonthPicker();
  745. },
  746. <span id='Ext-picker-Date-method-showPrevMonth'> /**
  747. </span> * Show the previous month.
  748. * @param {Object} e
  749. * @return {Ext.picker.Date} this
  750. */
  751. showPrevMonth : function(e){
  752. return this.update(Ext.Date.add(this.activeDate, Ext.Date.MONTH, -1));
  753. },
  754. <span id='Ext-picker-Date-method-showNextMonth'> /**
  755. </span> * Show the next month.
  756. * @param {Object} e
  757. * @return {Ext.picker.Date} this
  758. */
  759. showNextMonth : function(e){
  760. return this.update(Ext.Date.add(this.activeDate, Ext.Date.MONTH, 1));
  761. },
  762. <span id='Ext-picker-Date-method-showPrevYear'> /**
  763. </span> * Show the previous year.
  764. * @return {Ext.picker.Date} this
  765. */
  766. showPrevYear : function(){
  767. this.update(Ext.Date.add(this.activeDate, Ext.Date.YEAR, -1));
  768. },
  769. <span id='Ext-picker-Date-method-showNextYear'> /**
  770. </span> * Show the next year.
  771. * @return {Ext.picker.Date} this
  772. */
  773. showNextYear : function(){
  774. this.update(Ext.Date.add(this.activeDate, Ext.Date.YEAR, 1));
  775. },
  776. <span id='Ext-picker-Date-method-handleMouseWheel'> /**
  777. </span> * Respond to the mouse wheel event
  778. * @private
  779. * @param {Ext.EventObject} e
  780. */
  781. handleMouseWheel : function(e){
  782. e.stopEvent();
  783. if(!this.disabled){
  784. var delta = e.getWheelDelta();
  785. if(delta &gt; 0){
  786. this.showPrevMonth();
  787. } else if(delta &lt; 0){
  788. this.showNextMonth();
  789. }
  790. }
  791. },
  792. <span id='Ext-picker-Date-method-handleDateClick'> /**
  793. </span> * Respond to a date being clicked in the picker
  794. * @private
  795. * @param {Ext.EventObject} e
  796. * @param {HTMLElement} t
  797. */
  798. handleDateClick : function(e, t){
  799. var me = this,
  800. handler = me.handler;
  801. e.stopEvent();
  802. if(!me.disabled &amp;&amp; t.dateValue &amp;&amp; !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)){
  803. me.doCancelFocus = me.focusOnSelect === false;
  804. me.setValue(new Date(t.dateValue));
  805. delete me.doCancelFocus;
  806. me.fireEvent('select', me, me.value);
  807. if (handler) {
  808. handler.call(me.scope || me, me, me.value);
  809. }
  810. // event handling is turned off on hide
  811. // when we are using the picker in a field
  812. // therefore onSelect comes AFTER the select
  813. // event.
  814. me.onSelect();
  815. }
  816. },
  817. <span id='Ext-picker-Date-method-onSelect'> /**
  818. </span> * Perform any post-select actions
  819. * @private
  820. */
  821. onSelect: function() {
  822. if (this.hideOnSelect) {
  823. this.hide();
  824. }
  825. },
  826. <span id='Ext-picker-Date-method-selectToday'> /**
  827. </span> * Sets the current value to today.
  828. * @return {Ext.picker.Date} this
  829. */
  830. selectToday : function(){
  831. var me = this,
  832. btn = me.todayBtn,
  833. handler = me.handler;
  834. if(btn &amp;&amp; !btn.disabled){
  835. me.setValue(Ext.Date.clearTime(new Date()));
  836. me.fireEvent('select', me, me.value);
  837. if (handler) {
  838. handler.call(me.scope || me, me, me.value);
  839. }
  840. me.onSelect();
  841. }
  842. return me;
  843. },
  844. <span id='Ext-picker-Date-method-selectedUpdate'> /**
  845. </span> * Update the selected cell
  846. * @private
  847. * @param {Date} date The new date
  848. */
  849. selectedUpdate: function(date){
  850. var me = this,
  851. t = date.getTime(),
  852. cells = me.cells,
  853. cls = me.selectedCls,
  854. cellItems = cells.elements,
  855. c,
  856. cLen = cellItems.length,
  857. cell;
  858. cells.removeCls(cls);
  859. for (c = 0; c &lt; cLen; c++) {
  860. cell = Ext.fly(cellItems[c]);
  861. if (cell.dom.firstChild.dateValue == t) {
  862. me.fireEvent('highlightitem', me, cell);
  863. cell.addCls(cls);
  864. if(me.isVisible() &amp;&amp; !me.doCancelFocus){
  865. Ext.fly(cell.dom.firstChild).focus(50);
  866. }
  867. break;
  868. }
  869. }
  870. },
  871. <span id='Ext-picker-Date-method-fullUpdate'> /**
  872. </span> * Update the contents of the picker for a new month
  873. * @private
  874. * @param {Date} date The new date
  875. */
  876. fullUpdate: function(date){
  877. var me = this,
  878. cells = me.cells.elements,
  879. textNodes = me.textNodes,
  880. disabledCls = me.disabledCellCls,
  881. eDate = Ext.Date,
  882. i = 0,
  883. extraDays = 0,
  884. visible = me.isVisible(),
  885. sel = +eDate.clearTime(date, true),
  886. today = +eDate.clearTime(new Date()),
  887. min = me.minDate ? eDate.clearTime(me.minDate, true) : Number.NEGATIVE_INFINITY,
  888. max = me.maxDate ? eDate.clearTime(me.maxDate, true) : Number.POSITIVE_INFINITY,
  889. ddMatch = me.disabledDatesRE,
  890. ddText = me.disabledDatesText,
  891. ddays = me.disabledDays ? me.disabledDays.join('') : false,
  892. ddaysText = me.disabledDaysText,
  893. format = me.format,
  894. days = eDate.getDaysInMonth(date),
  895. firstOfMonth = eDate.getFirstDateOfMonth(date),
  896. startingPos = firstOfMonth.getDay() - me.startDay,
  897. previousMonth = eDate.add(date, eDate.MONTH, -1),
  898. longDayFormat = me.longDayFormat,
  899. prevStart,
  900. current,
  901. disableToday,
  902. tempDate,
  903. setCellClass,
  904. html,
  905. cls,
  906. formatValue,
  907. value;
  908. if (startingPos &lt; 0) {
  909. startingPos += 7;
  910. }
  911. days += startingPos;
  912. prevStart = eDate.getDaysInMonth(previousMonth) - startingPos;
  913. current = new Date(previousMonth.getFullYear(), previousMonth.getMonth(), prevStart, me.initHour);
  914. if (me.showToday) {
  915. tempDate = eDate.clearTime(new Date());
  916. disableToday = (tempDate &lt; min || tempDate &gt; max ||
  917. (ddMatch &amp;&amp; format &amp;&amp; ddMatch.test(eDate.dateFormat(tempDate, format))) ||
  918. (ddays &amp;&amp; ddays.indexOf(tempDate.getDay()) != -1));
  919. if (!me.disabled) {
  920. me.todayBtn.setDisabled(disableToday);
  921. me.todayKeyListener.setDisabled(disableToday);
  922. }
  923. }
  924. setCellClass = function(cell){
  925. value = +eDate.clearTime(current, true);
  926. cell.title = eDate.format(current, longDayFormat);
  927. // store dateValue number as an expando
  928. cell.firstChild.dateValue = value;
  929. if(value == today){
  930. cell.className += ' ' + me.todayCls;
  931. cell.title = me.todayText;
  932. }
  933. if(value == sel){
  934. cell.className += ' ' + me.selectedCls;
  935. me.fireEvent('highlightitem', me, cell);
  936. if (visible &amp;&amp; me.floating) {
  937. Ext.fly(cell.firstChild).focus(50);
  938. }
  939. }
  940. // disabling
  941. if(value &lt; min) {
  942. cell.className = disabledCls;
  943. cell.title = me.minText;
  944. return;
  945. }
  946. if(value &gt; max) {
  947. cell.className = disabledCls;
  948. cell.title = me.maxText;
  949. return;
  950. }
  951. if(ddays){
  952. if(ddays.indexOf(current.getDay()) != -1){
  953. cell.title = ddaysText;
  954. cell.className = disabledCls;
  955. }
  956. }
  957. if(ddMatch &amp;&amp; format){
  958. formatValue = eDate.dateFormat(current, format);
  959. if(ddMatch.test(formatValue)){
  960. cell.title = ddText.replace('%0', formatValue);
  961. cell.className = disabledCls;
  962. }
  963. }
  964. };
  965. for(; i &lt; me.numDays; ++i) {
  966. if (i &lt; startingPos) {
  967. html = (++prevStart);
  968. cls = me.prevCls;
  969. } else if (i &gt;= days) {
  970. html = (++extraDays);
  971. cls = me.nextCls;
  972. } else {
  973. html = i - startingPos + 1;
  974. cls = me.activeCls;
  975. }
  976. textNodes[i].innerHTML = html;
  977. cells[i].className = cls;
  978. current.setDate(current.getDate() + 1);
  979. setCellClass(cells[i]);
  980. }
  981. me.monthBtn.setText(Ext.Date.format(date, me.monthYearFormat));
  982. },
  983. <span id='Ext-picker-Date-method-update'> /**
  984. </span> * Update the contents of the picker
  985. * @private
  986. * @param {Date} date The new date
  987. * @param {Boolean} forceRefresh True to force a full refresh
  988. */
  989. update : function(date, forceRefresh){
  990. var me = this,
  991. active = me.activeDate;
  992. if (me.rendered) {
  993. me.activeDate = date;
  994. if(!forceRefresh &amp;&amp; active &amp;&amp; me.el &amp;&amp; active.getMonth() == date.getMonth() &amp;&amp; active.getFullYear() == date.getFullYear()){
  995. me.selectedUpdate(date, active);
  996. } else {
  997. me.fullUpdate(date, active);
  998. }
  999. me.innerEl.dom.title = Ext.String.format(me.ariaTitle, Ext.Date.format(me.activeDate, me.ariaTitleDateFormat));
  1000. }
  1001. return me;
  1002. },
  1003. // private, inherit docs
  1004. beforeDestroy : function() {
  1005. var me = this;
  1006. if (me.rendered) {
  1007. Ext.destroy(
  1008. me.todayKeyListener,
  1009. me.keyNav,
  1010. me.monthPicker,
  1011. me.monthBtn,
  1012. me.nextRepeater,
  1013. me.prevRepeater,
  1014. me.todayBtn
  1015. );
  1016. delete me.textNodes;
  1017. delete me.cells.elements;
  1018. }
  1019. me.callParent();
  1020. },
  1021. // private, inherit docs
  1022. onShow: function() {
  1023. this.callParent(arguments);
  1024. if (this.focusOnShow) {
  1025. this.focus();
  1026. }
  1027. }
  1028. },
  1029. // After dependencies have loaded:
  1030. function() {
  1031. var proto = this.prototype,
  1032. date = Ext.Date;
  1033. proto.monthNames = date.monthNames;
  1034. proto.dayNames = date.dayNames;
  1035. proto.format = date.defaultFormat;
  1036. });
  1037. </pre>
  1038. </body>
  1039. </html>