Dashboard sipadu mbip
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

aui-datepicker-debug.js 27KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  1. AUI.add('aui-datepicker-base', function(A) {
  2. var Lang = A.Lang,
  3. isBoolean = Lang.isBoolean,
  4. isFunction = Lang.isFunction,
  5. CALENDAR = 'calendar',
  6. CONTENT_BOX = 'contentBox',
  7. CURRENT_NODE = 'currentNode',
  8. FORMATTER = 'formatter',
  9. SELECT_MULTIPLE_DATES = 'selectMultipleDates',
  10. SET_VALUE = 'setValue',
  11. DATEPICKER = 'date-picker';
  12. var DatePicker = A.Component.create({
  13. NAME: DATEPICKER,
  14. ATTRS: {
  15. /**
  16. * <a href="Calendar.html">Calendar</a> configuration Object.</a>
  17. *
  18. * @attribute calendar
  19. * @default {}
  20. * @type Object
  21. */
  22. calendar: {
  23. setter: '_setCalendar',
  24. value: {}
  25. },
  26. /**
  27. * Function to format the array of the selected dates before set the
  28. * value of the input.
  29. *
  30. * @attribute formatter
  31. * @default function(dates) { return dates.formatted.join(','); }
  32. * @type function
  33. */
  34. formatter: {
  35. value: function(dates) {
  36. return dates.formatted.join(',');
  37. },
  38. validator: isFunction
  39. },
  40. /**
  41. * If true set the selected date with the correct
  42. * <a href="Calendar.html#config_dateFormat">dateFormat</a> to the
  43. * value of the input field which is hosting the Calendar.
  44. *
  45. * @attribute setValue
  46. * @default true
  47. * @type boolean
  48. */
  49. setValue: {
  50. value: true,
  51. validator: isBoolean
  52. },
  53. /**
  54. * If true is able To Do stacking with another overlays.
  55. *
  56. * @attribute stack
  57. * @default true
  58. * @type boolean
  59. */
  60. stack: {
  61. lazyAdd: false,
  62. value: true,
  63. setter: '_setStack',
  64. validator: isBoolean
  65. },
  66. showOn: {
  67. value: 'mousedown'
  68. },
  69. hideOn: {
  70. value: 'mousedown'
  71. }
  72. },
  73. EXTENDS: A.OverlayContext,
  74. prototype: {
  75. /**
  76. * Construction logic executed during Datepicker instantiation. Lifecycle.
  77. *
  78. * @method initializer
  79. * @protected
  80. */
  81. initializer: function() {
  82. var instance = this;
  83. instance.calendar = new A.Calendar(
  84. instance.get(CALENDAR)
  85. );
  86. },
  87. /**
  88. * Bind the events on the Datepicker UI. Lifecycle.
  89. *
  90. * @method bindUI
  91. * @protected
  92. */
  93. bindUI: function() {
  94. var instance = this;
  95. DatePicker.superclass.bindUI.apply(this, arguments);
  96. instance.on('show', instance._onShowOverlay);
  97. instance.after('calendar:select', instance._afterSelectDate);
  98. // Set the value of the trigger with the Calendar current date
  99. if (instance.get(SET_VALUE)) {
  100. instance._setTriggerValue(
  101. instance.calendar._getSelectEventData().date
  102. );
  103. }
  104. },
  105. /**
  106. * Descructor lifecycle implementation for the Datepicker class.
  107. * Purges events attached to the node (and all child nodes).
  108. *
  109. * @method destructor
  110. * @protected
  111. */
  112. destructor: function() {
  113. var instance = this;
  114. instance.calendar.destroy();
  115. },
  116. /**
  117. * Fires when a date is selected on the Calendar.
  118. *
  119. * @method _afterSelectDate
  120. * @param {Event} event
  121. * @protected
  122. */
  123. _afterSelectDate: function(event) {
  124. var instance = this;
  125. if (!instance.calendar.get(SELECT_MULTIPLE_DATES)) {
  126. instance.hide();
  127. }
  128. if (instance.get(SET_VALUE)) {
  129. instance._setTriggerValue(event.date);
  130. }
  131. },
  132. /**
  133. * Fires before the DatePicker overlay show. Responsible to invoke the
  134. * render phase of the Calendar.
  135. *
  136. * @method _onShowOverlay
  137. * @param {Event} event
  138. * @protected
  139. */
  140. _onShowOverlay: function(event) {
  141. var instance = this;
  142. instance._renderCalendar();
  143. },
  144. /**
  145. * Render the Calendar used inside the DatePicker.
  146. *
  147. * @method _renderCalendar
  148. * @protected
  149. */
  150. _renderCalendar: function() {
  151. var instance = this;
  152. instance.calendar.render(
  153. instance.get(CONTENT_BOX)
  154. );
  155. },
  156. /**
  157. * Setter for the <a href="DatePicker.html#calendar">calendar</a>
  158. * attribute.
  159. *
  160. * @method _setCalendar
  161. * @param {String} eventType Event type
  162. * @protected
  163. * @return {}
  164. */
  165. _setCalendar: function(val) {
  166. var instance = this;
  167. A.mix(val, {
  168. bubbleTargets: instance
  169. });
  170. return val;
  171. },
  172. /**
  173. * Setter for the <a href="Calendar.html#config_stack">stack</a> attribute.
  174. *
  175. * @method _setStack
  176. * @param {boolean} value
  177. * @protected
  178. * @return {boolean}
  179. */
  180. _setStack: function(value) {
  181. var instance = this;
  182. if (value) {
  183. A.DatepickerManager.register(instance);
  184. }
  185. else {
  186. A.DatepickerManager.remove(instance);
  187. }
  188. return value;
  189. },
  190. /**
  191. * Set the value of the trigger input with the date information.
  192. *
  193. * @method _setTriggerValue
  194. * @param {Object} dateObj Object containing date information
  195. * @protected
  196. */
  197. _setTriggerValue: function(dateObj) {
  198. var instance = this;
  199. var value = instance.get(FORMATTER).apply(instance, [dateObj]);
  200. instance.get(CURRENT_NODE).val(value);
  201. }
  202. }
  203. });
  204. A.DatePicker = DatePicker;
  205. /**
  206. * A base class for DatepickerManager:
  207. *
  208. * @param config {Object} Object literal specifying widget configuration properties.
  209. *
  210. * @class DatepickerManager
  211. * @constructor
  212. * @extends OverlayManager
  213. * @static
  214. */
  215. A.DatepickerManager = new A.OverlayManager({
  216. /**
  217. * ZIndex default value passed to the
  218. * <a href="OverlayManager.html#config_zIndexBase">zIndexBase</a> of
  219. * <a href="OverlayManager.html">OverlayManager</a>.
  220. *
  221. * @attribute zIndexBase
  222. * @default 1000
  223. * @type Number
  224. */
  225. zIndexBase: 1000
  226. });
  227. }, '@VERSION@' ,{requires:['aui-calendar','aui-overlay-context'], skinnable:true});
  228. AUI.add('aui-datepicker-select', function(A) {
  229. /**
  230. * The DatePickerSelect Utility
  231. *
  232. * @module aui-calendar
  233. * @submodule aui-calendar-datepicker-select
  234. */
  235. var Lang = A.Lang,
  236. isArray = Lang.isArray,
  237. nodeSetter = function(v) {
  238. return A.one(v);
  239. },
  240. createSelect = function() {
  241. return A.Node.create(SELECT_TPL);
  242. },
  243. DOC = A.config.doc,
  244. APPEND_ORDER = 'appendOrder',
  245. BLANK = '',
  246. BODY = 'body',
  247. BOUNDING_BOX = 'boundingBox',
  248. BUTTON = 'button',
  249. BUTTON_NODE = 'buttonNode',
  250. BUTTONITEM = 'buttonitem',
  251. CALENDAR = 'calendar',
  252. CLEARFIX = 'clearfix',
  253. CONTENT = 'content',
  254. CONTENT_BOX = 'contentBox',
  255. CURRENT_DAY = 'currentDay',
  256. CURRENT_MONTH = 'currentMonth',
  257. CURRENT_YEAR = 'currentYear',
  258. DATA_COMPONENT_ID = 'data-auiComponentID',
  259. DATEPICKER = 'datepicker',
  260. DAY = 'day',
  261. DAY_NODE = 'dayNode',
  262. DAY_NODE_NAME = 'dayNodeName',
  263. DISABLED = 'disabled',
  264. DISPLAY = 'display',
  265. DOT = '.',
  266. HELPER = 'helper',
  267. LOCALE = 'locale',
  268. ID = 'id',
  269. MAX_DATE = 'maxDate',
  270. MIN_DATE = 'minDate',
  271. MONTH = 'month',
  272. MONTH_NODE = 'monthNode',
  273. MONTH_NODE_NAME = 'monthNodeName',
  274. NAME = 'name',
  275. NULLABLE_DAY = 'nullableDay',
  276. NULLABLE_MONTH = 'nullableMonth',
  277. NULLABLE_YEAR = 'nullableYear',
  278. OPTION = 'option',
  279. POPULATE_DAY = 'populateDay',
  280. POPULATE_MONTH = 'populateMonth',
  281. POPULATE_YEAR = 'populateYear',
  282. SELECT = 'select',
  283. SELECTED = 'selected',
  284. SELECT_WRAPPER_NODE = 'selectWrapperNode',
  285. SPACE = ' ',
  286. SRC_NODE = 'srcNode',
  287. TRIGGER = 'trigger',
  288. WRAPPER = 'wrapper',
  289. YEAR = 'year',
  290. YEAR_NODE = 'yearNode',
  291. YEAR_NODE_NAME = 'yearNodeName',
  292. YEAR_RANGE = 'yearRange',
  293. getClassName = A.getClassName,
  294. CSS_BUTTONITEM = getClassName(BUTTONITEM),
  295. CSS_DATEPICKER = getClassName(DATEPICKER),
  296. CSS_DATEPICKER_BUTTON_WRAPPER = getClassName(DATEPICKER, BUTTON, WRAPPER),
  297. CSS_DATEPICKER_DAY = getClassName(DATEPICKER, DAY),
  298. CSS_DATEPICKER_DISPLAY = getClassName(DATEPICKER, DISPLAY),
  299. CSS_DATEPICKER_DISPLAY_CONTENT = getClassName(DATEPICKER, DISPLAY, CONTENT),
  300. CSS_DATEPICKER_MONTH = getClassName(DATEPICKER, MONTH),
  301. CSS_DATEPICKER_SELECT_WRAPPER = getClassName(DATEPICKER, SELECT, WRAPPER),
  302. CSS_DATEPICKER_YEAR = getClassName(DATEPICKER, YEAR),
  303. CSS_HELPER_CLEARFIX = getClassName(HELPER, CLEARFIX),
  304. SELECT_TPL = '<select></select>',
  305. SELECT_OPTION_TPL = '<option></option>',
  306. WRAPPER_BUTTON_TPL = '<div class="'+ CSS_DATEPICKER_BUTTON_WRAPPER +'"></div>',
  307. WRAPPER_SELECT_TPL = '<div class='+ CSS_DATEPICKER_SELECT_WRAPPER +'></div>';
  308. /**
  309. * <p><img src="assets/images/aui-calendar-datepicker-select/main.png"/></p>
  310. *
  311. * A base class for DatePickerSelect, providing:
  312. * <ul>
  313. * <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li>
  314. * <li>Select a date from Calendar to select elements</li>
  315. * </ul>
  316. *
  317. * Quick Example:<br/>
  318. *
  319. * <pre><code>var instance = new A.DatePickerSelect({
  320. * srcNode: '#srcNodeId',
  321. * calendar: {
  322. * // locale: 'pt-br',
  323. * dateFormat: '%m/%d/%y',
  324. * yearRange: [ 1970, 2009 ]
  325. * }
  326. * }).render();
  327. * </code></pre>
  328. *
  329. * Check the list of <a href="DatePickerSelect.html#configattributes">Configuration Attributes</a> available for
  330. * DatePickerSelect.
  331. *
  332. * @class DatePickerSelect
  333. * @param config {Object} Object literal specifying widget configuration properties.
  334. * @constructor
  335. * @extends Component
  336. */
  337. var DatePickerSelect = A.Component.create(
  338. {
  339. /**
  340. * Static property provides a string to identify the class.
  341. *
  342. * @property DatePickerSelect.NAME
  343. * @type String
  344. * @static
  345. */
  346. NAME: DATEPICKER,
  347. /**
  348. * Static property used to define the default attribute
  349. * configuration for the DatePickerSelect.
  350. *
  351. * @property DatePickerSelect.ATTRS
  352. * @type Object
  353. * @static
  354. */
  355. ATTRS: {
  356. /**
  357. * The order the selects elements are appended to the
  358. * <a href="DatePickerSelect.html#config_srcNode">srcNode</a>.
  359. *
  360. * @attribute appendOrder
  361. * @default [ 'm', 'd', 'y' ]
  362. * @type Array
  363. */
  364. appendOrder: {
  365. validator: isArray,
  366. value: [ 'm', 'd', 'y' ]
  367. },
  368. /**
  369. * DOM Node to display the button of the DatePickerSelect. If not
  370. * specified try to query using HTML_PARSER an element inside
  371. * contentBox which matches <code>aui-buttonitem</code>.
  372. *
  373. * @attribute buttonNode
  374. * @default Generated div element.
  375. * @type String
  376. */
  377. buttonNode: {},
  378. /**
  379. * <a href="Calendar.html">Calendar</a> configuration Object.</a>
  380. *
  381. * @attribute calendar
  382. * @default {}
  383. * @type Object
  384. */
  385. calendar: {
  386. value: {}
  387. },
  388. /**
  389. * DOM Node to display the day of the DatePickerSelect. If not
  390. * specified try to query using HTML_PARSER an element inside
  391. * contentBox which matches <code>aui-datepicker-year</code>.
  392. *
  393. * @attribute dayNode
  394. * @default Generated div element.
  395. * @type String | Node
  396. */
  397. dayNode: {
  398. setter: nodeSetter,
  399. valueFn: createSelect
  400. },
  401. /**
  402. * Name attribute used on the
  403. * <a href="DatePickerSelect.html#config_dayNode">dayNode</a>.
  404. *
  405. * @attribute dayNodeName
  406. * @default day
  407. * @type String
  408. */
  409. dayNodeName: {
  410. valueFn: function() {
  411. return this.get(DAY_NODE).get(NAME) || DAY;
  412. }
  413. },
  414. /**
  415. * DOM Node to display the month of the DatePickerSelect. If not
  416. * specified try to query using HTML_PARSER an element inside
  417. * contentBox which matches <code>aui-datepicker-year</code>.
  418. *
  419. * @attribute monthNode
  420. * @default Generated div element.
  421. * @type String | Node
  422. */
  423. monthNode: {
  424. setter: nodeSetter,
  425. valueFn: createSelect
  426. },
  427. /**
  428. * Name attribute used on the
  429. * <a href="DatePickerSelect.html#config_monthNode">monthNode</a>.
  430. *
  431. * @attribute monthNodeName
  432. * @default month
  433. * @type String
  434. */
  435. monthNodeName: {
  436. valueFn: function() {
  437. return this.get(MONTH_NODE).get(NAME) || MONTH;
  438. }
  439. },
  440. /**
  441. * If true the select element for the day will be nullable
  442. *
  443. * @attribute nullableDay
  444. * @default false
  445. * @type boolean
  446. */
  447. nullableDay: {
  448. value: false
  449. },
  450. /**
  451. * If true the select element for the month will be nullable
  452. *
  453. * @attribute nullableMonth
  454. * @default false
  455. * @type boolean
  456. */
  457. nullableMonth: {
  458. value: false
  459. },
  460. /**
  461. * If true the select element for the year will be nullable
  462. *
  463. * @attribute nullableYear
  464. * @default false
  465. * @type boolean
  466. */
  467. nullableYear: {
  468. value: false
  469. },
  470. /**
  471. * If true the select element for the days will be automatic
  472. * populated.
  473. *
  474. * @attribute populateDay
  475. * @default true
  476. * @type boolean
  477. */
  478. populateDay: {
  479. value: true
  480. },
  481. /**
  482. * If true the select element for the month will be automatic
  483. * populated.
  484. *
  485. * @attribute populateMonth
  486. * @default true
  487. * @type boolean
  488. */
  489. populateMonth: {
  490. value: true
  491. },
  492. /**
  493. * If true the select element for the year will be automatic
  494. * populated.
  495. *
  496. * @attribute populateYear
  497. * @default true
  498. * @type boolean
  499. */
  500. populateYear: {
  501. value: true
  502. },
  503. /**
  504. * DOM Node to display the selects of the DatePickerSelect. If not
  505. * specified try to query using HTML_PARSER an element inside
  506. * contentBox which matches <code>aui-datepicker-select-wrapper</code>.
  507. *
  508. * @attribute selectWrapperNode
  509. * @default Generated div element.
  510. * @type String
  511. */
  512. selectWrapperNode: {
  513. valueFn: function() {
  514. return A.Node.create(WRAPPER_SELECT_TPL);
  515. }
  516. },
  517. /**
  518. * Trigger element to open the calendar. Inherited from
  519. * <a href="OverlayContext.html#config_trigger">OverlayContext</a>.
  520. *
  521. * @attribute trigger
  522. * @default Generated HTLM div element
  523. * @type {Node | String}
  524. */
  525. trigger: {
  526. setter: function(value) {
  527. if (value instanceof A.NodeList) {
  528. return value;
  529. }
  530. else if (Lang.isString(value)) {
  531. return A.all(value);
  532. }
  533. return new A.NodeList(value);
  534. },
  535. valueFn: function() {
  536. return A.NodeList.create(WRAPPER_BUTTON_TPL);
  537. }
  538. },
  539. /**
  540. * DOM Node to display the year of the DatePickerSelect. If not
  541. * specified try to query using HTML_PARSER an element inside
  542. * contentBox which matches <code>aui-datepicker-year</code>.
  543. *
  544. * @attribute yearNode
  545. * @default Generated div element.
  546. * @type String | Node
  547. */
  548. yearNode: {
  549. setter: nodeSetter,
  550. valueFn: createSelect
  551. },
  552. /**
  553. * Name attribute used on the
  554. * <a href="DatePickerSelect.html#config_yearNode">yearNode</a>.
  555. *
  556. * @attribute yearNodeName
  557. * @default year
  558. * @type String
  559. */
  560. yearNodeName: {
  561. valueFn: function() {
  562. return this.get(YEAR_NODE).get(NAME) || YEAR;
  563. }
  564. },
  565. /**
  566. * Year range to be displayed on the year select element. By default
  567. * it displays from -10 to +10 years from the current year.
  568. *
  569. * @attribute yearRange
  570. * @default [ year - 10, year + 10 ]
  571. * @type Array
  572. */
  573. yearRange: {
  574. validator: isArray,
  575. valueFn: function() {
  576. var year = new Date().getFullYear();
  577. return [ year - 10, year + 10 ];
  578. }
  579. }
  580. },
  581. /**
  582. * Object hash, defining how attribute values are to be parsed from
  583. * markup contained in the widget's content box.
  584. *
  585. * @property DatePickerSelect.HTML_PARSER
  586. * @type Object
  587. * @static
  588. */
  589. HTML_PARSER: {
  590. buttonNode: DOT + CSS_BUTTONITEM,
  591. dayNode: DOT + CSS_DATEPICKER_DAY,
  592. monthNode: DOT + CSS_DATEPICKER_MONTH,
  593. selectWrapperNode: DOT + CSS_DATEPICKER_SELECT_WRAPPER,
  594. trigger: DOT + CSS_DATEPICKER_BUTTON_WRAPPER,
  595. yearNode: DOT + CSS_DATEPICKER_YEAR
  596. },
  597. EXTENDS: A.Component,
  598. prototype: {
  599. /**
  600. * Bind the events on the DatePickerSelect UI. Lifecycle.
  601. *
  602. * @method bindUI
  603. * @protected
  604. */
  605. bindUI: function() {
  606. var instance = this;
  607. instance._bindSelectEvents();
  608. instance.after('calendar:clear', instance._afterClearDate);
  609. instance.after('calendar:select', instance._afterSelectDate);
  610. },
  611. /**
  612. * Descructor lifecycle implementation for the Datepicker class.
  613. * Purges events attached to the node (and all child nodes).
  614. *
  615. * @method destructor
  616. * @protected
  617. */
  618. destructor: function() {
  619. var instance = this;
  620. instance.datePicker.destroy();
  621. },
  622. /**
  623. * Create the DOM structure for the DatePickerSelect. Lifecycle.
  624. *
  625. * @method renderUI
  626. * @protected
  627. */
  628. renderUI: function() {
  629. var instance = this;
  630. instance._renderElements();
  631. instance._renderTriggerButton();
  632. instance._renderCalendar();
  633. },
  634. /**
  635. * Sync the DatePickerSelect UI. Lifecycle.
  636. *
  637. * @method syncUI
  638. * @protected
  639. */
  640. syncUI: function() {
  641. var instance = this;
  642. instance._syncSelectsUI();
  643. },
  644. /**
  645. * Fires when a None is selected on the Calendar.
  646. *
  647. * @method _afterClearDate
  648. * @param {Event} event
  649. * @protected
  650. */
  651. _afterClearDate: function(event) {
  652. var instance = this;
  653. if (instance.get(NULLABLE_DAY) && instance.get(NULLABLE_MONTH) && instance.get(NULLABLE_YEAR)) {
  654. instance.get(DAY_NODE).val(-1);
  655. instance.get(MONTH_NODE).val(-1);
  656. instance.get(YEAR_NODE).val(-1);
  657. }
  658. },
  659. /**
  660. * Fires when a date is selected on the Calendar.
  661. *
  662. * @method _afterSelectDate
  663. * @param {Event} event
  664. * @protected
  665. */
  666. _afterSelectDate: function(event) {
  667. var instance = this;
  668. if (event.date.normal.length) {
  669. instance._syncSelectsUI();
  670. }
  671. },
  672. /**
  673. * Bind events on each select element (change, keypress, etc).
  674. *
  675. * @method _bindSelectEvents
  676. * @protected
  677. */
  678. _bindSelectEvents: function() {
  679. var instance = this;
  680. var selects = instance.get(SELECT_WRAPPER_NODE).all(SELECT);
  681. selects.on('change', instance._onSelectChange, instance);
  682. selects.on('keypress', instance._onSelectChange, instance);
  683. },
  684. /**
  685. * Gets an Array with the field elements in the correct order defined
  686. * on <a href="DatePickerSelect.html#config_appendOrder">appendOrder</a>.
  687. *
  688. * @method _getAppendOrder
  689. * @protected
  690. * @return {Array}
  691. */
  692. _getAppendOrder: function() {
  693. var instance = this;
  694. var appendOrder = instance.get(APPEND_ORDER);
  695. var id = instance.get(ID);
  696. var mapping = {
  697. d: instance.get(DAY_NODE),
  698. m: instance.get(MONTH_NODE),
  699. y: instance.get(YEAR_NODE)
  700. };
  701. var firstField = mapping[ appendOrder[0] ];
  702. var secondField = mapping[ appendOrder[1] ];
  703. var thirdField = mapping[ appendOrder[2] ];
  704. firstField.setAttribute(DATA_COMPONENT_ID, id);
  705. secondField.setAttribute(DATA_COMPONENT_ID, id);
  706. thirdField.setAttribute(DATA_COMPONENT_ID, id);
  707. return [ firstField, secondField, thirdField ];
  708. },
  709. /**
  710. * Fired on any select change.
  711. *
  712. * @method _onSelectChange
  713. * @param {EventFacade} event
  714. * @protected
  715. */
  716. _onSelectChange: function(event) {
  717. var instance = this;
  718. var target = event.currentTarget || event.target;
  719. var monthChanged = target.test(DOT + CSS_DATEPICKER_MONTH);
  720. var yearChanged = target.test(DOT + CSS_DATEPICKER_YEAR);
  721. var currentDay = instance.get(DAY_NODE).val();
  722. var currentMonth = instance.get(MONTH_NODE).val();
  723. var currentYear = instance.get(YEAR_NODE).val();
  724. var validDay = (currentDay > -1);
  725. var validMonth = (currentMonth > -1);
  726. var validYear = (currentYear > -1);
  727. if (validDay) {
  728. instance.calendar.set(CURRENT_DAY, currentDay);
  729. }
  730. if (validMonth) {
  731. instance.calendar.set(CURRENT_MONTH, currentMonth);
  732. }
  733. if (validYear) {
  734. instance.calendar.set(CURRENT_YEAR, currentYear);
  735. }
  736. if (monthChanged || yearChanged) {
  737. instance._uiSetCurrentMonth();
  738. if (validDay) {
  739. instance._selectCurrentDay();
  740. }
  741. }
  742. if (validDay) {
  743. instance.calendar.selectCurrentDate();
  744. }
  745. if (!validDay || !validMonth || !validYear) {
  746. instance.calendar.clear();
  747. }
  748. },
  749. /**
  750. * Populate the day select element with the correct data.
  751. *
  752. * @method _populateDays
  753. * @protected
  754. */
  755. _populateDays: function() {
  756. var instance = this;
  757. if (instance.get(POPULATE_DAY)) {
  758. instance._populateSelect(
  759. instance.get(DAY_NODE),
  760. 1,
  761. instance.calendar.getDaysInMonth(),
  762. null,
  763. null,
  764. instance.get(NULLABLE_DAY)
  765. );
  766. }
  767. },
  768. /**
  769. * Populate the month select element with the correct data.
  770. *
  771. * @method _populateMonths
  772. * @protected
  773. */
  774. _populateMonths: function() {
  775. var instance = this;
  776. var localeMap = instance.calendar._getLocaleMap();
  777. var monthLabels = localeMap.B;
  778. if (instance.get(POPULATE_MONTH)) {
  779. instance._populateSelect(
  780. instance.get(MONTH_NODE),
  781. 0,
  782. (monthLabels.length - 1),
  783. monthLabels,
  784. null,
  785. instance.get(NULLABLE_MONTH)
  786. );
  787. }
  788. },
  789. /**
  790. * Populate the year select element with the correct data.
  791. *
  792. * @method _populateYears
  793. * @protected
  794. */
  795. _populateYears: function() {
  796. var instance = this;
  797. var yearRange = instance.get(YEAR_RANGE);
  798. if (instance.get(POPULATE_YEAR)) {
  799. instance._populateSelect(
  800. instance.get(YEAR_NODE),
  801. yearRange[0],
  802. yearRange[1],
  803. null,
  804. null,
  805. instance.get(NULLABLE_YEAR)
  806. );
  807. }
  808. },
  809. /**
  810. * Populate a select element with the data passed on the params.
  811. *
  812. * @method _populateSelect
  813. * @param {HTMLSelectElement} select Select to be populated
  814. * @param {Number} fromIndex Index to start
  815. * @param {Number} toIndex Index to end
  816. * @param {Object} values Object with labels to be used as content of each
  817. * option. Optional.
  818. * @protected
  819. * @return {String}
  820. */
  821. _populateSelect: function(select, fromIndex, toIndex, labels, values, nullable) {
  822. var i = 0;
  823. var index = fromIndex;
  824. var selectEl = A.Node.getDOMNode(select);
  825. select.empty();
  826. labels = labels || [];
  827. values = values || [];
  828. if (nullable) {
  829. selectEl.options[0] = new Option(BLANK, -1);
  830. i++;
  831. }
  832. while (index <= toIndex) {
  833. var value = values[index] || index;
  834. var label = labels[index] || index;
  835. selectEl.options[i] = new Option(label, index);
  836. i++;
  837. index++;
  838. }
  839. },
  840. /**
  841. * Populate each select element with the correct data for the day, month
  842. * and year.
  843. *
  844. * @method _populateSelects
  845. * @protected
  846. */
  847. _populateSelects: function() {
  848. var instance = this;
  849. instance._populateDays();
  850. instance._populateMonths();
  851. instance._populateYears();
  852. // restricting dates based on the selects values
  853. var monthOptions = instance.get(MONTH_NODE).all(OPTION);
  854. var yearOptions = instance.get(YEAR_NODE).all(OPTION);
  855. var mLength = monthOptions.size() - 1;
  856. var yLength = yearOptions.size() - 1;
  857. var firstMonth = monthOptions.item(0).val();
  858. var firstYear = yearOptions.item(0).val();
  859. var lastMonth = monthOptions.item(mLength).val();
  860. var lastYear = yearOptions.item(yLength).val();
  861. var maxMonthDays = instance.calendar.getDaysInMonth(lastYear, lastMonth);
  862. var minDate = new Date(firstYear, firstMonth, 1);
  863. var maxDate = new Date(lastYear, lastMonth, maxMonthDays);
  864. instance.calendar.set(MAX_DATE, maxDate);
  865. instance.calendar.set(MIN_DATE, minDate);
  866. },
  867. _renderCalendar: function() {
  868. var instance = this;
  869. var datePickerConfig = {
  870. calendar: instance.get(CALENDAR),
  871. trigger: instance.get(TRIGGER).item(0)
  872. };
  873. var datePicker = new A.DatePicker(datePickerConfig).render();
  874. datePicker.addTarget(instance);
  875. instance.datePicker = datePicker;
  876. instance.calendar = datePicker.calendar;
  877. },
  878. /**
  879. * Render DOM elements for the DatePickerSelect.
  880. *
  881. * @method _renderElements
  882. * @protected
  883. */
  884. _renderElements: function() {
  885. var instance = this;
  886. var boundingBox = instance.get(BOUNDING_BOX);
  887. var contentBox = instance.get(CONTENT_BOX);
  888. var dayNode = instance.get(DAY_NODE);
  889. var monthNode = instance.get(MONTH_NODE);
  890. var yearNode = instance.get(YEAR_NODE);
  891. dayNode.addClass(CSS_DATEPICKER_DAY);
  892. monthNode.addClass(CSS_DATEPICKER_MONTH);
  893. yearNode.addClass(CSS_DATEPICKER_YEAR);
  894. boundingBox.addClass(CSS_DATEPICKER_DISPLAY);
  895. boundingBox.addClass(CSS_HELPER_CLEARFIX);
  896. contentBox.addClass(CSS_DATEPICKER_DISPLAY_CONTENT);
  897. // setting name of the fields
  898. monthNode.set(NAME, instance.get(MONTH_NODE_NAME));
  899. yearNode.set(NAME, instance.get(YEAR_NODE_NAME));
  900. dayNode.set(NAME, instance.get(DAY_NODE_NAME));
  901. if (!monthNode.inDoc(A.config.doc)) {
  902. // append elements
  903. var selectWrapper = instance.get(SELECT_WRAPPER_NODE);
  904. var orderedFields = instance._getAppendOrder();
  905. // this textNode is to prevent layout shifting only
  906. // simulate the default browser space between inputs/selects on re-append
  907. var textNode = A.one(
  908. DOC.createTextNode(SPACE)
  909. );
  910. selectWrapper.append(orderedFields[0]);
  911. selectWrapper.append( textNode.clone() );
  912. selectWrapper.append(orderedFields[1]);
  913. selectWrapper.append( textNode );
  914. selectWrapper.append(orderedFields[2]);
  915. contentBox.append(selectWrapper);
  916. }
  917. },
  918. /**
  919. * Render DOM element for the trigger button of the DatePickerSelect.
  920. *
  921. * @method _renderTriggerButton
  922. * @protected
  923. */
  924. _renderTriggerButton: function() {
  925. var instance = this;
  926. var trigger = instance.get(TRIGGER).item(0);
  927. instance._buttonItem = new A.ButtonItem(
  928. {
  929. boundingBox: instance.get(BUTTON_NODE),
  930. icon: CALENDAR
  931. }
  932. );
  933. instance.get(CONTENT_BOX).append(trigger);
  934. trigger.setAttribute(DATA_COMPONENT_ID, instance.get(ID));
  935. if ( trigger.test(DOT + CSS_DATEPICKER_BUTTON_WRAPPER) ) {
  936. // use Button if the user doesn't specify a trigger
  937. instance._buttonItem.render(trigger);
  938. }
  939. },
  940. /**
  941. * Select the current day on the respective input field.
  942. *
  943. * @method _selectCurrentDay
  944. * @protected
  945. */
  946. _selectCurrentDay: function() {
  947. var instance = this;
  948. var currentDate = instance.calendar.getCurrentDate();
  949. instance.get(DAY_NODE).val(
  950. String(currentDate.getDate())
  951. );
  952. },
  953. /**
  954. * Select the current month on the respective input field.
  955. *
  956. * @method _selectCurrentMonth
  957. * @protected
  958. */
  959. _selectCurrentMonth: function() {
  960. var instance = this;
  961. var currentDate = instance.calendar.getCurrentDate();
  962. instance.get(MONTH_NODE).val(
  963. String(currentDate.getMonth())
  964. );
  965. },
  966. /**
  967. * Select the current year on the respective input field.
  968. *
  969. * @method _selectCurrentYear
  970. * @protected
  971. */
  972. _selectCurrentYear: function() {
  973. var instance = this;
  974. var currentDate = instance.calendar.getCurrentDate();
  975. instance.get(YEAR_NODE).val(
  976. String(currentDate.getFullYear())
  977. );
  978. },
  979. /**
  980. * Sync the UI of each DOM Select element.
  981. *
  982. * @method _syncSelectsUI
  983. * @protected
  984. */
  985. _syncSelectsUI: function() {
  986. var instance = this;
  987. instance._populateSelects();
  988. instance._selectCurrentDay();
  989. instance._selectCurrentMonth();
  990. instance._selectCurrentYear();
  991. },
  992. /**
  993. * Fired after
  994. * <a href="DatePickerSelect.html#config_currentMonth">currentMonth</a> is set.
  995. *
  996. * @method _uiSetCurrentMonth
  997. * @param {EventFacade} event
  998. * @protected
  999. */
  1000. _uiSetCurrentMonth: function(value) {
  1001. var instance = this;
  1002. instance._populateDays();
  1003. },
  1004. /**
  1005. * Fired after
  1006. * <a href="DatePickerSelect.html#config_disabled">disabled</a> is set.
  1007. *
  1008. * @method _afterDisabledChangeDatePicker
  1009. * @param {EventFacade} event
  1010. * @protected
  1011. */
  1012. _uiSetDisabled: function(disabled) {
  1013. var instance = this;
  1014. DatePickerSelect.superclass._uiSetDisabled.apply(instance, arguments);
  1015. instance.get(DAY_NODE).set('disabled', disabled);
  1016. instance.get(MONTH_NODE).set('disabled', disabled);
  1017. instance.get(YEAR_NODE).set('disabled', disabled);
  1018. instance.datePicker.set(DISABLED, disabled);
  1019. instance._buttonItem.set(DISABLED, disabled);
  1020. instance._buttonItem.StateInteraction.set(DISABLED, disabled);
  1021. }
  1022. }
  1023. }
  1024. );
  1025. A.DatePickerSelect = DatePickerSelect;
  1026. }, '@VERSION@' ,{requires:['aui-datepicker-base','aui-button-item'], skinnable:true});
  1027. AUI.add('aui-datepicker', function(A){}, '@VERSION@' ,{skinnable:true, use:['aui-datepicker-base','aui-datepicker-select']});