PageRenderTime 37ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/site-source/js/Uize/Widget/Picker.js

http://github.com/UIZE/UIZE-JavaScript-Framework
JavaScript | 230 lines | 138 code | 23 blank | 69 comment | 13 complexity | 06fee37d7e9f1a59ea257051087325b7 MD5 | raw file
Possible License(s): GPL-3.0
  1. /*______________
  2. | ______ | U I Z E J A V A S C R I P T F R A M E W O R K
  3. | / / | ---------------------------------------------------
  4. | / O / | MODULE : Uize.Widget.Picker Class
  5. | / / / |
  6. | / / / /| | ONLINE : http://www.uize.com
  7. | /____/ /__/_| | COPYRIGHT : (c)2009-2016 UIZE
  8. | /___ | LICENSE : Available under MIT License or GNU General Public License
  9. |_______________| http://www.uize.com/license.html
  10. */
  11. /* Module Meta Data
  12. type: Class
  13. importance: 6
  14. codeCompleteness: 100
  15. docCompleteness: 7
  16. */
  17. /*?
  18. Introduction
  19. The =Uize.Widget.Picker= class acts as a base class for value picker widget classes, such as the =Uize.Widget.Picker.Date= class.
  20. *DEVELOPERS:* `Chris van Rensburg`, `Ben Ilegbodu`
  21. ### In a Nutshell
  22. - deferred loading of picker dialog, including loading of JavaScript modules, building and insertion of HTML markup for widget, and wiring up of picker dialog widget, so that many picker instances can be created on a page without adding siginificant load to the page.
  23. - dialog is moored to =selector= button's root node, with =offsetX= and =offsetY= values that are half the width and height of the selector button's root node, respectively, so that the top left corner of the diaog should be positioned by the center of the selector button.
  24. - picker dialog is shared among multiple picker instances
  25. - when the picker dialog is launched, the values of the piped properties are relayed to the picker dialog widget, which are in turn piped through to the counterpart properties of the picker widget, allowing multiple =Uize.Widget.Picker= instances to share the same dialog widget. Whenever the dialog is launched for a specific picker instance, the dialog's state is synchronized to the state of the picker instance.
  26. - widget class for dialog is configurable. This allows a subclass specific to your own Web application to be used, which is likely to be a subclass of =Uize.Widget.Dialog.Picker=
  27. */
  28. Uize.module ({
  29. name:'Uize.Widget.Picker',
  30. superclass:'Uize.Widget.FormElement',
  31. required:[
  32. 'Uize.Widget.Button.ValueDisplay',
  33. 'Uize.Dom.Pos',
  34. 'Uize.Dom.Event'
  35. ],
  36. builder:function (_superclass) {
  37. 'use strict';
  38. var
  39. /*** Variables for Scruncher Optimization ***/
  40. _null = null
  41. ;
  42. return _superclass.subclass ({
  43. omegastructor:function () {
  44. var
  45. m = this,
  46. _pickValue = function () { m.pickValue() }
  47. ;
  48. /*** watch focus by user ***/
  49. m.wire (
  50. 'Changed.focused',
  51. function () { m.get('focused') && !m._allowManualEntry && _pickValue () }
  52. );
  53. /*** add selector button */
  54. m.addChild (
  55. 'selector',
  56. m._selectorButtonWidgetClass || Uize.Widget.Button.ValueDisplay,
  57. m._selectorButtonWidgetProperties
  58. ).wire ('Click',_pickValue);
  59. /*?
  60. Child Widgets
  61. selector
  62. .
  63. */
  64. },
  65. instanceMethods:{
  66. getDialogWidgetProperties:function () { return _null },
  67. getMoreDialogEventHandlers:function () { return _null },
  68. getMooringNode:function () {
  69. return this.children.selector.getNode () || this.getNode ('input');
  70. },
  71. handleDialogSubmit:function (_valueInfo) {
  72. var
  73. m = this,
  74. _value = _valueInfo.value,
  75. _valueDetails = _valueInfo.valueDetails,
  76. _undefined
  77. ;
  78. m.set(
  79. Uize.copy(
  80. _valueDetails !== _undefined ? {valueDetails:_valueDetails} : _undefined,
  81. _value !== _undefined
  82. ? ({
  83. value:_value != _null
  84. ? (m._valueFormatter ? m._valueFormatter.call (m,_value) : _value)
  85. : ''
  86. }) : _undefined
  87. )
  88. );
  89. },
  90. pickValue:function () {
  91. var m = this;
  92. m.set({focused:false});
  93. var
  94. _mooringNode = m.getMooringNode(),
  95. _mooringNodeDims = Uize.Dom.Pos.getDimensions (_mooringNode)
  96. ;
  97. function _possiblyFocus () {
  98. m._allowManualEntry && m.set({focused:true});
  99. }
  100. m.callInherited ('useDialog') ({
  101. component:m._dialogComponent
  102. ? Uize.copyInto(m._dialogComponent, {value:m.get('value')})
  103. : _null,
  104. widgetClassName:m._dialogWidgetClass,
  105. widgetProperties:
  106. Uize.copyInto (
  107. {
  108. name:m._dialogName || 'dialog' + m._dialogWidgetClass.replace (/\./g,''),
  109. picker:m,
  110. mooringNode:_mooringNode,
  111. offsetX:_mooringNodeDims.width >> 1,
  112. offsetY: _mooringNodeDims.height >> 1,
  113. preventPageScrollWhenShown: m._dialogPreventScrollWhenShown
  114. },
  115. m.getDialogWidgetProperties(),
  116. m.get ((m._pipedProperties || []).concat ('value', 'valueDetails'))
  117. ),
  118. submitHandler:function (_valueInfo,_event) {
  119. m.handleDialogSubmit(_valueInfo);
  120. _event && _event.keepOpen || _possiblyFocus ();
  121. },
  122. dismissHandler:_possiblyFocus,
  123. widgetEventHandlers:m.getMoreDialogEventHandlers()
  124. });
  125. },
  126. wireUi:function () {
  127. var m = this;
  128. if (!m.isWired) {
  129. m.wireNode (
  130. 'input',
  131. 'mousedown',
  132. function (_event) {
  133. if (!m._allowManualEntry) {
  134. Uize.Dom.Event.abort (_event);
  135. m.pickValue ();
  136. }
  137. }
  138. );
  139. _superclass.doMy (m,'wireUi');
  140. }
  141. }
  142. },
  143. stateProperties:{
  144. _allowManualEntry:{
  145. name:'allowManualEntry',
  146. value:true
  147. /*?
  148. State Properties
  149. allowManualEntry
  150. .
  151. NOTES
  152. - the initial value is =true=
  153. */
  154. },
  155. _dialogComponent:'dialogComponent',
  156. _dialogName:'dialogName',
  157. _dialogWidgetClass:'dialogWidgetClass',
  158. /*?
  159. State Properties
  160. dialogWidgetClass
  161. .
  162. NOTES
  163. - the initial value is =undefined=
  164. */
  165. _dialogPreventScrollWhenShown: {
  166. name: 'dialogPreventScrollWhenShown',
  167. value: false
  168. },
  169. _pipedProperties:'pipedProperties',
  170. /*?
  171. State Properties
  172. pipedProperties
  173. .
  174. NOTES
  175. - the initial value is =undefined=
  176. */
  177. _selectorButtonWidgetClass:'selectorButtonWidgetClass',
  178. _selectorButtonWidgetProperties:'selectorButtonWidgetProperties',
  179. _valueDetails:{
  180. name:'valueDetails',
  181. onChange:function () {
  182. var _selector = this.children.selector;
  183. _selector
  184. && _selector.set({valueDetails:this._valueDetails});
  185. }
  186. },
  187. _valueFormatter:'valueFormatter'
  188. /*?
  189. State Properties
  190. valueFormatter
  191. .
  192. NOTES
  193. - the initial value is =undefined=
  194. */
  195. },
  196. set:{
  197. value:_null
  198. }
  199. });
  200. }
  201. });