]> source.dussan.org Git - jquery-ui.git/commitdiff
Porting old spinner implementation to 1.8, dropping some baggage.
authorjzaefferer <joern.zaefferer@gmail.com>
Fri, 22 Oct 2010 04:16:12 +0000 (06:16 +0200)
committerjzaefferer <joern.zaefferer@gmail.com>
Fri, 22 Oct 2010 04:16:12 +0000 (06:16 +0200)
demos/spinner/default.html [new file with mode: 0644]
demos/spinner/donation.html [new file with mode: 0644]
demos/spinner/hexadecimal.html [new file with mode: 0644]
demos/spinner/index.html [new file with mode: 0644]
demos/spinner/latlong.html [new file with mode: 0644]
demos/spinner/rtl.html [new file with mode: 0644]
external/jquery.mousewheel-3.0.2.js [new file with mode: 0644]
themes/base/jquery.ui.base.css
themes/base/jquery.ui.spinner.css [new file with mode: 0644]
ui/jquery.ui.spinner.js [new file with mode: 0644]

diff --git a/demos/spinner/default.html b/demos/spinner/default.html
new file mode 100644 (file)
index 0000000..d90b73f
--- /dev/null
@@ -0,0 +1,65 @@
+<!doctype html>\r
+<html lang="en">\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>jQuery UI Spinner - Default functionality</title>\r
+       <link type="text/css" href="../../themes/base/jquery.ui.all.css" rel="stylesheet" />\r
+       <script type="text/javascript" src="../../jquery-1.4.3.js"></script>\r
+       <script type="text/javascript" src="../../external/jquery.mousewheel-3.0.2.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.core.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.widget.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.button.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.spinner.js"></script>\r
+       <link type="text/css" href="../demos.css" rel="stylesheet" />\r
+       <script type="text/javascript">\r
+       $(function() {\r
+               $("#spinner").spinner();\r
+               \r
+               $("#disable").toggle(function() {\r
+                       $("#spinner").spinner("disable");\r
+               }, function() {\r
+                       $("#spinner").spinner("enable");\r
+               });\r
+               $("#destroy").toggle(function() {\r
+                       $("#spinner").spinner("destroy");\r
+               }, function() {\r
+                       $("#spinner").spinner();\r
+               });\r
+               $("#getvalue").click(function() {\r
+                       alert($("#spinner").spinner("value"));\r
+               });\r
+               $("#setvalue").click(function() {\r
+                       $("#spinner").spinner("value", 5);\r
+               });\r
+               \r
+               $("button").button();\r
+       });\r
+       </script>\r
+</head>\r
+<body>\r
+\r
+<div class="demo">\r
+\r
+<p><label for="spinner">Select a value:</label>\r
+<input id="spinner" name="value" /></p>\r
+\r
+<p>\r
+<button id="disable">Toggle disable/enable</button>\r
+<button id="destroy">Toggle widget</button>\r
+</p>\r
+\r
+<p>\r
+<button id="getvalue">Get value</button>\r
+<button id="setvalue">Set value to 5</button>\r
+</p>\r
+\r
+</div><!-- End demo -->\r
+\r
+<div class="demo-description">\r
+<p>\r
+Default spinner.\r
+</p>\r
+</div><!-- End demo-description -->\r
+\r
+</body>\r
+</html>\r
diff --git a/demos/spinner/donation.html b/demos/spinner/donation.html
new file mode 100644 (file)
index 0000000..617570b
--- /dev/null
@@ -0,0 +1,74 @@
+<!doctype html>\r
+<html lang="en">\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>jQuery UI Spinner - Default functionality</title>\r
+       <link type="text/css" href="../../themes/base/jquery.ui.all.css" rel="stylesheet" />\r
+       <script type="text/javascript" src="../../jquery-1.4.3.js"></script>\r
+       <script type="text/javascript" src="../../external/jquery.mousewheel-3.0.2.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.core.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.widget.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.button.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.spinner.js"></script>\r
+       <link type="text/css" href="../demos.css" rel="stylesheet" />\r
+       <script type="text/javascript">\r
+       $(function() {\r
+\r
+               var opts = {\r
+                       's1': { currency: '$' },\r
+                       's2': { currency: '€' },\r
+                       's3': { currency: '¥' },\r
+                       's4': { currency: '$', groupSeparator: ' ', radixPoint: '.' },\r
+                       's5': { currency: 'Fr ', groupSeparator: "'", radixPoint: '.' },\r
+                       's6': { currency: 'RUB', groupSeparator: ".", radixPoint: ',' }\r
+               };\r
+               \r
+               var currency = $("#currency").change(function() {\r
+                       var val = $(this).val();\r
+                       $("#amount")\r
+                               .spinner("option", "currency", opts[val].currency)\r
+                               .spinner("option", "groupSeparator", opts[val].groupSeparator ? opts[val].groupSeparator : ',')\r
+                               .spinner("option", "radixPoint", opts[val].radixPoint ? opts[val].radixPoint : '.')\r
+                               .blur();\r
+               });\r
+               $("#amount").spinner({\r
+                       currency: opts[currency.val()].currency,\r
+                       min: 5,\r
+                       max: 2500,\r
+                       step: 25,\r
+                       start: 1000,\r
+                       width: '10em'\r
+               });     \r
+               \r
+       });\r
+       </script>\r
+</head>\r
+<body>\r
+\r
+<div class="demo">\r
+\r
+<p>\r
+       <label for="currency">Currency</label>\r
+       <select id="currency" name="currency">\r
+               <option value="s1">US $</option>\r
+               <option value="s2">EUR €</option>\r
+               <option value="s3">YEN ¥</option>\r
+               <option value="s4">Australian $</option>\r
+               <option value="s5">Swiss Franc Fr</option>\r
+               <option value="s6">Russian Ruble RUB</option>\r
+       </select>       \r
+</p>\r
+<p>\r
+       <label for="amount">Select the amount to donate:</label>\r
+       <input id="amount" name="amount" value="5" />\r
+</p>\r
+</div><!-- End demo -->\r
+\r
+<div class="demo-description">\r
+<p>\r
+Example of a donation form, with currency selection and amout spinner.\r
+</p>\r
+</div><!-- End demo-description -->\r
+\r
+</body>\r
+</html>\r
diff --git a/demos/spinner/hexadecimal.html b/demos/spinner/hexadecimal.html
new file mode 100644 (file)
index 0000000..03952a6
--- /dev/null
@@ -0,0 +1,37 @@
+<!doctype html>\r
+<html lang="en">\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>jQuery UI Spinner - Hexadecimal</title>\r
+       <link type="text/css" href="../../themes/base/jquery.ui.all.css" rel="stylesheet" />\r
+       <script type="text/javascript" src="../../jquery-1.4.3.js"></script>\r
+       <script type="text/javascript" src="../../external/jquery.mousewheel-3.0.2.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.core.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.widget.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.button.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.spinner.js"></script>\r
+       <link type="text/css" href="../demos.css" rel="stylesheet" />\r
+       <script type="text/javascript">\r
+       $(function() {\r
+               $("#hexadecimal").spinner({radix: 16, padLength: 6, precision: 2, step: '0.01'});       \r
+       });\r
+       </script>\r
+</head>\r
+<body>\r
+\r
+<div class="demo">\r
+\r
+<p>\r
+       <label for="hexadecimal">Hexadecimal spinner:</label>\r
+       <input id="hexadecimal" name="hexadecimal" value="0" />\r
+</p>\r
+</div><!-- End demo -->\r
+\r
+<div class="demo-description">\r
+<p>\r
+Example of a hexadecimal spinner.\r
+</p>\r
+</div><!-- End demo-description -->\r
+\r
+</body>\r
+</html>\r
diff --git a/demos/spinner/index.html b/demos/spinner/index.html
new file mode 100644 (file)
index 0000000..6d7b980
--- /dev/null
@@ -0,0 +1,20 @@
+<!doctype html>\r
+<html lang="en">\r
+<head>\r
+       <title>jQuery UI Spinner Demos</title>\r
+       <link type="text/css" href="../demos.css" rel="stylesheet" />\r
+</head>\r
+<body>\r
+       <div class="demos-nav">\r
+               <h4>Examples</h4>\r
+               <ul>\r
+                       <li class="demo-config-on"><a href="default.html">Default functionality</a></li>\r
+                       <li><a href="donation.html">Donation</a></li>\r
+                       <li><a href="hexadecimal.html">Hexadecimal</a></li>\r
+                       <li><a href="latlong.html">Map</a></li>\r
+                       <li><a href="mousewheel-disabled.html">Mousewheel Disabled</a></li>\r
+                       <li><a href="rtl.html">RTL</a></li>\r
+               </ul>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/demos/spinner/latlong.html b/demos/spinner/latlong.html
new file mode 100644 (file)
index 0000000..6b955ba
--- /dev/null
@@ -0,0 +1,60 @@
+<!doctype html>\r
+<html lang="en">\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>jQuery UI Spinner - Map</title>\r
+       <link type="text/css" href="../../themes/base/jquery.ui.all.css" rel="stylesheet" />\r
+       <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>\r
+       <script type="text/javascript" src="../../jquery-1.4.3.js"></script>\r
+       <script type="text/javascript" src="../../external/jquery.mousewheel-3.0.2.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.core.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.widget.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.button.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.spinner.js"></script>\r
+       <link type="text/css" href="../demos.css" rel="stylesheet" />\r
+       <script type="text/javascript">\r
+       $(function() {\r
+               function latlong() {\r
+                       return new google.maps.LatLng($("#lat").val(),$("#lng").val());\r
+               }\r
+               function position() {\r
+                       map.setCenter(latlong());\r
+               }\r
+               $("#lat, #lng").spinner({\r
+                       precision: 6,\r
+                       change: position\r
+               });\r
+               \r
+               var map = new google.maps.Map($("#map")[0], {\r
+                       zoom: 8,\r
+                       center: latlong(),\r
+                       mapTypeId: google.maps.MapTypeId.ROADMAP\r
+               });\r
+       });\r
+       </script>\r
+       <style>\r
+               #map { width:500px; height:500px; }\r
+       </style>\r
+</head>\r
+<body>\r
+\r
+<div class="demo">\r
+\r
+<label for="lat">Latitude</label>\r
+<input id="lat" name="lat" value="44.797916" />\r
+<br/>\r
+<label for="lng">Longitude</label>\r
+<input id="lng" name="lng" value="-93.278046" />\r
+\r
+<div id="map"></div>\r
+\r
+</div><!-- End demo -->\r
+\r
+<div class="demo-description">\r
+<p>\r
+Google Maps integration, using spinners to change latidude and longitude.\r
+</p>\r
+</div><!-- End demo-description -->\r
+\r
+</body>\r
+</html>\r
diff --git a/demos/spinner/rtl.html b/demos/spinner/rtl.html
new file mode 100644 (file)
index 0000000..52d7b10
--- /dev/null
@@ -0,0 +1,36 @@
+<!doctype html>\r
+<html lang="en">\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>jQuery UI Spinner - Default functionality</title>\r
+       <link type="text/css" href="../../themes/base/jquery.ui.all.css" rel="stylesheet" />\r
+       <script type="text/javascript" src="../../jquery-1.4.3.js"></script>\r
+       <script type="text/javascript" src="../../external/jquery.mousewheel-3.0.2.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.core.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.widget.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.button.js"></script>\r
+       <script type="text/javascript" src="../../ui/jquery.ui.spinner.js"></script>\r
+       <link type="text/css" href="../demos.css" rel="stylesheet" />\r
+       <script type="text/javascript">\r
+       $(function() {\r
+               $("#s1").spinner({dir: 'rtl'});\r
+       });\r
+       </script>\r
+</head>\r
+<body>\r
+\r
+<div class="demo">\r
+\r
+<p><label for="s1">Select a value:</label>\r
+<input id="s1" name="value" /></p>\r
+\r
+</div><!-- End demo -->\r
+\r
+<div class="demo-description">\r
+<p>\r
+Default spinner.\r
+</p>\r
+</div><!-- End demo-description -->\r
+\r
+</body>\r
+</html>\r
diff --git a/external/jquery.mousewheel-3.0.2.js b/external/jquery.mousewheel-3.0.2.js
new file mode 100644 (file)
index 0000000..507ab00
--- /dev/null
@@ -0,0 +1,60 @@
+/*! Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)\r
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)\r
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.\r
+ * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.\r
+ * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.\r
+ *\r
+ * Version: 3.0.2\r
+ * \r
+ * Requires: 1.2.2+\r
+ */\r
+\r
+(function($) {\r
+\r
+var types = ['DOMMouseScroll', 'mousewheel'];\r
+\r
+$.event.special.mousewheel = {\r
+       setup: function() {\r
+               if ( this.addEventListener )\r
+                       for ( var i=types.length; i; )\r
+                               this.addEventListener( types[--i], handler, false );\r
+               else\r
+                       this.onmousewheel = handler;\r
+       },\r
+       \r
+       teardown: function() {\r
+               if ( this.removeEventListener )\r
+                       for ( var i=types.length; i; )\r
+                               this.removeEventListener( types[--i], handler, false );\r
+               else\r
+                       this.onmousewheel = null;\r
+       }\r
+};\r
+\r
+$.fn.extend({\r
+       mousewheel: function(fn) {\r
+               return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");\r
+       },\r
+       \r
+       unmousewheel: function(fn) {\r
+               return this.unbind("mousewheel", fn);\r
+       }\r
+});\r
+\r
+\r
+function handler(event) {\r
+       var args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true;\r
+       \r
+       event = $.event.fix(event || window.event);\r
+       event.type = "mousewheel";\r
+       \r
+       if ( event.wheelDelta ) delta = event.wheelDelta/120;\r
+       if ( event.detail     ) delta = -event.detail/3;\r
+       \r
+       // Add events and delta to the front of the arguments\r
+       args.unshift(event, delta);\r
+\r
+       return $.event.handle.apply(this, args);\r
+}\r
+\r
+})(jQuery);
\ No newline at end of file
index 7634fb61e7cc6c475a8ec24f2530d146e22fc4af..62d17c7e24ad985af8bad9f3bc13a7d0b6507822 100644 (file)
@@ -18,4 +18,5 @@
 @import url("jquery.ui.resizable.css");
 @import url("jquery.ui.selectable.css");
 @import url("jquery.ui.slider.css");
+@import url("jquery.ui.spinner.css");
 @import url("jquery.ui.tabs.css");
diff --git a/themes/base/jquery.ui.spinner.css b/themes/base/jquery.ui.spinner.css
new file mode 100644 (file)
index 0000000..6d8bfa5
--- /dev/null
@@ -0,0 +1,24 @@
+/* Spinner\r
+----------------------------------*/\r
+.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; height: 1.8em; }\r
+.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; }\r
+.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; z-index: 100; text-align: center; vertical-align: middle; position: absolute; cursor: default; display: block; overflow: hidden; }\r
+.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; } /* more specificity required here to overide default borders */\r
+.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */\r
+.ui-spinner-up { top: 0; }\r
+.ui-spinner-down { bottom: 0; }\r
+\r
+/* ltr (default) */\r
+.ui-spinner-ltr { direction: ltr; }\r
+.ui-spinner-ltr .ui-spinner-input { float: left; margin-left: .4em; margin-right: 22px; }\r
+.ui-spinner-ltr .ui-spinner-button { right: 0; }\r
+.ui-spinner-ltr a.ui-spinner-button { border-right: none; }\r
+\r
+/* rtl */\r
+.ui-spinner-rtl { direction: rtl; }\r
+.ui-spinner-rtl .ui-spinner-input { float: right; margin-left: 22px; margin-right: .4em; }\r
+.ui-spinner-rtl .ui-spinner-button { left: 0; }\r
+.ui-spinner-rtl a.ui-spinner-button { border-left: none; }\r
+\r
+/* TR overrides */\r
+div.ui-spinner { background: none; }\r
diff --git a/ui/jquery.ui.spinner.js b/ui/jquery.ui.spinner.js
new file mode 100644 (file)
index 0000000..c0167fd
--- /dev/null
@@ -0,0 +1,505 @@
+/*\r
+ * jQuery UI Spinner @VERSION\r
+ *\r
+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)\r
+ * Dual licensed under the MIT (MIT-LICENSE.txt)\r
+ * and GPL (GPL-LICENSE.txt) licenses.\r
+ *\r
+ * http://docs.jquery.com/UI/Spinner\r
+ *\r
+ * Depends:\r
+ *  jquery.ui.core.js\r
+ *  jquery.ui.widget.js\r
+ */\r
+(function($) {\r
+\r
+// shortcut constants\r
+var hover = 'ui-state-hover',\r
+       active = 'ui-state-active',\r
+       namespace = '.spinner',\r
+       buttonRegex = /hide|auto|fast|slow|(\d+)/,\r
+       uiSpinnerClasses = 'ui-spinner ui-state-default ui-widget ui-widget-content ui-corner-all ';\r
+\r
+$.widget('ui.spinner', {\r
+       options: {\r
+               currency: false,\r
+               dir: 'ltr',\r
+               groupSeparator: '',\r
+               incremental: true,\r
+               max: null,\r
+               min: null,\r
+               mouseWheel: true,\r
+               padding: 0,\r
+               page: 5,\r
+               precision: 0,\r
+               radix: 10,\r
+               radixPoint: '.',\r
+               spinnerClass: null,\r
+               step: null,\r
+               value: 0,\r
+               width: false\r
+       },\r
+       \r
+       _create: function() {           \r
+               this._initOptions();\r
+\r
+               this.value(this._parse(this.element.val() || this.options.value));\r
+               \r
+               this._draw();\r
+\r
+               this._mousewheel();\r
+               \r
+               this._aria();\r
+       },\r
+       _initOptions: function() {\r
+               var self = this,\r
+                       options = self.options;\r
+\r
+               // check for precision in stepping and set _precision as internal\r
+               var precision = parseInt(options.precision, 10);\r
+               \r
+               if (self._step().toString().indexOf('.') != -1 && precision === 0) {\r
+                       var s = self._step().toString();\r
+                       precision = s.slice(s.indexOf('.')+1, s.length).length;\r
+               }\r
+               \r
+               // set currency options\r
+               if (options.currency) {\r
+                       precision = 2;\r
+                       options.radix = 10;\r
+                       options.groupSeparator = options.groupSeparator || (options.radixPoint === ',' ? '' : ',');\r
+               }\r
+               options.precision = precision;\r
+       },\r
+       _draw: function() {\r
+               var self = this,\r
+                       options = self.options;\r
+\r
+               var uiSpinner = self.element\r
+                       .addClass('ui-spinner-input')\r
+                       .attr('autocomplete', 'off')\r
+                       .wrap(self._uiSpinnerHtml())\r
+                       .parent()\r
+                               // add buttons\r
+                               .append(self._buttonHtml())\r
+                               // add behaviours\r
+                               .hover(function() {\r
+                                       if (!options.disabled) {\r
+                                               $(this).addClass(hover);\r
+                                       }\r
+                                       self.hovered = true;\r
+                               }, function() {\r
+                                       $(this).removeClass(hover);\r
+                                       self.hovered = false;\r
+                               });\r
+\r
+               // TODO: need a better way to exclude IE8 without resorting to $.browser.version\r
+               // fix inline-block issues for IE. Since IE8 supports inline-block we need to exclude it.\r
+               if (!$.support.opacity && uiSpinner.css('display') == 'inline-block' && $.browser.version < 8) {\r
+                       uiSpinner.css('display', 'inline');\r
+               }\r
+\r
+               this.element\r
+                       .bind('keydown'+namespace, function(event) {\r
+                               return self._start(event) ? self._keydown(event) : false;\r
+                       })\r
+                       .bind('keyup'+namespace, function(event) {\r
+                               if (self.spinning) {\r
+                                       self._stop(event);\r
+                                       self._change(event);                                    \r
+                               }\r
+                       })\r
+                       .bind('focus'+namespace, function() {\r
+                               uiSpinner.addClass(active);\r
+                               self.focused = true;\r
+                       })\r
+                       .bind('blur'+namespace, function(event) {\r
+                               self._value(self.element.val());\r
+                               if (!self.hovered) {\r
+                                       uiSpinner.removeClass(active);\r
+                               }               \r
+                               self.focused = false;\r
+                       });\r
+\r
+               // force width if passed through options\r
+               if (options.width) {\r
+                       this.element.width(options.width);\r
+               }\r
+\r
+               // disable spinner if element was already disabled\r
+               if (options.disabled) {\r
+                       this.disable();\r
+               }\r
+               \r
+               // button bindings\r
+               this.buttons = uiSpinner.find('.ui-spinner-button')\r
+                       .bind('mousedown', function(event) {                            \r
+                               if (self._start(event) === false) {\r
+                                       return false;\r
+                               }\r
+                               self._repeat(null, $(this).hasClass('ui-spinner-up') ? 1 : -1, event);\r
+                               \r
+                               if (!self.options.disabled) {\r
+                                       $(this).addClass(active);\r
+                                       uiSpinner.addClass(active);\r
+                               }\r
+                       })\r
+                       .bind('mouseup', function(event) {\r
+                               if (self.counter == 1) {\r
+                                       self._spin(($(this).hasClass('ui-spinner-up') ? 1 : -1) * self._step(), event);\r
+                               }\r
+                               if (self.spinning) {\r
+                                       self._stop(event);\r
+                                       self._change(event);                                    \r
+                               }\r
+                               $(this).removeClass(active);\r
+                       })\r
+                       .hover(function() {\r
+                               if (!self.options.disabled) {\r
+                                       $(this).addClass(hover);                                        \r
+                               }\r
+                       }, function(event) {\r
+                               $(this).removeClass(active + ' ' + hover);\r
+                               if (self.timer && self.spinning) {\r
+                                       self._stop(event);\r
+                                       self._change(event);\r
+                               }\r
+                       });\r
+                                       \r
+               self.uiSpinner = uiSpinner;\r
+       },\r
+       _uiSpinnerHtml: function() {\r
+               return '<div role="spinbutton" class="' + uiSpinnerClasses + \r
+                               (this.options.spinnerClass || '') + \r
+                               ' ui-spinner-' + this.options.dir + \r
+                               '"></div>';\r
+       },\r
+       _buttonHtml: function() {\r
+               return '<a class="ui-spinner-button ui-spinner-up ui-state-default ui-corner-t' + this.options.dir.substr(-1,1) + \r
+                               '"><span class="ui-icon ui-icon-triangle-1-n">&#9650;</span></a>' +\r
+                               '<a class="ui-spinner-button ui-spinner-down ui-state-default ui-corner-b' + this.options.dir.substr(-1,1) + \r
+                               '"><span class="ui-icon ui-icon-triangle-1-s">&#9660;</span></a>';\r
+       },\r
+       _start: function(event) {\r
+               if (!this.spinning && this._trigger('start', event, { value: this.value()}) !== false) {\r
+                       if (!this.counter) {\r
+                               this.counter = 1;\r
+                       }\r
+                       this.spinning = true;\r
+                       return true;\r
+               }\r
+               return false;\r
+       },\r
+       _spin: function(step, event) {\r
+               if (this.options.disabled) {\r
+                       return;\r
+               }\r
+               if (!this.counter) {\r
+                       this.counter = 1;\r
+               }\r
+               \r
+               var newVal = this._value() + step * (this.options.incremental && this.counter > 100\r
+                       ? this.counter > 200\r
+                               ? 100 \r
+                               : 10\r
+                       : 1);\r
+               \r
+               // cancelable\r
+               if (this._trigger('spin', event, { value: newVal }) !== false) {\r
+                       this._value(newVal);\r
+                       this.counter++;                 \r
+               }\r
+       },\r
+       _stop: function(event) {\r
+               this.counter = 0;\r
+               if (this.timer) {\r
+                       window.clearInterval(this.timer);\r
+               }\r
+               this.element[0].focus();\r
+               this.spinning = false;\r
+               this._trigger('stop', event);\r
+       },\r
+       _change: function(event) {\r
+               this._trigger('change', event);\r
+       },\r
+       _repeat: function(i, steps, event) {\r
+               var self = this;\r
+               i = i || 100;\r
+\r
+               if (this.timer) {\r
+                       window.clearInterval(this.timer);\r
+               }\r
+               \r
+               this.timer = window.setInterval(function() {\r
+                       self._repeat(self.options.incremental && self.counter > 20 ? 20 : i, steps, event);\r
+               }, i);\r
+               \r
+               self._spin(steps*self._step(), event);\r
+       },\r
+       _keydown: function(event) {\r
+               var o = this.options,\r
+                       KEYS = $.ui.keyCode;\r
+\r
+               switch (event.keyCode) {\r
+                       case KEYS.UP:                   this._repeat(null, event.shiftKey ? o.page : 1, event); break;\r
+                       case KEYS.DOWN:                 this._repeat(null, event.shiftKey ? -o.page : -1, event); break;\r
+                       case KEYS.PAGE_UP:              this._repeat(null, o.page, event); break;\r
+                       case KEYS.PAGE_DOWN:    this._repeat(null, -o.page, event); break;\r
+                       \r
+                       case KEYS.HOME:\r
+                       case KEYS.END:\r
+                               if (event.shiftKey) {\r
+                                       return true;\r
+                               }\r
+                               this._value(this['_' + (event.keyCode == KEYS.HOME ? 'min':'max')]());\r
+                               break;\r
+                       \r
+                       case KEYS.TAB:\r
+                       case KEYS.BACKSPACE:\r
+                       case KEYS.LEFT:\r
+                       case KEYS.RIGHT:\r
+                       case KEYS.PERIOD:\r
+                       case KEYS.NUMPAD_DECIMAL:\r
+                       case KEYS.NUMPAD_SUBTRACT:\r
+                               return true;\r
+                       \r
+                       case KEYS.ENTER:\r
+                               this.value(this.element.val());\r
+                               return true;\r
+                               \r
+                       default:                                \r
+                               if ((event.keyCode >= 96 && event.keyCode <= 105) || // numeric keypad 0-9\r
+                                       (new RegExp('[' + this._validChars() + ']', 'i').test(String.fromCharCode(event.keyCode)))) {\r
+                                       return true;\r
+                               };\r
+               }\r
+               \r
+               return false;\r
+       },\r
+       _mousewheel: function() {\r
+               var self = this;\r
+               if ($.fn.mousewheel && self.options.mouseWheel) {\r
+                       this.element.mousewheel(function(event, delta) {\r
+                               delta = ($.browser.opera ? -delta / Math.abs(delta) : delta);\r
+                               if (!self._start(event)) {\r
+                                       return false;\r
+                               }\r
+                               self._spin((delta > 0 ? 1 : -1) * self._step(), event);                                 \r
+                               if (self.timeout) {\r
+                                       window.clearTimeout(self.timeout);\r
+                               }\r
+                               self.timeout = window.setTimeout(function() {\r
+                                       if (self.spinning) {\r
+                                               self._stop(event);\r
+                                               self._change(event);                                            \r
+                                       }\r
+                               }, 400);\r
+                               event.preventDefault();                 \r
+                       });                     \r
+               }\r
+       },\r
+       _value: function(newVal) {\r
+               if (!arguments.length) {\r
+                       return this._parse(this.element.val());\r
+               }\r
+               this._setOption('value', newVal);\r
+       },\r
+       _getData: function(key) {\r
+               switch (key) {\r
+                       case 'min':\r
+                       case 'max':\r
+                       case 'step':\r
+                               return this['_'+key]();\r
+                               break;\r
+               }\r
+               return this.options[key];\r
+       },\r
+       _setOption: function(key, value) {              \r
+               switch (key) {\r
+                       case 'value':\r
+                               value = this._parse(value);\r
+                               if (value < this._min()) {\r
+                                       value = this._min();\r
+                               }\r
+                               if (value > this._max()) {\r
+                                       value = this._max();\r
+                               }\r
+                               break;\r
+                       case 'spinnerClass':\r
+                               this.uiSpinner\r
+                                       .removeClass(this.options.spinnerClass)\r
+                                       .addClass(uiSpinnerClasses + value);\r
+                               break;\r
+               }\r
+\r
+               $.Widget.prototype._setOption.call( this, key, value );\r
+               \r
+               this._afterSetData(key, value);\r
+       },\r
+       _afterSetData: function(key, value) {\r
+               switch(key) {\r
+                       case 'max':\r
+                       case 'min':\r
+                       case 'step':\r
+                               if (value != null) {\r
+                                       // write attributes back to element if original exist\r
+                                       if (this.element.attr(key)) {\r
+                                               this.element.attr(key, value);\r
+                                       }\r
+                               }\r
+                               this._aria();\r
+                               break;\r
+                       case 'width':\r
+                               this.element.width(value);\r
+                               break;\r
+                       case 'precision':\r
+                       case 'value':\r
+                               this._format(this._parse(this.options.value));\r
+                               break;\r
+               }\r
+       },\r
+       _aria: function() {\r
+               this.uiSpinner\r
+                               .attr('aria-valuemin', this._min())\r
+                               .attr('aria-valuemax', this._max())\r
+                               .attr('aria-valuenow', this.value());\r
+       },\r
+       _validChars: function() {\r
+               var radix = parseInt(this.options.radix);\r
+               return '\\-\\' + this.options.radixPoint + (this.options.groupSeparator\r
+                       ? '\\' + this.options.groupSeparator\r
+                       :'') + (radix < 10\r
+                               ? '0-' + radix\r
+                               : '0-9' + (radix > 10\r
+                                       ? 'a-' + String.fromCharCode('a'.charCodeAt(0) + radix - 11)\r
+                                       :''));\r
+       },\r
+       _parse: function(val) {\r
+               if (typeof val == 'string') {\r
+                       if (this.options.groupSeparator) {\r
+                               val = val.replace(new RegExp('\\'+this.options.groupSeparator,'g'), '');\r
+                       }\r
+                       val = val.replace(new RegExp('[^' + this._validChars() + ']', 'gi'), '').split(this.options.radixPoint);\r
+                       result = parseInt(val[0] == '-' ? 0 : val[0] || 0, this.options.radix);\r
+                       if (val.length > 1) {\r
+                               result += parseInt(val[1], this.options.radix) / Math.pow(this.options.radix, val[1].length) *\r
+                                       // must test first character of val[0] for minus sign because -0 is parsed as 0 in result\r
+                                       (val[0].substr(0,1) == '-' ? -1 : 1);\r
+                       }\r
+                       val = result;                   \r
+               }\r
+               return isNaN(val) ? null : val;\r
+       },\r
+       _format: function(num) {\r
+               var regex = /(\d+)(\d{3})/,\r
+                       options = this.options,\r
+                       sym = options.currency || '',\r
+                       dec = options.precision,\r
+                       radix = options.radix,\r
+                       group = options.groupSeparator,\r
+                       pt = options.radixPoint,\r
+                       neg = num < 0 ? '-' : '';\r
+       \r
+               for (\r
+                       num = (\r
+                               isNaN(num)\r
+                                       ? options.value\r
+                                       : radix === 10\r
+                                               ? parseFloat(num, radix).toFixed(dec) \r
+                                               : parseInt(num, radix)\r
+                               ).toString(radix).replace('.', pt);\r
+                       regex.test(num) && group;\r
+                       num = num.replace(regex, '$1'+group+'$2')\r
+               );\r
+\r
+               result = num.replace('-','');\r
+               while (options.padding && (result.length < options.padding)) {\r
+                       result = '0' + result;\r
+               }               \r
+               this.element.val(neg + sym + result);\r
+       },\r
+       _getOption: function(key, defaultValue) {\r
+               return this._parse(this.options[key] !== null\r
+                               ? this.options[key]\r
+                               : this.element.attr(key)\r
+                                       ? this.element.attr(key)\r
+                                       : defaultValue);\r
+       },\r
+       _step: function(newVal) {\r
+               if (!arguments.length) {\r
+                       return this._getOption('step', 1);\r
+               }\r
+               this._setOption('step', newVal);\r
+       },\r
+       _min: function(newVal) {\r
+               if (!arguments.length) {\r
+                       return this._getOption('min', -Number.MAX_VALUE);\r
+               }\r
+               this._setOption('min', newVal);\r
+       },\r
+       _max: function(newVal) {\r
+               if (!arguments.length) {\r
+                       return this._getOption('max', Number.MAX_VALUE);\r
+               }\r
+               this._setOption('max', newVal);\r
+       },\r
+               \r
+       destroy: function() {\r
+               if ($.fn.mousewheel) {\r
+                       this.element.unmousewheel();\r
+               }\r
+               \r
+               this.element\r
+                       .removeClass('ui-spinner-input')\r
+                       .removeAttr('disabled')\r
+                       .removeAttr('autocomplete')\r
+                       .removeData('spinner')\r
+                       .unbind(namespace);\r
+               \r
+               this.uiSpinner.replaceWith(this.element);       \r
+       },\r
+       enable: function() {\r
+               this.element\r
+                       .removeAttr('disabled')\r
+                       .siblings()\r
+                               .removeAttr('disabled')\r
+                       .parent()\r
+                               .removeClass('ui-spinner-disabled ui-state-disabled');\r
+               this.options.disabled = false;\r
+       },\r
+       disable: function() {\r
+               this.element\r
+                       .attr('disabled', true)\r
+                       .siblings()\r
+                               .attr('disabled', true)\r
+                       .parent()\r
+                               .addClass('ui-spinner-disabled ui-state-disabled');\r
+               this.options.disabled = true;\r
+       },\r
+       value: function(newVal) {\r
+               if (!arguments.length) {\r
+                       return this._value();\r
+               }               \r
+               this._value(newVal);\r
+       },\r
+       stepUp: function(steps) {\r
+               this._spin((steps || 1) * this._step(), null);\r
+               return this;\r
+       },\r
+       stepDown: function(steps) {\r
+               this._spin((steps || 1) * -this._step(), null); \r
+               return this;\r
+       },\r
+       pageUp: function(pages) {\r
+               return this.stepUp((pages || 1) * this.options.page);           \r
+       },\r
+       pageDown: function(pages) {\r
+               return this.stepDown((pages || 1) * this.options.page);         \r
+       },\r
+       \r
+       widget: function() {\r
+               return this.uiSpinner;\r
+       }\r
+});\r
+\r
+})(jQuery);\r