Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

slider-value-range-debug.js 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /*
  2. Copyright (c) 2010, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.com/yui/license.html
  5. version: 3.4.0
  6. build: nightly
  7. */
  8. YUI.add('slider-value-range', function(Y) {
  9. /**
  10. * Adds value support for Slider as a range of integers between a configured
  11. * minimum and maximum value. For use with <code>Y.Base.build(..)</code> to
  12. * add the plumbing to <code>Y.SliderBase</code>.
  13. *
  14. * @module slider
  15. * @submodule slider-value-range
  16. */
  17. // Constants for compression or performance
  18. var MIN = 'min',
  19. MAX = 'max',
  20. VALUE = 'value',
  21. round = Math.round;
  22. /**
  23. * One class of value algorithm that can be built onto SliderBase. By default,
  24. * values range between 0 and 100, but you can configure these on the
  25. * built Slider class by setting the <code>min</code> and <code>max</code>
  26. * configurations. Set the initial value (will cause the thumb to move to the
  27. * appropriate location on the rail) in configuration as well if appropriate.
  28. *
  29. * @class SliderValueRange
  30. */
  31. function SliderValueRange() {
  32. this._initSliderValueRange();
  33. }
  34. Y.SliderValueRange = Y.mix( SliderValueRange, {
  35. // Prototype properties and methods that will be added onto host class
  36. prototype: {
  37. /**
  38. * Factor used to translate value -&gt; position -&gt; value.
  39. *
  40. * @property _factor
  41. * @type {Number}
  42. * @protected
  43. */
  44. _factor: 1,
  45. /**
  46. * Stub for construction logic. Override if extending this class and
  47. * you need to set something up during the initializer phase.
  48. *
  49. * @method _initSliderValueRange
  50. * @protected
  51. */
  52. _initSliderValueRange: function () {},
  53. /**
  54. * Override of stub method in SliderBase that is called at the end of
  55. * its bindUI stage of render(). Subscribes to internal events to
  56. * trigger UI and related state updates.
  57. *
  58. * @method _bindValueLogic
  59. * @protected
  60. */
  61. _bindValueLogic: function () {
  62. this.after( {
  63. minChange : this._afterMinChange,
  64. maxChange : this._afterMaxChange,
  65. valueChange: this._afterValueChange
  66. } );
  67. },
  68. /**
  69. * Move the thumb to appropriate position if necessary. Also resets
  70. * the cached offsets and recalculates the conversion factor to
  71. * translate position to value.
  72. *
  73. * @method _syncThumbPosition
  74. * @protected
  75. */
  76. _syncThumbPosition: function () {
  77. this._calculateFactor();
  78. this._setPosition( this.get( VALUE ) );
  79. },
  80. /**
  81. * Calculates and caches
  82. * (range between max and min) / (rail length)
  83. * for fast runtime calculation of position -&gt; value.
  84. *
  85. * @method _calculateFactor
  86. * @protected
  87. */
  88. _calculateFactor: function () {
  89. var length = this.get( 'length' ),
  90. thumbSize = this.thumb.getStyle( this._key.dim ),
  91. min = this.get( MIN ),
  92. max = this.get( MAX );
  93. // The default thumb width is based on Sam skin's thumb dimension.
  94. // This attempts to allow for rendering off-DOM, then attaching
  95. // without the need to call syncUI(). It is still recommended
  96. // to call syncUI() in these cases though, just to be sure.
  97. length = parseFloat( length ) || 150;
  98. thumbSize = parseFloat( thumbSize ) || 15;
  99. this._factor = ( max - min ) / ( length - thumbSize );
  100. Y.log("Calculating factor(~" + this._factor.toFixed(3) + " = (max(" + max + ") - min(" + min + ")) / (length(" + length + ") - thumb size(" + thumbSize + "))","info","slider");
  101. },
  102. /**
  103. * Dispatch the new position of the thumb into the value setting
  104. * operations.
  105. *
  106. * @method _defThumbMoveFn
  107. * @param e { EventFacade } The host's thumbMove event
  108. * @protected
  109. */
  110. _defThumbMoveFn: function ( e ) {
  111. var previous = this.get( VALUE ),
  112. value = this._offsetToValue( e.offset );
  113. // This test avoids duplication of this.set(..) if the origin
  114. // of this thumbMove is from slider.set('value',x);
  115. // slider.set() -> afterValueChange -> uiMoveThumb ->
  116. // fire(thumbMove) -> _defThumbMoveFn -> this.set()
  117. if ( previous !== value ) {
  118. this.set( VALUE, value, { positioned: true } );
  119. }
  120. },
  121. /**
  122. * <p>Converts a pixel position into a value. Calculates current
  123. * thumb offset from the leading edge of the rail multiplied by the
  124. * ratio of <code>(max - min) / (constraining dim)</code>.</p>
  125. *
  126. * <p>Override this if you want to use a different value mapping
  127. * algorithm.</p>
  128. *
  129. * @method _offsetToValue
  130. * @param offset { Number } X or Y pixel offset
  131. * @return { mixed } Value corresponding to the provided pixel offset
  132. * @protected
  133. */
  134. _offsetToValue: function ( offset ) {
  135. var value = round( offset * this._factor ) + this.get( MIN );
  136. Y.log("Offset: " + offset + " => Value: " + value, "info", "slider");
  137. return round( this._nearestValue( value ) );
  138. },
  139. /**
  140. * Converts a value into a pixel offset for use in positioning
  141. * the thumb according to the reverse of the
  142. * <code>_offsetToValue( xy )</code> operation.
  143. *
  144. * @method _valueToOffset
  145. * @param val { Number } The value to map to pixel X or Y position
  146. * @return { Number } The pixel offset
  147. * @protected
  148. */
  149. _valueToOffset: function ( value ) {
  150. var offset = round( ( value - this.get( MIN ) ) / this._factor );
  151. Y.log("Value: " + value + " => Offset: " + offset, "info", "slider");
  152. return offset;
  153. },
  154. /**
  155. * Returns the current value. Override this if you want to introduce
  156. * output formatting. Otherwise equivalent to slider.get( "value" );
  157. *
  158. * @method getValue
  159. * @return {Number}
  160. */
  161. getValue: function () {
  162. return this.get( VALUE );
  163. },
  164. /**
  165. * Updates the current value. Override this if you want to introduce
  166. * input value parsing or preprocessing. Otherwise equivalent to
  167. * slider.set( "value", v );
  168. *
  169. * @method setValue
  170. * @param val {Number} The new value
  171. * @return {Slider}
  172. * @chainable
  173. */
  174. setValue: function ( val ) {
  175. return this.set( VALUE, val );
  176. },
  177. /**
  178. * Update position according to new min value. If the new min results
  179. * in the current value being out of range, the value is set to the
  180. * closer of min or max.
  181. *
  182. * @method _afterMinChange
  183. * @param e { EventFacade } The <code>min</code> attribute change event.
  184. * @protected
  185. */
  186. _afterMinChange: function ( e ) {
  187. this._verifyValue();
  188. this._syncThumbPosition();
  189. },
  190. /**
  191. * Update position according to new max value. If the new max results
  192. * in the current value being out of range, the value is set to the
  193. * closer of min or max.
  194. *
  195. * @method _afterMaxChange
  196. * @param e { EventFacade } The <code>max</code> attribute change event.
  197. * @protected
  198. */
  199. _afterMaxChange: function ( e ) {
  200. this._verifyValue();
  201. this._syncThumbPosition();
  202. },
  203. /**
  204. * Verifies that the current value is within the min - max range. If
  205. * not, value is set to either min or max, depending on which is
  206. * closer.
  207. *
  208. * @method _verifyValue
  209. * @protected
  210. */
  211. _verifyValue: function () {
  212. var value = this.get( VALUE ),
  213. nearest = this._nearestValue( value );
  214. if ( value !== nearest ) {
  215. // @TODO Can/should valueChange, minChange, etc be queued
  216. // events? To make dd.set( 'min', n ); execute after minChange
  217. // subscribers before on/after valueChange subscribers.
  218. this.set( VALUE, nearest );
  219. }
  220. },
  221. /**
  222. * Propagate change to the thumb position unless the change originated
  223. * from the thumbMove event.
  224. *
  225. * @method _afterValueChange
  226. * @param e { EventFacade } The <code>valueChange</code> event.
  227. * @protected
  228. */
  229. _afterValueChange: function ( e ) {
  230. if ( !e.positioned ) {
  231. Y.log("Positioning thumb after set('value',x)","info","slider");
  232. this._setPosition( e.newVal );
  233. }
  234. },
  235. /**
  236. * Positions the thumb in accordance with the translated value.
  237. *
  238. * @method _setPosition
  239. * @protected
  240. */
  241. _setPosition: function ( value ) {
  242. this._uiMoveThumb( this._valueToOffset( value ) );
  243. },
  244. /**
  245. * Validates new values assigned to <code>min</code> attribute. Numbers
  246. * are acceptable. Override this to enforce different rules.
  247. *
  248. * @method _validateNewMin
  249. * @param value { mixed } Value assigned to <code>min</code> attribute.
  250. * @return { Boolean } True for numbers. False otherwise.
  251. * @protected
  252. */
  253. _validateNewMin: function ( value ) {
  254. return Y.Lang.isNumber( value );
  255. },
  256. /**
  257. * Validates new values assigned to <code>max</code> attribute. Numbers
  258. * are acceptable. Override this to enforce different rules.
  259. *
  260. * @method _validateNewMax
  261. * @param value { mixed } Value assigned to <code>max</code> attribute.
  262. * @return { Boolean } True for numbers. False otherwise.
  263. * @protected
  264. */
  265. _validateNewMax: function ( value ) {
  266. return Y.Lang.isNumber( value );
  267. },
  268. /**
  269. * Restricts new values assigned to <code>value</code> attribute to be
  270. * between the configured <code>min</code> and <code>max</code>.
  271. * Rounds to nearest integer value.
  272. *
  273. * @method _setNewValue
  274. * @param value { Number } Value assigned to <code>value</code> attribute
  275. * @return { Number } Normalized and constrained value
  276. * @protected
  277. */
  278. _setNewValue: function ( value ) {
  279. return round( this._nearestValue( value ) );
  280. },
  281. /**
  282. * Returns the nearest valid value to the value input. If the provided
  283. * value is outside the min - max range, accounting for min > max
  284. * scenarios, the nearest of either min or max is returned. Otherwise,
  285. * the provided value is returned.
  286. *
  287. * @method _nearestValue
  288. * @param value { mixed } Value to test against current min - max range
  289. * @return { Number } Current min, max, or value if within range
  290. * @protected
  291. */
  292. _nearestValue: function ( value ) {
  293. var min = this.get( MIN ),
  294. max = this.get( MAX ),
  295. tmp;
  296. // Account for reverse value range (min > max)
  297. tmp = ( max > min ) ? max : min;
  298. min = ( max > min ) ? min : max;
  299. max = tmp;
  300. return ( value < min ) ?
  301. min :
  302. ( value > max ) ?
  303. max :
  304. value;
  305. }
  306. },
  307. /**
  308. * Attributes that will be added onto host class.
  309. *
  310. * @property ATTRS
  311. * @type {Object}
  312. * @static
  313. * @protected
  314. */
  315. ATTRS: {
  316. /**
  317. * The value associated with the farthest top, left position of the
  318. * rail. Can be greater than the configured <code>max</code> if you
  319. * want values to increase from right-to-left or bottom-to-top.
  320. *
  321. * @attribute min
  322. * @type { Number }
  323. * @default 0
  324. */
  325. min: {
  326. value : 0,
  327. validator: '_validateNewMin'
  328. },
  329. /**
  330. * The value associated with the farthest bottom, right position of
  331. * the rail. Can be less than the configured <code>min</code> if
  332. * you want values to increase from right-to-left or bottom-to-top.
  333. *
  334. * @attribute max
  335. * @type { Number }
  336. * @default 100
  337. */
  338. max: {
  339. value : 100,
  340. validator: '_validateNewMax'
  341. },
  342. /**
  343. * The value associated with the thumb's current position on the
  344. * rail. Defaults to the value inferred from the thumb's current
  345. * position. Specifying value in the constructor will move the
  346. * thumb to the position that corresponds to the supplied value.
  347. *
  348. * @attribute value
  349. * @type { Number }
  350. * @default (inferred from current thumb position)
  351. */
  352. value: {
  353. value : 0,
  354. setter: '_setNewValue'
  355. }
  356. }
  357. }, true );
  358. }, '3.4.0' ,{requires:['slider-base']});