ui_alchemy-rails 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +6 -0
  3. data/Rakefile +21 -0
  4. data/app/assets/fonts/alchemy/LiberationSans-Bold-webfont.eot +0 -0
  5. data/app/assets/fonts/alchemy/LiberationSans-Bold-webfont.svg +154 -0
  6. data/app/assets/fonts/alchemy/LiberationSans-Bold-webfont.ttf +0 -0
  7. data/app/assets/fonts/alchemy/LiberationSans-Bold-webfont.woff +0 -0
  8. data/app/assets/fonts/alchemy/LiberationSans-BoldItalic-webfont.eot +0 -0
  9. data/app/assets/fonts/alchemy/LiberationSans-BoldItalic-webfont.svg +154 -0
  10. data/app/assets/fonts/alchemy/LiberationSans-BoldItalic-webfont.ttf +0 -0
  11. data/app/assets/fonts/alchemy/LiberationSans-BoldItalic-webfont.woff +0 -0
  12. data/app/assets/fonts/alchemy/LiberationSans-Italic-webfont.eot +0 -0
  13. data/app/assets/fonts/alchemy/LiberationSans-Italic-webfont.svg +154 -0
  14. data/app/assets/fonts/alchemy/LiberationSans-Italic-webfont.ttf +0 -0
  15. data/app/assets/fonts/alchemy/LiberationSans-Italic-webfont.woff +0 -0
  16. data/app/assets/fonts/alchemy/LiberationSans-Regular-webfont.eot +0 -0
  17. data/app/assets/fonts/alchemy/LiberationSans-Regular-webfont.svg +154 -0
  18. data/app/assets/fonts/alchemy/LiberationSans-Regular-webfont.ttf +0 -0
  19. data/app/assets/fonts/alchemy/LiberationSans-Regular-webfont.woff +0 -0
  20. data/app/assets/fonts/alchemy/Red Hat Liberation License.txt +78 -0
  21. data/app/assets/fonts/alchemy/overpass_bold-web.eot +0 -0
  22. data/app/assets/fonts/alchemy/overpass_bold-web.svg +470 -0
  23. data/app/assets/fonts/alchemy/overpass_bold-web.ttf +0 -0
  24. data/app/assets/fonts/alchemy/overpass_bold-web.woff +0 -0
  25. data/app/assets/fonts/alchemy/overpass_regular-web.eot +0 -0
  26. data/app/assets/fonts/alchemy/overpass_regular-web.svg +470 -0
  27. data/app/assets/fonts/alchemy/overpass_regular-web.ttf +0 -0
  28. data/app/assets/fonts/alchemy/overpass_regular-web.woff +0 -0
  29. data/app/assets/images/alchemy/icons/action-icons.png +0 -0
  30. data/app/assets/images/alchemy/icons/arrow_icon.png +0 -0
  31. data/app/assets/images/alchemy/icons/chosen-sprite.png +0 -0
  32. data/app/assets/images/alchemy/icons/error_icon.png +0 -0
  33. data/app/assets/images/alchemy/icons/objects.png +0 -0
  34. data/app/assets/images/alchemy/icons/spinner.gif +0 -0
  35. data/app/assets/images/alchemy/icons/spinner_head.gif +0 -0
  36. data/app/assets/images/alchemy/icons/success_icon.png +0 -0
  37. data/app/assets/images/alchemy/icons/warning_icon.png +0 -0
  38. data/app/assets/javascripts/alchemy/flash_messages.js +12 -0
  39. data/app/assets/javascripts/alchemy/forms.js +25 -0
  40. data/app/assets/javascripts/alchemy/i18n.js +36 -0
  41. data/app/assets/javascripts/alchemy/login.js +130 -0
  42. data/app/assets/javascripts/alchemy/password.js +99 -0
  43. data/app/assets/stylesheets/alchemy/components/_chosen.scss +423 -0
  44. data/app/assets/stylesheets/alchemy/components/_content.scss +58 -0
  45. data/app/assets/stylesheets/alchemy/components/_helpers.scss +38 -0
  46. data/app/assets/stylesheets/alchemy/components/_media.scss +49 -0
  47. data/app/assets/stylesheets/alchemy/components/_media_object.scss +22 -0
  48. data/app/assets/stylesheets/alchemy/components/_normalize.scss +396 -0
  49. data/app/assets/stylesheets/alchemy/components/_shared.scss +18 -0
  50. data/app/assets/stylesheets/alchemy/components/buttons/_buttons.scss +278 -0
  51. data/app/assets/stylesheets/alchemy/components/buttons/_buttons_vars.scss +11 -0
  52. data/app/assets/stylesheets/alchemy/components/flash_messages/_flash_messages.scss +93 -0
  53. data/app/assets/stylesheets/alchemy/components/flash_messages/_flash_messages_vars.scss +3 -0
  54. data/app/assets/stylesheets/alchemy/components/fonts/_liberation.scss +44 -0
  55. data/app/assets/stylesheets/alchemy/components/fonts/_overpass.scss +24 -0
  56. data/app/assets/stylesheets/alchemy/components/footer/_footer.scss +53 -0
  57. data/app/assets/stylesheets/alchemy/components/footer/_footer_vars.scss +4 -0
  58. data/app/assets/stylesheets/alchemy/components/forms/_forms.scss +552 -0
  59. data/app/assets/stylesheets/alchemy/components/forms/_forms_ie.scss +45 -0
  60. data/app/assets/stylesheets/alchemy/components/forms/_forms_mixins.scss +18 -0
  61. data/app/assets/stylesheets/alchemy/components/forms/_forms_responsive.scss +167 -0
  62. data/app/assets/stylesheets/alchemy/components/forms/_forms_vars.scss +25 -0
  63. data/app/assets/stylesheets/alchemy/components/header/_header.scss +216 -0
  64. data/app/assets/stylesheets/alchemy/components/header/_header_vars.scss +11 -0
  65. data/app/assets/stylesheets/alchemy/components/login/_login.scss +173 -0
  66. data/app/assets/stylesheets/alchemy/components/login/_login_mixins.scss +7 -0
  67. data/app/assets/stylesheets/alchemy/components/login/_login_vars.scss +19 -0
  68. data/app/assets/stylesheets/alchemy/components/sprites/_sprites.scss +110 -0
  69. data/app/assets/stylesheets/alchemy/components/sprites/_sprites_mixins.scss +9 -0
  70. data/app/assets/stylesheets/alchemy/components/text/_text.scss +30 -0
  71. data/app/assets/stylesheets/alchemy/components/text/_text_vars.scss +1 -0
  72. data/app/assets/stylesheets/alchemy/composites/content_elements.scss +6 -0
  73. data/app/assets/stylesheets/alchemy/composites/login.scss +9 -0
  74. data/app/assets/stylesheets/alchemy/composites/shell.scss +4 -0
  75. data/app/assets/stylesheets/alchemy/partials/_base.scss +8 -0
  76. data/app/assets/stylesheets/alchemy/partials/_colors.scss +99 -0
  77. data/app/assets/stylesheets/alchemy/partials/_mixins.scss +24 -0
  78. data/app/assets/stylesheets/alchemy/partials/_vars.scss +31 -0
  79. data/app/helpers/ui_alchemy/gettext_translations.rb +28 -0
  80. data/app/helpers/ui_alchemy/layout_helper.rb +35 -0
  81. data/app/helpers/ui_alchemy/rails_translations.rb +21 -0
  82. data/app/helpers/ui_alchemy/translation_helper.rb +19 -0
  83. data/app/views/alchemy/layouts/_change_password_layout.html.haml +20 -0
  84. data/app/views/alchemy/layouts/_common_i18n.haml +4 -0
  85. data/app/views/alchemy/layouts/_header_layout.haml +13 -0
  86. data/app/views/alchemy/layouts/_login_layout.html.haml +58 -0
  87. data/app/views/alchemy/layouts/_user_session_layout.haml +17 -0
  88. data/app/views/alchemy/layouts/base.html.haml +20 -0
  89. data/app/views/alchemy/layouts/shell_layout.haml +10 -0
  90. data/lib/ui_alchemy/rails/engine.rb +6 -0
  91. data/lib/ui_alchemy/rails/version.rb +5 -0
  92. data/lib/ui_alchemy-rails.rb +2 -0
  93. data/vendor/assets/javascripts/alchemy/handlebars.js +2201 -0
  94. data/vendor/assets/javascripts/alchemy/html5shiv.js +298 -0
  95. data/vendor/assets/javascripts/alchemy/jquery/jquery-1.6.2.js +8981 -0
  96. data/vendor/assets/javascripts/alchemy/jquery/plugins/chosen.jquery.js +1003 -0
  97. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/excanvas.js +1427 -0
  98. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/excanvas.min.js +1 -0
  99. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.colorhelpers.js +179 -0
  100. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.colorhelpers.min.js +1 -0
  101. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.crosshair.js +167 -0
  102. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.crosshair.min.js +1 -0
  103. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.fillbetween.js +183 -0
  104. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.fillbetween.min.js +1 -0
  105. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.image.js +238 -0
  106. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.image.min.js +1 -0
  107. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.js +2599 -0
  108. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.min.js +6 -0
  109. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.navigate.js +336 -0
  110. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.navigate.min.js +1 -0
  111. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.pie.js +750 -0
  112. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.pie.min.js +1 -0
  113. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.resize.js +60 -0
  114. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.resize.min.js +1 -0
  115. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.selection.js +344 -0
  116. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.selection.min.js +1 -0
  117. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.stack.js +184 -0
  118. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.stack.min.js +1 -0
  119. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.symbol.js +70 -0
  120. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.symbol.min.js +1 -0
  121. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.threshold.js +103 -0
  122. data/vendor/assets/javascripts/alchemy/jquery/plugins/flot-0.7/jquery.flot.threshold.min.js +1 -0
  123. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/blank.svg +3 -0
  124. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/custom_test.js +67 -0
  125. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/jquery.svg.css +9 -0
  126. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/jquery.svg.js +1101 -0
  127. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/jquery.svg.min.js +7 -0
  128. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/jquery.svg.pack.js +7 -0
  129. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/jquery.svgfilter.js +396 -0
  130. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/jquery.svgfilter.min.js +7 -0
  131. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/jquery.svgfilter.pack.js +7 -0
  132. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/jquery.svggraph.js +1337 -0
  133. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/jquery.svggraph.min.js +7 -0
  134. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/jquery.svggraph.pack.js +7 -0
  135. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/lion.svg +161 -0
  136. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery-svg/test.js +714 -0
  137. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.ajaxfileupload.js +205 -0
  138. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.ba-bbq.js +1137 -0
  139. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.ba-resize.js +246 -0
  140. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.cookie.js +92 -0
  141. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.easing.1.3.js +205 -0
  142. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.fancyqueries.js +106 -0
  143. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.flash.js +288 -0
  144. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.form.js +964 -0
  145. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.hoverIntent.js +106 -0
  146. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.jeditable.ajaxupload.js +62 -0
  147. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.jeditable.js +556 -0
  148. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.jnotify.js +210 -0
  149. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.jscrollpane.js +1390 -0
  150. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.jscrollpane.min.js +11 -0
  151. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.linkHover.js +89 -0
  152. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.loadmask.min.js +10 -0
  153. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.mousewheel.js +78 -0
  154. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.multiselect.filter.js +176 -0
  155. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.multiselect.js +668 -0
  156. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.pack.js +11 -0
  157. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.periodicalupdater.js +175 -0
  158. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.sortElements.js +75 -0
  159. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.sparkline.min.js +94 -0
  160. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.text-overflow.js +60 -0
  161. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.timepickr.js +214 -0
  162. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.timers.js +142 -0
  163. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.tipsy.js +358 -0
  164. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.treeTable.js +226 -0
  165. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.trunk8.js +203 -0
  166. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.ui.multiselect.js +338 -0
  167. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.ui.totop.js +58 -0
  168. data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.uitablefilter.js +95 -0
  169. data/vendor/assets/javascripts/alchemy/jquery/plugins/ui.spinner.js +683 -0
  170. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  171. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  172. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-bg_highlight-hard_75_dadada_1x100.png +0 -0
  173. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-bg_highlight-hard_75_e6e6e6_1x100.png +0 -0
  174. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-bg_highlight-hard_95_ffffff_1x100.png +0 -0
  175. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-bg_highlight-soft_80_e0e0e0_1x100.png +0 -0
  176. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-bg_inset-hard_65_ffffff_1x100.png +0 -0
  177. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-bg_inset-soft_95_fef1ec_1x100.png +0 -0
  178. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-icons_8f8f8f_256x240.png +0 -0
  179. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-icons_97baed_256x240.png +0 -0
  180. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/images/ui-icons_cd0a0a_256x240.png +0 -0
  181. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/css/custom-theme/jquery-ui-1.8.11.custom.css +573 -0
  182. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/js/jquery-1.5.1.min.js +16 -0
  183. data/vendor/assets/javascripts/alchemy/jquery-ui-1.8.11.custom/js/jquery-ui-1.8.11.custom.min.js +783 -0
  184. data/vendor/assets/javascripts/alchemy/rails.js +331 -0
  185. data/vendor/assets/javascripts/alchemy/underscore-1.3.1.js +999 -0
  186. metadata +252 -0
@@ -0,0 +1,683 @@
1
+ /**
2
+ * @license jQuery UI Spinner 1.20
3
+ *
4
+ * Copyright (c) 2009-2010 Brant Burnett
5
+ * Dual licensed under the MIT or GPL Version 2 licenses.
6
+ */
7
+ (function($, undefined) {
8
+
9
+ var
10
+ // constants
11
+ active = 'ui-state-active',
12
+ hover = 'ui-state-hover',
13
+ disabled = 'ui-state-disabled',
14
+
15
+ keyCode = $.ui.keyCode,
16
+ up = keyCode.UP,
17
+ down = keyCode.DOWN,
18
+ right = keyCode.RIGHT,
19
+ left = keyCode.LEFT,
20
+ pageUp = keyCode.PAGE_UP,
21
+ pageDown = keyCode.PAGE_DOWN,
22
+ home = keyCode.HOME,
23
+ end = keyCode.END,
24
+
25
+ msie = $.browser.msie,
26
+ mouseWheelEventName = $.browser.mozilla ? 'DOMMouseScroll' : 'mousewheel',
27
+
28
+ // namespace for events on input
29
+ eventNamespace = '.uispinner',
30
+
31
+ // only these special keys will be accepted, all others will be ignored unless CTRL or ALT are pressed
32
+ validKeys = [up, down, right, left, pageUp, pageDown, home, end, keyCode.BACKSPACE, keyCode.DELETE, keyCode.TAB],
33
+
34
+ // stores the currently focused spinner
35
+ // Note: due to oddities in the focus/blur events, this is part of a two-part system for confirming focus
36
+ // this must set to the control, and the focus variable must be true
37
+ // this is because hitting up/down arrows with mouse causes focus to change, but blur event for previous control doesn't fire
38
+ focusCtrl;
39
+
40
+ $.widget('ui.spinner', {
41
+ options: {
42
+ min: null,
43
+ max: null,
44
+ allowNull: false,
45
+
46
+ group: '',
47
+ point: '.',
48
+ prefix: '',
49
+ suffix: '',
50
+ places: null, // null causes it to detect the number of places in step, 'free' will let the user enters decimals as he wants
51
+
52
+ defaultStep: 1, // real value is 'step', and should be passed as such. This value is used to detect if passed value should override HTML5 attribute
53
+ largeStep: 10,
54
+ mouseWheel: true,
55
+ increment: 'slow',
56
+ className: null,
57
+ showOn: 'always',
58
+ width: 16,
59
+ upIconClass: "ui-icon-triangle-1-n",
60
+ downIconClass: "ui-icon-triangle-1-s",
61
+
62
+ format: function(num, places) {
63
+ var options = this,
64
+ regex = /(\d+)(\d{3})/;
65
+ var result;
66
+ if ('free' == places)
67
+ result = (isNaN(num) ? 0 : Math.abs(num)) + '';
68
+ else
69
+ result = ((isNaN(num) ? 0 : Math.abs(num)).toFixed(places)) + '';
70
+
71
+ for (result = result.replace('.', options.point); regex.test(result) && options.group; result=result.replace(regex, '$1'+options.group+'$2')) {};
72
+ return (num < 0 ? '-' : '') + options.prefix + result + options.suffix;
73
+ },
74
+
75
+ parse: function(val) {
76
+ var options = this;
77
+
78
+ if (options.group == '.')
79
+ val = val.replace('.', '');
80
+ if (options.point != '.')
81
+ val = val.replace(options.point, '.');
82
+ return parseFloat(val.replace(/[^0-9\-\.]/g, ''));
83
+ }
84
+ },
85
+
86
+ // * Widget fields *
87
+ // curvalue - current value
88
+ // places - currently effective number of decimal places
89
+ // oWidth - original input width (used for destroy)
90
+ // oMargin - original input right margin (used for destroy)
91
+ // counter - number of spins at the current spin speed
92
+ // incCounter - index within options.increment of the current spin speed
93
+ // selfChange - indicates that change event is being fired by the widget, so don't reprocess input value
94
+ // inputMaxLength - initial maxLength value on the input
95
+ // focused - this spinner currently has the focus
96
+
97
+ _create: function() {
98
+ // shortcuts
99
+ var self = this,
100
+ input = self.element,
101
+ type = input.attr('type');
102
+
103
+ if (!input.is('input') || ((type != 'text') && (type != 'number'))) {
104
+ console.error('Invalid target for ui.spinner');
105
+ return;
106
+ }
107
+
108
+ self._procOptions(true);
109
+ self._createButtons(input);
110
+
111
+ if (!input.is(':enabled'))
112
+ self.disable();
113
+ },
114
+
115
+ _createButtons: function(input) {
116
+ function getMargin(margin) {
117
+ // IE8 returns auto if no margin specified
118
+ return margin == 'auto' ? 0 : parseInt(margin);
119
+ }
120
+
121
+ var self = this,
122
+ options = self.options,
123
+ className = options.className,
124
+ buttonWidth = options.width,
125
+ showOn = options.showOn,
126
+ box = $.support.boxModel,
127
+ height = input.outerHeight(),
128
+ rightMargin = self.oMargin = getMargin(input.css('margin-right')); // store original width and right margin for later destroy
129
+ input.css({ textAlign: 'right' });
130
+ if (showOn != 'never') {
131
+ wrapper = self.wrapper = input.css({ width: (self.oWidth = (box ? input.width() : input.outerWidth())) - buttonWidth,
132
+ marginRight: rightMargin + buttonWidth})
133
+ .after('<span class="ui-spinner ui-widget"></span>').next(),
134
+ btnContainer = self.btnContainer = $(
135
+ '<div class="ui-spinner-buttons">' +
136
+ '<div class="ui-spinner-up ui-spinner-button ui-state-default ui-corner-tr"><span class="ui-icon '+options.upIconClass+'">&nbsp;</span></div>' +
137
+ '<div class="ui-spinner-down ui-spinner-button ui-state-default ui-corner-br"><span class="ui-icon '+options.downIconClass+'">&nbsp;</span></div>' +
138
+ '</div>');
139
+ }
140
+
141
+ // object shortcuts
142
+ var upButton, downButton, buttons, icons,
143
+
144
+ hoverDelay,
145
+ hoverDelayCallback,
146
+
147
+ // current state booleans
148
+ hovered, inKeyDown, inSpecialKey, inMouseDown,
149
+
150
+ // used to reverse left/right key directions
151
+ rtl = input[0].dir == 'rtl';
152
+
153
+ // apply className before doing any calculations because it could affect them
154
+ if (className && typeof(wrapper) != 'undefined') wrapper.addClass(className);
155
+
156
+ if (showOn != 'never') {
157
+ wrapper.append(btnContainer.css({ height: height, left: -buttonWidth-rightMargin,
158
+ // use offset calculation to fix vertical position in Firefox
159
+ top: (input.offset().top - wrapper.offset().top) + 'px' }));
160
+
161
+ buttons = self.buttons = btnContainer.find('div.ui-spinner-button');
162
+ buttons.css({ width: buttonWidth - (box ? buttons.outerWidth() - buttons.width() : 0), height: height/2 - (box ? buttons.outerHeight() - buttons.height() : 0) });
163
+ upButton = buttons[0];
164
+ downButton = buttons[1];
165
+
166
+ // fix icon centering
167
+ icons = buttons.find('span.ui-icon');
168
+ icons.css({ marginLeft: (buttons.innerWidth() - icons.width()) / 2, marginTop: (buttons.innerHeight() - icons.height()) / 2 });
169
+
170
+ // set width of btnContainer to be the same as the buttons
171
+ btnContainer.width(buttons.outerWidth());
172
+ if (showOn != 'always')
173
+ btnContainer.css('opacity', 0);
174
+ }
175
+
176
+ /* Event Bindings */
177
+
178
+ // bind hover events to show/hide buttons
179
+ if (showOn == 'hover' || showOn == 'both')
180
+ buttons.add(input)
181
+ .bind('mouseenter' + eventNamespace, function() {
182
+ setHoverDelay(function() {
183
+ hovered = true;
184
+ if (!self.focused || (showOn == 'hover')) // ignore focus flag if show on hover only
185
+ self.showButtons();
186
+ });
187
+ })
188
+
189
+ .bind('mouseleave' + eventNamespace, function hoverOut() {
190
+ setHoverDelay(function() {
191
+ hovered = false;
192
+ if (!self.focused || (showOn == 'hover')) // ignore focus flag if show on hover only
193
+ self.hideButtons();
194
+ });
195
+ });
196
+
197
+
198
+ if (buttons != null) {
199
+ buttons.hover(function() {
200
+ // ensure that both buttons have hover removed, sometimes they get left on
201
+ self.buttons.removeClass(hover);
202
+
203
+ if (!options.disabled)
204
+ $(this).addClass(hover);
205
+ }, function() {
206
+ $(this).removeClass(hover);
207
+ })
208
+ .mousedown(mouseDown)
209
+ .mouseup(mouseUp)
210
+ .mouseout(mouseUp);
211
+ }
212
+
213
+ if (msie && buttons != null)
214
+ // fixes dbl click not firing second mouse down in IE
215
+ buttons.dblclick(function() {
216
+ if (!options.disabled) {
217
+ // make sure any changes are posted
218
+ self._change();
219
+ self._doSpin((this === upButton ? 1 : -1) * options.step);
220
+ }
221
+
222
+ return false;
223
+ })
224
+
225
+ // fixes IE8 dbl click selection highlight
226
+ .bind('selectstart', function() {return false;});
227
+
228
+ input.bind('keydown' + eventNamespace, function(e) {
229
+ var dir, large, limit,
230
+ keyCode = e.keyCode; // shortcut for minimization
231
+ if (e.ctrl || e.alt) return true; // ignore these events
232
+
233
+ if (isSpecialKey(keyCode))
234
+ inSpecialKey = true;
235
+
236
+ if (inKeyDown) return false; // only one direction at a time, and suppress invalid keys
237
+
238
+ switch (keyCode) {
239
+ case up:
240
+ case pageUp:
241
+ dir = 1;
242
+ large = keyCode == pageUp;
243
+ break;
244
+
245
+ case down:
246
+ case pageDown:
247
+ dir = -1;
248
+ large = keyCode == pageDown;
249
+ break;
250
+
251
+ case right:
252
+ case left:
253
+ dir = (keyCode == right) ^ rtl ? 1 : -1;
254
+ break;
255
+
256
+ case home:
257
+ limit = self.options.min;
258
+ if (limit != null) self._setValue(limit);
259
+ return false;
260
+
261
+ case end:
262
+ limit = self.options.max;
263
+ limit = self.options.max;
264
+ if (limit != null) self._setValue(limit);
265
+ return false;
266
+ }
267
+
268
+ if (dir) { // only process if dir was set above
269
+ if (!inKeyDown && !options.disabled) {
270
+ keyDir = dir;
271
+ if (buttons != null)
272
+ $(dir > 0 ? upButton : downButton).addClass(active);
273
+ inKeyDown = true;
274
+ self._startSpin(dir, large);
275
+ }
276
+
277
+ return false;
278
+ }
279
+ })
280
+
281
+ .bind('keyup' + eventNamespace, function(e) {
282
+ if (e.ctrl || e.alt) return true; // ignore these events
283
+ var keyCode = e.keyCode; // shortcut for minimization
284
+
285
+ if (isSpecialKey(keyCode))
286
+ inSpecialKey = false;
287
+
288
+ switch (keyCode) {
289
+ case up:
290
+ case right:
291
+ case pageUp:
292
+ case down:
293
+ case left:
294
+ case pageDown:
295
+ if (buttons != null)
296
+ buttons.removeClass(active);
297
+ self._stopSpin();
298
+ inKeyDown = false;
299
+ return false;
300
+ }
301
+ })
302
+
303
+ .bind('keypress' + eventNamespace, function(e) {
304
+ if (invalidKey(e.keyCode, e.charCode, e.target)) return false;
305
+ })
306
+
307
+ .bind('change' + eventNamespace, function() { self._change(); })
308
+
309
+ .bind('focus' + eventNamespace, function() {
310
+ function selectAll() {
311
+ self.element.select();
312
+ }
313
+
314
+ msie ? selectAll() : setTimeout(selectAll, 0); // add delay for Chrome, but breaks IE8
315
+ self.focused = true;
316
+ focusCtrl = self;
317
+ if (!hovered && (showOn == 'focus' || showOn == 'both')) // hovered will only be set if hover affects show
318
+ self.showButtons();
319
+ })
320
+
321
+ .bind('blur' + eventNamespace, function() {
322
+ self.focused = false;
323
+ if (!hovered && (showOn == 'focus' || showOn == 'both')) // hovered will only be set if hover affects show
324
+ self.hideButtons();
325
+ });
326
+
327
+ function isSpecialKey(keyCode) {
328
+ for (var i=0; i<validKeys.length; i++) // predefined list of special keys
329
+ if (validKeys[i] == keyCode) return true;
330
+
331
+ return false;
332
+ }
333
+
334
+ function invalidKey(keyCode, charCode, target) {
335
+ if (inSpecialKey) return false;
336
+
337
+ var ch = String.fromCharCode(charCode || keyCode),
338
+ options = self.options;
339
+
340
+ if ((ch >= '0') && (ch <= '9') || (ch == '-')) return false;
341
+ // Allow the decimal separator if there's only one and we want decimals
342
+ if (((self.places > 0 || self.places == 'free') && (ch == options.point) && ($(target).val() == null || $(target).val().indexOf(options.point) == -1))
343
+ || (ch == options.group)) return false;
344
+
345
+ return true;
346
+ }
347
+
348
+ // used to delay start of hover show/hide by 100 milliseconds
349
+ function setHoverDelay(callback) {
350
+ if (hoverDelay) {
351
+ // don't do anything if trying to set the same callback again
352
+ if (callback === hoverDelayCallback) return;
353
+
354
+ clearTimeout(hoverDelay);
355
+ }
356
+
357
+ hoverDelayCallback = callback;
358
+ hoverDelay = setTimeout(execute, 100);
359
+
360
+ function execute() {
361
+ hoverDelay = 0;
362
+ callback();
363
+ }
364
+ }
365
+
366
+ function mouseDown() {
367
+ if (!options.disabled) {
368
+ var input = self.element[0],
369
+ dir = (this === upButton ? 1 : -1);
370
+
371
+ input.focus();
372
+ input.select();
373
+ $(this).addClass(active);
374
+
375
+ inMouseDown = true;
376
+ self._startSpin(dir);
377
+ }
378
+
379
+ return false;
380
+ }
381
+
382
+ function mouseUp() {
383
+ if (inMouseDown) {
384
+ $(this).removeClass(active);
385
+ self._stopSpin();
386
+ inMouseDown = false;
387
+ }
388
+ return false;
389
+ }
390
+ },
391
+
392
+ _procOptions: function(init) {
393
+ var self = this,
394
+ input = self.element,
395
+ options = self.options,
396
+ min = options.min,
397
+ max = options.max,
398
+ step = options.step,
399
+ places = options.places,
400
+ maxlength = -1, temp;
401
+
402
+ // setup increment based on speed string
403
+ if (options.increment == 'slow')
404
+ options.increment = [{count: 1, mult: 1, delay: 250},
405
+ {count: 3, mult: 1, delay: 100},
406
+ {count: 0, mult: 1, delay: 50}];
407
+ else if (options.increment == 'fast')
408
+ options.increment = [{count: 1, mult: 1, delay: 250},
409
+ {count: 19, mult: 1, delay: 100},
410
+ {count: 80, mult: 1, delay: 20},
411
+ {count: 100, mult: 10, delay: 20},
412
+ {count: 0, mult: 100, delay: 20}];
413
+
414
+ if ((min == null) && ((temp = input.attr('min')) != null))
415
+ min = parseFloat(temp);
416
+
417
+ if ((max == null) && ((temp = input.attr('max')) != null))
418
+ max = parseFloat(temp);
419
+
420
+ if (!step && ((temp = input.attr('step')) != null))
421
+ if (temp != 'any') {
422
+ step = parseFloat(temp);
423
+ options.largeStep *= step;
424
+ }
425
+ options.step = step = step || options.defaultStep;
426
+
427
+ // Process step for decimal places if none are specified
428
+ if ((places == null) && ((temp = step + '').indexOf('.') != -1))
429
+ places = temp.length - temp.indexOf('.') - 1;
430
+ self.places = places;
431
+
432
+ if ((max != null) && (min != null)) {
433
+ // ensure that min is less than or equal to max
434
+ if (min > max) min = max;
435
+
436
+ // set maxlength based on min/max
437
+ maxlength = Math.max(Math.max(maxlength, options.format(max, places, input).length), options.format(min, places, input).length);
438
+ }
439
+
440
+ // only lookup input maxLength on init
441
+ if (init) self.inputMaxLength = input[0].maxLength;
442
+ temp = self.inputMaxLength;
443
+
444
+ if (temp > 0) {
445
+ maxlength = maxlength > 0 ? Math.min(temp, maxlength) : temp;
446
+ temp = Math.pow(10, maxlength) - 1;
447
+
448
+ // Infinity is a value assigned by IE in temp when it becomes to big or too small
449
+ if (((max == null) || (max > temp)) && temp != 'Infinity')
450
+ max = temp;
451
+ temp = -(temp + 1) / 10 + 1;
452
+ if (((min == null) || (min < temp)) && temp != '-Infinity')
453
+ min = temp;
454
+ }
455
+
456
+ if (maxlength > 0)
457
+ input.attr('maxlength', maxlength);
458
+
459
+ options.min = min;
460
+ options.max = max;
461
+
462
+ // ensures that current value meets constraints
463
+ self._change();
464
+
465
+ input.unbind(mouseWheelEventName + eventNamespace);
466
+ if (options.mouseWheel)
467
+ input.bind(mouseWheelEventName + eventNamespace, self._mouseWheel);
468
+ },
469
+
470
+ _mouseWheel: function(e) {
471
+ var self = $.data(this, 'spinner');
472
+ if (!self.options.disabled && self.focused && (focusCtrl === self)) {
473
+ // make sure changes are posted
474
+ self._change();
475
+ self._doSpin(((e.wheelDelta || -e.detail) > 0 ? 1 : -1) * self.options.step);
476
+ return false;
477
+ }
478
+ },
479
+
480
+ // sets an interval to call the _spin function
481
+ _setTimer: function(delay, dir, large) {
482
+ var self = this;
483
+ self._stopSpin();
484
+ self.timer = setInterval(fire, delay);
485
+
486
+ function fire() {
487
+ self._spin(dir, large);
488
+ }
489
+ },
490
+
491
+ // stops the spin timer
492
+ _stopSpin: function() {
493
+ if (this.timer) {
494
+ clearInterval(this.timer);
495
+ this.timer = 0;
496
+ }
497
+ },
498
+
499
+ // performs first step, and starts the spin timer if increment is set
500
+ _startSpin: function(dir, large) {
501
+ // shortcuts
502
+ var self = this,
503
+ options = self.options,
504
+ increment = options.increment;
505
+
506
+ // make sure any changes are posted
507
+ self._change();
508
+ self._doSpin(dir * (large ? self.options.largeStep : self.options.step));
509
+
510
+ if (increment && increment.length > 0) {
511
+ self.counter = 0;
512
+ self.incCounter = 0;
513
+ self._setTimer(increment[0].delay, dir, large);
514
+ }
515
+ },
516
+
517
+ // called by timer for each step in the spin
518
+ _spin: function(dir, large) {
519
+ // shortcuts
520
+ var self = this,
521
+ increment = self.options.increment,
522
+ curIncrement = increment[self.incCounter];
523
+
524
+ self._doSpin(dir * curIncrement.mult * (large ? self.options.largeStep : self.options.step));
525
+ self.counter++;
526
+
527
+ if ((self.counter > curIncrement.count) && (self.incCounter < increment.length-1)) {
528
+ self.counter = 0;
529
+ curIncrement = increment[++self.incCounter];
530
+ self._setTimer(curIncrement.delay, dir, large);
531
+ }
532
+ },
533
+
534
+ // actually spins the timer by a step
535
+ _doSpin: function(step) {
536
+ // shortcut
537
+ var self = this,
538
+ value = self.curvalue;
539
+
540
+ if (value == null)
541
+ value = (step > 0 ? self.options.min : self.options.max) || 0;
542
+ if (self.options.places == 'free') {
543
+ // We may be in the floating problem! Lets stick with the number of decimals in the original value or in the step (max)
544
+ var point = self.options.point,
545
+ result = value + step,
546
+ strResult = result.toString(),
547
+ strValue = value.toString(),
548
+ strStep = step.toString(),
549
+ numDigitValue = (strValue.indexOf(point) == -1 ? 0 : strValue.length - strValue.indexOf(point) - 1),
550
+ numDigitStep = (strStep.indexOf(point) == -1 ? 0 : strStep.length - strStep.indexOf(point) - 1),
551
+ desiredNumDigit = Math.max(numDigitValue, numDigitStep),
552
+ numDigitResult = (strResult.indexOf(point) == -1 ? 0 : strResult.length - strResult.indexOf(point) - 1);
553
+ if (numDigitResult > desiredNumDigit)
554
+ self._setValue(result.toFixed(desiredNumDigit));
555
+ else
556
+ self._setValue(result);
557
+
558
+ } else {
559
+ self._setValue(value + step);
560
+ }
561
+ },
562
+
563
+ // Parse the value currently in the field
564
+ _parseValue: function() {
565
+ var value = this.element.val();
566
+ return value ? this.options.parse(value, this.element) : null;
567
+ },
568
+
569
+ _validate: function(value) {
570
+ var options = this.options,
571
+ min = options.min,
572
+ max = options.max;
573
+
574
+ if ((value == null) && !options.allowNull)
575
+ value = this.curvalue != null ? this.curvalue : min || max || 0; // must confirm not null in case just initializing and had blank value
576
+
577
+ if ((max != null) && (value > max))
578
+ return max;
579
+ else if ((min != null) && (value < min))
580
+ return min;
581
+ else
582
+ return value;
583
+ },
584
+
585
+ _change: function() {
586
+ var self = this, // shortcut
587
+ value = self._parseValue(),
588
+ min = self.options.min,
589
+ max = self.options.max;
590
+
591
+ // don't reprocess if change was self triggered
592
+ if (!self.selfChange) {
593
+ if (isNaN(value))
594
+ value = self.curvalue;
595
+
596
+ self._setValue(value, true);
597
+ }
598
+ },
599
+
600
+ // overrides _setData to force option parsing
601
+ _setOption: function(key, value) {
602
+ $.Widget.prototype._setOption.call(this, key, value);
603
+ this._procOptions();
604
+ },
605
+
606
+ increment: function() {
607
+ this._doSpin(this.options.step);
608
+ },
609
+
610
+ decrement: function() {
611
+ this._doSpin(-this.options.step);
612
+ },
613
+
614
+ showButtons: function(immediate) {
615
+ var btnContainer = this.btnContainer.stop();
616
+ if (immediate)
617
+ btnContainer.css('opacity', 1);
618
+ else
619
+ btnContainer.fadeTo('fast', 1);
620
+ },
621
+
622
+ hideButtons: function(immediate) {
623
+ var btnContainer = this.btnContainer.stop();
624
+ if (immediate)
625
+ btnContainer.css('opacity', 0);
626
+ else
627
+ btnContainer.fadeTo('fast', 0);
628
+ this.buttons.removeClass(hover);
629
+ },
630
+
631
+ // Set the value directly
632
+ _setValue: function(value, suppressFireEvent) {
633
+ var self = this;
634
+
635
+ self.curvalue = value = self._validate(value);
636
+ self.element.val(value != null ?
637
+ self.options.format(value, self.places, self.element) :
638
+ '');
639
+
640
+ if (!suppressFireEvent) {
641
+ self.selfChange = true;
642
+ self.element.change();
643
+ self.selfChange = false;
644
+ }
645
+ },
646
+
647
+ // Set or retrieve the value
648
+ value: function(newValue) {
649
+ if (arguments.length) {
650
+ this._setValue(newValue);
651
+
652
+ // maintains chaining
653
+ return this.element;
654
+ }
655
+
656
+ return this.curvalue;
657
+ },
658
+
659
+ enable: function() {
660
+ this.buttons.removeClass(disabled);
661
+ this.element[0].disabled = false;
662
+ $.Widget.prototype.enable.call(this);
663
+ },
664
+
665
+ disable: function() {
666
+ this.buttons.addClass(disabled)
667
+ // in case hover class got left on
668
+ .removeClass(hover);
669
+
670
+ this.element[0].disabled = true;
671
+ $.Widget.prototype.disable.call(this);
672
+ },
673
+
674
+ destroy: function(target) {
675
+ if (typeof(this.wrapper) != 'undefined')
676
+ this.wrapper.remove();
677
+ this.element.unbind(eventNamespace).css({ width: this.oWidth, marginRight: this.oMargin });
678
+
679
+ $.Widget.prototype.destroy.call(this);
680
+ }
681
+ });
682
+
683
+ })( jQuery );