Spinning wheel on webkit for iPhone/iPod touch

I’m more and more amazed by the power of mobile webkit. I don’t love the iPhone that much, but as a web developer the beauty of CSS transitions, animations and transforms can’t pass unnoticed. This time I’m giving away a widget that resembles the native Picker View (UIPickerView) functionality but entirely built on javascript.

First things first. Have a look at the demo page or, if you don’t have your device at hand, watch the screencast I baked for you.

Please note that the script is in beta phase, I am publishing it to receive feedback and suggestions. In the next few days we should have a stable version.

Update 2009/03/16:
We are out of beta, the script is now stable and ready for production (hope so 🙂 ). In the zip I also included a minified (9kb) version of the script to save some bits of precious bandwidth.

Update 2009/04/19: the script is now compatible with full screen mode apps. It seems that in full screen mode preventDefault() and stopPropagation() placed in touchStart event are not enough to block the propagation of the touch event. Adding preventDefault() to touchMove event solved the problem.

Update 2009/06/18: the script has been updated for OS3.0 compatibility.

Update 2009/07/09: it turned out that Apple is well aware of the webkit refresh bug, fortunately they are kind enough to offer a workaround. All we have to do is to use translate3d instead of translate and all our animations will be fluid as never before! Go get the latest version of the script!

How to use the script

The widget is composed of two parts: the stylesheet and the javascript. No HTML is needed as all the elements are created by the script on the fly. Include both the JS and the CSS into your page and you are ready to spin. You’ll be also surprised to see that the spinning wheel itself is built with just two images, while other three images are needed for the header and buttons. The PNGs altogether are 4.3kb.

The code does not need initialization on window load. You cannot have more than one picker at a time, so the SpinningWheel object is unique and it is created as soon as you include the JS file.

The first thing you need to do is to define the slots with:

SpinningWheel.addSlot(obj values, str styles, str defaultValue)

values is in the form of: { key: value, key2: value, ... }. Keys are the identifiers that won’t be shown in the picker (think of them as the value parameter in the <option value="foo">bar</option> tag). Values are the labels printed on the slots.
styles is a list of space separated predefined styles to be applied to the slot. The available values are:

  • right, align text inside the slot to the right;
  • readonly, the slot can’t be spun;
  • shrink, shrink the slot width to the minimum possible.

The first element of the slot will be selected if no defaultValue is defined.

When all the slots have been created, set the default actions for the cancel and done buttons.

SpinningWheel.setCancelAction( function(){ } );
SpinningWheel.setDoneAction( function() { } );

Finally show the picker:


Voila, the Picker View is ready for countless hours of spinning pleasure.

To get the actual selected values call:

var result = SpinningWheel.getSelectedValues();

result.keys will be filled with an array of the selected keys while result.values will hold the list of the selected values (or labels).

Let’s wrap everything together.

function swExample() {
	var numbers = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9 };
	SpinningWheel.addSlot(numbers, 'right');
	SpinningWheel.addSlot(numbers, 'right');
	SpinningWheel.addSlot({ separator: '.' }, 'readonly shrink');
	SpinningWheel.addSlot(numbers, 'right');
	SpinningWheel.addSlot({ Kg: 'Kg', Lb: 'Lb', St: 'St' }, 'shrink');



function done() {
	var results = SpinningWheel.getSelectedValues();
	alert('values:' + results.values.join(', ') + ' - keys: ' + results.keys.join(', '));

function cancel() {

Look at the demo for more examples.

Create custom styles

I preconfigured for you three styles for the slots, but you can add as many as you need. Say you want a slot with center aligned text. Add the following to the stylesheet:

#sw-slots .sw-center { text-align:center; }

To apply the style create the slot like this:

SpinningWheel.addSlot(values, 'center');

A piece of cake.

By default the slots try to fit their content. Slots with long text will be wider than ones with short text. (Same as the <table /> cell elements). With custom style you can override this behavior. If you have two slots and you want them to be exactly the same width you may add the following style:

#sw-slots .sw-50percent { width:50%; }

and create the slots with:

SpinningWheel.addSlot(values, '50percent');

You don’t need to apply the style to both slots as the second will fit the remaining space (or the other 50% of the screen width).


None that I can tell if not those imposed by the device small CPU. All animations are hardware accelerated, the “birth date” example in the demo creates more than one hundred elements and all animations are pretty fluid.

The script is also compatible with both landscape and portrait mode and you can freely switch from one to the other while the spinning wheel is opened. (That is more than what the native Picker View has to offer).

Note that once closed the spinning wheel is completely inaccessible and all variables will be null or undefined. So basically you can’t programmatically query the SpinningWheel object while it is not visible.

I’m now working on code optimization to reduce memory usage, I hope to release a stable version as soon as possible. The code is now stable, please leave your comments and suggestions.

As always released under MIT license for all your coding needs.

Download the script

346 thoughts on “Spinning wheel on webkit for iPhone/iPod touch”

  1. Looking very nice. Liking the fluid animation when the picker appears. Often for me animation is jumpy.

  2. This is a marvel. Wonderfully done. My only comment would be that flicking each spinner could be a bit more fluid but otherwise a wonder!

  3. This is amazing!
    I’ve got a website where I can use it with!

    Best regards
    Gummy Media Ltd

  4. Is there a way to get a similar control working on firefox or a non-mobile browser?

  5. @Steve,
    yes, it’s not that difficult. First of all you need to remove all the CSS animations and related event handlers (ontransitionend) and replace them with a timed (setInterval) function (it’s a lot easier if you use something like jquery). You also need to replace touchstart with mousedown, touchmove with mousemove and touchend with mouseup. Probably you want to open a popup instead of making the control slide up from the bottom of the page.

  6. Is there a way to programatically set the wheels before or just after it appears? I’m looking to remember what the user chooses, then set it back to their previous setting the next time the spinner comes back up.

  7. @Russ, the “birth date” example in the demo page shows you how to do that. The third parameter of the addSlot method sets the selected value.

  8. dumb questions:

    Could images be used in the pickers? Sorta like your image of a slot machine. And then could the wheels be set into motion in a circular fashion, by clicking a button (or shaking like in UrbanSpoon)?

  9. @AwayBBL, images can be used but you probably need to play a bit with CSS and cellHeight (now fixed at 44px). Regarding the circular motion is feasible but probably it’s easier setting a 3d rotation, there’s an example about it on the apple developers’ site.

  10. Hi,

    I am able to get the spinning wheel working, but not when I use it with jQTouch.

    The javascript is all called correctly, but the spinning wheel doesn’t appear. I think there are some css conflicts or something.

    Anyone have any idea how to get the two to work together?

  11. Have you think about put a title in the top bar ? It would be very handy to know from which button the spinning wheel have been opened…

  12. @Matteo

    The script no longer works in 3.0 beta. Perhaps it’s an Apple bug, or maybe they’ve changed the way they handle touches?

  13. @AwayBBL, surely something has changed in os3.0, but the beta is still too buggy. I hope the next beta will be something we can work with, because so far it seems Apple forgot their loyal web developers 😉

  14. It doesn’t work in 3.0 beta as the webkitTransform call in getComputedStyle() returns a 2d matrix() and not a matrix3d(). I’m not sure why. Changing the index from 13 I think to 5 will make it work but still not as smooth as OS 2.2.1

  15. The reason for returning a 2d matrix is an optimization. A 3d matrix is returned if z-axis is used.

  16. There are better ways to get the y-axis than “split”, as soon as I get better I’ll show you how. (You can get a clue looking at the “Rotating wheel” code).

  17. Any reason why the spinner for the number of days flickers when selecting the year or month. This only happens in 3.0 beta and doesn’t happen in 2.2.1 where it’s fluid.

  18. Dumb question here…

    How would I be able to get the single wheel to load a new page when clicked?

  19. I am trying to make it work in iUI, but no luck, as soon as I load the iUI CSS, it stops working. Help will be much appreciated

  20. @Matteo

    Hope you are feeling well. Have you had a chance to look at how this works in 3.0GM?

  21. @AwayBBL: I’m still trying to recover from a very obstinate kind of illness. BTW, I’ll surely update my scripts as soon as the os3.0 is out.

  22. The spinner still flashes in 3.0 GM seed.
    It’s not as fluid as in OS 2.2.1

  23. Pugwash,

    Are you saying it works? I wasn’t able to make it work a all. It’d freeze on first item.

  24. Just updated to official OS 3.0 today and same problem.
    The wheel is also glued on the first item. We need to investigate this problem.

  25. The script has been updated. It should be compatible with OS3.0. I’ll try to find out why it is more fluid on OS2 than on OS3, maybe something changed in the css transactions engine.

  26. Ok, the wheel is now “wheelable” on OS3.
    But effectively, the animation is quite unusable because really not so smooth as it was on OS2.

  27. Is there an iPhone forum/board explaining the major/minor diffs in the webkit between OS2 and OS3 ? This may be useful to understand why the wheel’s animation is not smooth with OS3.

  28. @Matteo

    Thanks for getting spinning wheel working again.

    Agree with the other folks that it’s still a little choppy, and it flashes the background, but at least it works.

    Hope you can make it work smoothly again.

  29. I am struggling to figure out the changes between 2.0 and 3.0. The reported “freeze” after a touchstart event is similar to what I am experiencing. All is fine until the first touchend is fired. What was changed in this to make it 3.0 compatible?

  30. this is a great product, has anyone gotten it working with the iWebkit framework? I have been unsuccessful, it fails on the var results = SpinningWheel.getSelectedValues(); call, just sits there and does nothing.

  31. Did anyone figure out how to get it to open a html link when the “Done” button is clicked?

  32. @mike: syntax to open a link from JS is window.location.href="http://example.com";. You probably want to pass the selected values to the page. Something like window.location.href="http://example.com?value=" + results.value[0]; should work.

  33. This is really wonderful Iphone WebApp for date picker and any other selection u need. I made it work perfectly with iwebkit and it works like charm. Please contact me if you need any help on how to use it with iwebkit. I made few changes to create a proper date picker with only the valid date selection possible.

    1. hello ska_lit, i am working on an iWebKit site and want to integrate iScroll as well. i would really appreciate any sample code or help you’ve shared with others on how you got them to work together?

  34. @ska_iit: if you want to share a mod to this script please send it to me (hint: matteo at-this-domain), I’ll be glad to publish it (please remember that I release all the scripts under the MIT license).

  35. I am interested in knowing how to validate the days in a month

    for instance if sept is picked only show 30 days
    or october show 31 days, and so on

    is this possible with this script?

  36. Hi, Great piece of work!

    Any advice on getting this to work in jQTouch framework? Would look great on a project I am working on.


  37. Thx guys for showing interest… please let me know how and where to send the updated sample?

    1. Hi ska_itt

      Will you please send me your code for making a proper date picker with only the valid date selection possible.
      david (at) bjornhart.dk, thanks!

  38. can send me an email at, mylivingweb (at) gmail.com

    i would greatly appreciate it.


  39. Hi Matteo,
    I sent one test email to you, let me know if you received it.. then I will send the code also.

    Dave, Matt
    I sent the sample code to the above given email addresses.

  40. I have not tried with the JQtouch..i made it work with the iwebkit only

  41. love this, its great, question, built in scroll wheel for iphone allows you to touch instead of dragging the bar like here, curious when you’ll have the ability to touch the wheel selection item instead of dragging the frame. again, love your work, its just awesome, shows web apps can do as much if not more than embedded, gonna try this script with pre and android to see how they react aswell, keep up good work

  42. This is wonderful, any plans on getting it to work with JQTouch as well? it works somewhat when the jqtouch.min.css file isn’t added, but not at all when it is. Still a great piece of work!

  43. @Bruce T, I’d like to build a completely native and independent framework for iphone and android (no jquery, iui, whatever dependency). The iScroll is just the base for it.

  44. The component is great! I modified the script a little so that SW can function within my iui based iPhone app.

  45. Julian & Bruce T,

    I’ve been working with jqtouch as well and the conflict is easily fixed with a few tweaks to the css. Note that one of the first selectors in the jtouch.css hides all elements under the body tag, so what we have to do is reinforce a couple selectors in spinningwheel.css to make sure certain element styles wont get stomped on.

    The primary one is here:

    #sw-wrapper {
    position:absolute; z-index:1000;
    display:inline !important;
    min-height: 0px !important;
    font-family:helvetica, sans-serif;

    You must add display:inline !important; and min-height: 0px !important; otherwise the container will inherit these values from jtouch.css and you don’t want that.

    The other change is here:

    #sw-slots li {
    border-top: 0px solid black !important;
    color:#000000 !important;
    padding:0 8px;
    font:bold 24px/44px Helvetica,sans-serif;

    Again, you must add border-top: 0px solid black !important; and color:#000000 !important; or they will get inherited from theme.css (at least they will in the apple theme) and that makes the list items get out of sync and look all messed up.

    With these two tweaks you will be able to see the control slide up into place and operate as advertised. You will still have to wire your cancel and done actions of course, but this will get you on your way.

  46. Hi guys

    i have a tough one, (although its probably something easy that i’m missing) i need the keys to show the 0 for example

    Original code
    var months = { 1: ‘Jan’, 2: ‘Feb’, 3: ‘Mar’, 4: ‘Apr’, 5: ‘May’, 6: ‘Jun’, 7: ‘Jul’, 8: ‘Aug’, 9: ‘Sep’, 10: ‘Oct’, 11: ‘Nov’, 12: ‘Dec’ };

    Tried this
    var months = { 01: ‘Jan’, 02: ‘Feb’, 03: ‘Mar’, 04: ‘Apr’, 05: ‘May’, 06: ‘Jun’, 07: ‘Jul’, 08: ‘Aug’, 09: ‘Sep’, 10: ‘Oct’, 11: ‘Nov’, 12: ‘Dec’ };

    but results.keys.join(‘-‘) still outputs 2009-1-1 instead of 2009-01-01 as you can see i need it this way for a sql query

    any help would be great


  47. Hi Brian,

    You can use pop() to get the value from results.keys and check the value to see if it is greater than 10 to add ‘0’ if necessary.

  48. Hey guys, i’m having one problem that maybe you can help with. I used this script on a text box input, but it comes up behind the default iphone keyboard and the user must first know to cancel the keyboard to use the SW. is there any way to stop the default keyboard from coming up?

    any help would be a life saver


  49. hey… gr8 script as always… a lifesaver.
    1 prob though… i am calling it on click of a button and it comes up fine bt the prob is, when it loads, it comes up without any images ie pure numbers and stuff… then in a fraction of second css loads up and the SW is up to go… i just wanna know if its possible that we dont show up an ugly SW coz its ruining all the beauty of it…

  50. Is it possible to have a true “wheel” where the data reaches the upper limit and restarts the lower limit? Any chance of including the clicky sound?


  51. Hi

    Here is few step to make it works in Safari , Chrome & Android browsers.

    Just replace event names
    touchstart -> mousedown
    touchmove -> mousemove
    touchend -> mouseup

    e.targetTouches[0].clientX – >e.clientX
    e.targetTouches[0].clientY -> e.clientY

  52. Hi

    If you want integrate with iUi .Add the following to iui.css

    body > #sw-wrapper {
    display : block;
    min-height :0px;

    body[orient=”landscape”] > #sw-wrapper {

    min-height: 100px;

  53. @venkat: yes it would be possible to add some preloading. I’m a bit busy at the moment but that is a feature that I’m going to add to the iScroll and the spinning wheel is actually based on iScroll. So as soon as iScroll v3 will be ready we will have a better spinning wheel as well.

    @Daniel J. Pinter: it is possible to have an “infinite” loop. We can do it in two ways. The first one is by replicating the content and keeping the control in 2D. The second would be to turn the control 3D. I’d like to try the second option, but there’s a lot of coding involved.

  54. A great, great script – thanks so much! Works great on the iphone, and I’m trying to get it working on Android (Nexus One). If I run the script as-is, the wheels scroll great, but all other events on the screen don’t work – Cancel, Done, and my menu buttons are “dead.” I blindy tried the code changes in comment 84, but that brought no joy. I’m wondering if I need to ADD mouse events instead of replacing the touch events, and add them for the Cancel and Done buttons? Or is some lockScreen function not getting undone? As you can tell, my JavaScript skills suck … anyone figured out the Android secret?

    Many thanks.

  55. I am having terrible trouble getting this to work with jQtouch. From what I’ve read in the comments quite a few people have gotten it to work with the provided solutions. I’d really love to inspect there implementation of the Spinning Wheel. Can I please see what you’ve done to get the Spinning Wheel working with jQTouch.

  56. Regarding JQTouch, make sure to get the latest build (131 or 132?). The create a #jqt namespace that allows Spinning Wheel to work … and did it primarily for Spinning Wheel.

  57. Okay, I’m going to load up build 132 and see how it goes, will report back. Will also try and create the #jqt namespace. (ps. do you have an example of your where you have it working with jqtouch, would be extremely helpful, thanks).

  58. I would think 24px would be a bit much. I changed it to 18px for the font #sw-slots li and it works much better…especially on longer items.

    Did you just choose 24px or were you guessing? (please take no offense…just asking)

  59. Hi ska_iit, Can you e-mail the updates that you made for iWebKit, please..
    E:Mail: vijishvanya at gmail

  60. Any chance to add a “select” feature on click … like in the apple spinning wheel? Ie: If you touch a selection and release, it will auto-scroll that selection into the “selected area” gray bar and that way you do not have to scroll up.

    For instance, say you have

    showing in spinning wheel and 2 is highlighted. Say you touched BUT DID NOT SPIN 3. 3 *should* (according to the “apple” spinning wheel on the iphone) checkmark itself. (in this case not a checkmark, but 3 should become the selected item.

    Any chance?



  61. oops..For some reason I had JavaScript off on my iPhone Safari Settings. The demo shows good now. Great script. Thanks

  62. @matt:
    can you please tell how i can i test spinning wheel on windows OS ,tried to load on palm emultor and couple of simulator didnt worked

  63. Hi ska_iit:
    Could you please send me the code modification you did for it to work with iWebKit?

  64. looks very good. Comparing with the native picker, its lacking to loop a certain slot option. (Like hours going from 1-12 and continuing back to 1 in the same slot)
    Do you plan to add this in the near future? Thanks again.

  65. I thinks this is great, I would like to know how to use it for multiple date elements on the same html form without repeating the code for each date element.


    1. What I did Mark was to set some vars up to elements I wanted the data to go to. Then within the click event of the function i set the element names.

      So within the done function I could easy set where i wanted the data to go ie,
      var elementDate = ‘checkindate’;

      function checkoutDate()
      elementDate = ‘the_element_id’;

      function done()
      var results = SpinningWheel.getSelectedValues();
      $(“#”+elementDate).val(results.keys[0] + ‘/’ + results.keys[1] + ‘/’ + results.keys[2]);

      Hope this helps someone

  66. if i use it inside -tags it the wheel-div disappears shortly after the beginning of the animation. am i missing someting?

    thanks for your help!

  67. @Brian S.

    Did you find a solution for suppressing the keyboard on text input?
    My workaround is to use a DIV with an event handler showing the formatted date and a hidden input holding the date value for form submission.

  68. This looks like a great component, I was thrilled to find it!

    Is it possible to decide how many slots should be shown? As it is now it seems to be set to 5. In my case 3 would be more suitable.

    Is it possible to decide where on the screen the SW should be shown? As is it is now it’s always located at the bottom I think. In my case I would like it to be positioned higher up (in conjunction with a button the user will press).

    I’ve looked around a bit at the code but not yet managed to solve these two issues. Any pointers would be appreciated.

  69. I’m trying to get this code to work with iWebKit and have gotten it to work I think, but cannot figure out how to submit the result. Any help would be appreciated. davynixon at g mail.

  70. Ska_lit,
    Can you post or send the mod to make the date valid?
    or email me at danbodenstein at g mail dot com

  71. hi,
    same problem like #105:

    if i include it inside my form-tags, it disappears immediately after the click and the form “autosubmits”.

    any suggestions?


  72. I have a fix for android devices:

    change lines:
    30 this.tapDown to this.tapUp(e);

    comment out the following lines

    38 // this.tapCancel(e);
    44 // this.tapUp(e)

    The android devices are triggering a touchMove event after clicking on the done and cancel buttons. In the default implementation touchMove will cancel the action as it is meant to catch people who drag their finger off the done event .

    I haven’t tested this on iPhone yet but I imagine it will work as well.

  73. Would be nice to have a date picker demo for use in a form. Can anyone provide? Thanks!

    1. I’ve seen a few comments regarding this, so it seems like it can be done….can anyone help? I just want the results to be put into an input or some element the form will be able to send vs. a tag……Anybody?

  74. I have a HTC Desire and followed the information regarding Android mods in posts by Vivek 09/01/10 and your post here but the ‘Cancel’ or ‘Done’ buttons are VERY unresponsive the majority of the time only chance of getting them to work is to tap really quickly and firmly with top of finger tip.

    Can we have a Android 2.0+ fully working version?


  75. Hi all

    I am unable to implement this along with JQTouch. Does not give an error, but does not appear either. Though I am able to see the html generated using web inspector.

    Please help. If possible please upload the code where it is implemented with JQTouch

    1. Hi,
      did you find any solution for that problem? I also want to use it with jQTouch, but even if I copy and paste the example in my project, it does not work. How did you fix that? I´m stuck on it, please help…


    2. spinningwheel wrapper div gets added as a child of body, so it litterally is a jQT page on its own when it is crated, not as a child of the current page, so, just navigate to it by using the jQT public object goTo function:


      in your close/done events, you can then do

      close() { jQT.goBack(); }

      for example to navigate away from the spinner, also you can grab the usual jQT pageAnimationEnd and pageAnimationStart events by binding to the wrapper:

      $(“#sw-wrapper”).bind(“pageAnimationStart”, function() {} );

      If you want the spinner to appear within another page, then you can detach and append it with jquery

      mySpinner = $(“#sw-wrapper”).detach();
      $(“#mySpinnerPage”).append( mySpinner );

      Hope that helps!

  76. I’m having a problem using the data from a SpinningWheel. It seems that whenever I call SpinningWheel.getSelectedValues() my JS stops processing. I can do whatever I want with the Cancel and Done actions, so long as I don’t try to see what I have selected.

    1. I am also having the same problem. I found that if I remove from the HTML file in the the following:
      …then the getSelectedValues() works.
      This is not a workaround however, as I need to include the parts.js

    2. I have the same problem. I narrowed it down to the reference to parts.js in the HTML file. if you remove the reference then the getSelectedValues works. So, something in parts.js is killing the script.

    1. Hi,

      It would be absolutely fantastic if you can get the spinning wheel to work on the HTC Desire….somewhere I read you had one of these phones too.

      Look foward to the next release.

    2. Hi Matteo

      Any updates on the new version? I am eagerly waiting for this.


  77. I have a form with 4 text fields that need to capture a date. I got this script working when I click on the first text field it’ll bring up the spinning wheel, I select the date and it puts it back into my text field. How can I use the same function (I adapted the openBirthDate() function) to output in the 4 different text fields? Someone at JQTouch offered this solution, which makes sense, but after I bring up the spinning wheel, clicking Done does nothing.

    First change openBirthDate() to openDate()

    Then Add the variable to find which ID to associate it to. My example is:

    var $which_date = null;
    function openStartDate()
    which_date = $(“#startdate”);
    function openEndDate()
    which_date = $(“#enddate”);

    And then change function done() to:

    function done() {
    var results = SpinningWheel.getSelectedValues();

    My text fields are:

    Can anyone help?

  78. Is it possible to use the Spinning wheel module with the iScroll module? I can’t seem to get the two working together. When i try to add the Spinning Wheel module to iScroll, it displays briefly, then disappears before I can select anything from the spinning wheels.

  79. Do you have plans to or a timeframe for making the images high res for the retina display on iPhone 4?

  80. I have a problem. I am using it for checkin and checkout dates on the same form. I’ve created different events to fire those.

    But while the sw is on for checkin date and i fire the event for checkout date, it does not clear the data, rather adds more slots to the existing sw. I tried closing the sw before opening it again but all in vain.

    Will appreciate any help.

  81. Hi,

    I am trying to create a picker using HTML 5 and Javascript which can be run on Webbrowser and then can be turned into a webapplication for android phones using phonegap.

    Any ideas on how to create this? Code would be helpful.

  82. hey there, how do I test it after i download the script file?

    sorry im quite green in iphone app..

  83. Hi,

    Thank you very much for such a wonderful plug-in 🙂

    But in our application, window.innerHeight is returning document height instead of window height. So spinning wheel is always displaying at bottom of document and its not visible. Could you advise any fix for this?


  84. Ok, probably a complete noob question, but do I have to have webkit for this plugin to work?

  85. Thanks Matteo. After opening spinning wheel, I’m trying to dynamically set the “sw-wrapper” position dynamically as follows.

    document.getElementById(“sw-wrapper”).style.top = 420 + window.pageYOffset + ‘px’;

    So that it will work fine in “Portrait mode”. But window.pageYOffset is always returning “0” irrespective of page scoll position. Any clue on this?


  86. Hi Matteo,

    It seems like “window.pageYOffset” does not have any effect on iPhone and its always returning “0”. You may check this and you may modify the code.

    Since our pages are long, by default we are not able to see the spinning wheel. So after opening spinning wheel, I’m scrolling to spinning wheel using following code.


    I’m also grabbing the element id which has initiated the spinning wheel and I’m storing it in JS variable. Once the user click on Done or cancel, again I’m scrolling back to ‘the element’ using following code.


    I’m just sharing this as it can help others who are facing similar issue.

    Thanks and Regards,

  87. To get it working with jQTouch, just add the following to your own css file:

    #sw-wrapper { display: block; min-height: 0 !important; }
    #sw-slots ul { font: normal normal bold 16px/normal Helvetica; color: black; border: none; }
    #sw-slots ul li { color: black; background-image: none; border: none; }

    I used Chrome to compare the final CSS of the main elements of the demo with the one produced when using jQTouch and the jqt theme. If you’re using another theme, you may (or may not) need to override other jQTouch styles.

  88. This is a really cool plugin though I’m missing a feature to close the wheel. I tried


    but it seems to destroy the whole spinning wheel. Such a feature would come very handy when you have two different slides on one page and the user selects the other slide while the first one is still opened. Currently the new slots will just get added to the already existing slots (you have that problem in your demo too!).

    1. Could you not add it inside a div, or move it inside a div after opening it, then simply show / hide that div without “closing” the spinner? That should work…

      Best from Prague 😉


  89. Any news on the updated date picker?

    Also, I’m interested in backfilling single digit date and month fields so that I can use the results in a mysql date field. Has anyone done this?

    Thanks, and good work here!

  90. Is it totally impossible to change the values and make it to a calendar who have:

    This day, this month and this year

    and update it self automatic?

    I tryed but it won’t work!

  91. Thank You for this widget. I want to know how we can make one slot dependent on another. For example if I have 2 slots and if I change the value on slot 1, slot 2 should load new set of values.

  92. I needed a way for this to update UI cues as the user is selecting a value, without them having to click Done (like the native spinner does). So I added a callback procedure to the script to allow this to happen. Essentially, add this to the handleEvent function, right after the call to this.scrollEnd(e):

    if (typeof this.valueChangedCallback == “function”)
    this.valueChangedCallback.call(this, e);

    Then add in a valueChangedCallback property somewhere:

    valueChangedCallback: function(e)
    { }

  93. you’re a life-saver!! it took a while to format your one-liner js file dough, my vs2008 wouldn’t hack it.

    and i would suggest defining the wrapper div in the target side instead of in the js, so that device-frameworks that use transitions between divs could display the sw without altering the js.

    thanks from norway!

  94. i’ve altered the open method to include my container div-id as parameter (instead of adding and removing sw-wrapper div to the body element), and it works perfectly! 🙂

  95. when i try to add the iui.css file to the index.html file in the demo the demo button does not display. only the text.

    the offending text in iui.css seems to be here

    body > *:not(.toolbar) {
    display: none;
    position: absolute;
    margin: 0;
    padding: 0;
    left: 0;
    top: 45px;
    width: 100%;
    min-height: 372px;
    -webkit-transition-duration: 300ms;
    -webkit-transition-property: -webkit-transform;
    -webkit-transform: translateX(0%);

    if i comment out all but the last 3 lines everything displays

  96. Great work – thanks for such a necessary plugin for phoneGappers 😉
    Could you give us an idea when the new script might be ready?
    And will the upgrade be seamless? I mean, if I implement this version, will I be able to do a straight swap with the next version and just gain more functionality / stability, or would you advise me to wait for the new script?
    Thanks again



  97. Well that´s ok for me. I just made a small datetimepicker and it works fine. Thanks for the code. Much appreciated.

  98. Is there any way to make this work with a web form? I would like the results to replace the value of a text input.

    ETA on a new version of the script?

  99. I am hoping to use this and then set a localStorage.variable. I’m new to this…can anyone help with hints/suggestions please?


  100. The following patch avoids the problem of having multiple nodes with same id populating over and over again in the page when the new pages are loaded using ajax:
    // //Remove any existing node with the same id.
    if (document.getElementById($node.attr(‘id’))) {
    $(“#” + $node.attr(‘id’)).empty().remove();

  101. using jQuery a better way to do the same (above)

    //Remove any existing node with the same id.
    if ($(“#”+$node.attr(‘id’)).length > 0) {
    var data = $(“#”+$node.attr(‘id’)).html();
    console.log(“Removing ” + data.length + ” bytes of flab!”);
    $(“#” + $node.attr(‘id’)).empty().remove();

  102. You have spared me one quite a long coding session.

    Thanks a bunch.

    P.S. For those in doubt, yes, it works well on the iPad.

  103. I am using a single slot spinner on an iphone app.
    I want open up a “new page” by clicking the selection shown on the spinner. I am not interested in displaying the selected key/values as is shown on the demo.
    Is this possible to call up a page which is relevant to the selection on the spinner
    If so how do I implement it?

  104. so, after some adjustments i have finally suited your sw to my needs and there is one thing, which you might want change:

    If the sws width is not 100% of the screenwidth and the sw-wrapper is positioned arbitrary on the page, the scrolling does not function anymore. To quick fix this change the xPos in the scrollStart function to this: xPos = e.targetTouches[0].clientX – this.swSlots.offsetLeft – this.swWrapper.offsetLeft;

    Just on a personal note, I find your method of determining the currently scrolling slot rather heuristic. IMHO this should be done via assigning an eventlistener to each slot, so that the browser does the determination automatically for you.

    Anyways. thanks for sharing the script. Good job.

    1. why “heuristic”? The chances of taking the wrong slot are very small, and working with just on eventlistener saves a lot of resources.

  105. Cool!

    I’m rather new to jQuery but is it possible to show the sw in a popup like the way bookmarks are shown in safari on the iPhone/iPad? (window with neat pointer)

  106. I am using it from my iPhone in debug mode.
    Sometimes I get this error :

    Javascript Error on line 1 ..min.js?v=1.4
    TypeError: Result of expression
    ‘e.targetTouches[0]’ [undefined] is not an object.

  107. How do I call the SpinningWheel function from my HTML?

    I want that a new page opens when the user taps on a date and the spinning wheel should immediately pop up on the new page. If I write something like this:

    <a href=”#date” rel=”nofollow”>

    the picker won´t show up. #date is the new page where the picker should pop up. How should I call the picker so that it shows up on that page?

    1. Hi,
      I am having a similar problem. I put an onClick event in my href tag, so that the function is called.
      It all goes pretty well in desktop Safari (ok, you can’t spin, but anyway) and even if I change the user agent to Mobile Safari it works. However, when testing on an iPhone, the wheel’s gone!!!

      Does anybody have an idea why??? Please, any help is appreciated!

  108. Hi!

    Thank you for this great tool!

    Is it possible to prevent “opening” more than once SpinningWheel? Even in your demo page, when I click the demo botton several times, more than one SpnningWheel opens next to each other…

    Thank you.$


    1. Hi,
      you can prevent “opening” more than one SpinningWheels if you check whether the object already exists. In the demo the SpinningWheel pops up as often as you click the corresponding button since it is in an onClick event.

      Hope that helps!

    2. techcrunch2,

      After playing around a bit, I found a solution for the problem with opening multiple wheels at the same time. In spinningwheel_load.js, as the first line in each occurrence of a openXXX function, place a test for “sw-wrapper” and exit if it exists…

      function openBdate() {
      if(document.getElementById(‘sw-wrapper’)) { return; }


    3. Jack,

      Thanks for the simple resolution. I can confirm this works perfectly, even with multiple pickers in one window.

  109. Great solution !!
    I am a newbie to JS in general and have 2 questions.
    1. Is there a way to allow a wheel to loop around, the native picker does that for some of the wheels. For example in the Weight picker in the sample, I want the number wheels to just loop

    2. Is there a way to grey out invalid choices ?
    For instance in the Date picker, for the month of February, I would like to grey out 29,30,31.

    I checked the previous threads and these questions have been asked but didn’t see a solution.

    Please help…

    1. I am also tring a similair thing. Like to generate an event on selection of a particular value. Are you able to find any solution . Please help….

    2. SpinningWheel.setDoneAction(function(){
      var results = SpinningWheel.getSelectedValues();
      var y = results.keys[0];
      var m = results.keys[1];
      var d = results.keys[2];

      return m > 0 && m 0 && y 0 && d <= (new Date(y, m, 0)).getDate();

  110. Really nice, but. If I try the following:

    SpinningWheel.addSlot(letters, ‘right’, tmpA[0]);
    SpinningWheel.addSlot({ separator: ” }, ‘readonly’);
    if (tmpA[1] != null) SpinningWheel.addSlot(numbers, ‘right’, tmpA[1]);
    if (tmpA[2] != null) SpinningWheel.addSlot(numbers, ‘right’, tmpA[2]);

    If doesn’t work. I get bogus data where the default values should be.
    tmpA = {Y, 3, 9} shows as X, 7,1 and the characters are not centered horizontally.

    If I comment out the first line, all is well. But that’s not what I need.

    Data is:

    var numbers = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9 };
    var letters = {‘ ‘: ‘ ‘, A: ‘A’, B: ‘B’, C: ‘C’, D: ‘D’, E: ‘E’, F: ‘F’, G: ‘G’, H: ‘H’, I: ‘I’, J: ‘J’,
    K: ‘K’, L: ‘L’, M: ‘M’, N: ‘N’, O: ‘O’, P: ‘P’, Q: ‘Q’, R: ‘R’, S: ‘S’, T: ‘T’,
    U: ‘U’, V: ‘V’, W: ‘W’, X: ‘X’, Y: ‘Y’, Z: ‘Z’ };

    I can’t see anything obviously wrong in the code. Is it me?

    1. Update after much instrumentation. Code above reliably yields correct first letter value and spin range . But the numbers are one less than they should be and the spin range is also off by one (i can’t spin to 9).

      If I remove the letter slot, numbers work fine.

      slotMaxScroll and yPos seem to be correct up to the
      serPosition call, and then the wrong values appear.

      Very weird, and a heartbreaking showstopper for my use.
      Any clues much appreciated.

  111. This is great. Thank you.

    I have a wheel with two slots (date and month), and need to input the two keys separately in two different locations in a generated URL. How can I split up the keys-result, instead of it being (0,0)? Or in the following code, is it possible to call the var “months” or “days”?

    function done() {
    var results = SpinningWheel.getSelectedValues();
    window.location.href = “http://www.example.com/example.aspx?format=png&week=”+results.keys+

    Any help is greatly appreciated!

    1. It’s an array of values.

      months = results.values[0];
      days = results.values[1];

      ought to work. I use

      newQty = results.values.join(”).replace(/^0+/, ”);

      to make my multi-digit spinner return one value.

  112. I use it with JQTouch, and need the input values to load an image to a and the DONE function to bring me to it.

    Is this possible? Can someone point me in the right direction?

  113. Anyone know howto get the year to go from 2011-1911 to 2011-2021?

    Ive tried playing around with

    for( i = now.getFullYear()-100; i < now.getFullYear()+1; i += 1 ) {
    years[i] = i;

    But I seem to be messing this thing up!

    1. Probably a little late for you but in case anyone else is looking:

      for( i = now.getFullYear(); i < now.getFullYear()+11; i += 1 ) {
      years[i] = i;

  114. This is a great tool!

    However, I am having one issue on the iPad. In a form, I have a series of text boxes. Some of the textboxes I have regular keyboard input method and for others I have the spinning wheel method where I use jQuery :
    $(“#”).click(function(event) {

    I am noticing that while I have not chosen the spinning wheel method, my inputs are rendering fine, but once I use the spinning wheel method, my inputs are not rendering as they should.

    Is anyone having a similar issue?

    *I have no screen shot or link, sorry 🙁

    *preventDefault() does not stop the keyboard from from showing, however using “onFocus(blur());” does stop the keyboard from popping up

    1. Spinning Wheel is designed to be modal.
      Everything else should block when it is up.

    2. Thanks Lou but that wasn’t it. I found that it was a combination of “position:relative” and a firmware update… go figure huh? haha

  115. Anyone… I would like the date picker to default to the current date on load… any ideas?

    1. var now = new Date();

      SpinningWheel.addSlot(years, ‘right’, now.getFullYear());
      SpinningWheel.addSlot(months, ”, now.getMonth());
      SpinningWheel.addSlot(days, ‘right’, now.getDate());

  116. Would love if the default iPhone spinner sound, as well as a custom one if needed, was an option.

  117. Pardon my ignorance, but how can I construct spinner data on the fly? I want to read from my database and use the results as a selection set. Can’t figure out the syntax of the example static data.

    Any pointers appreciated.

    1. LouMazz,

      Create a PHP function (or use any dynamic server-sided language of your choosing) that writes a javascript to assign the variables. The script can be just about anywhere on the page. Remember, If it is assigned outside the SW functions, it will be global, so name the vars such that they won’t interfere with anything else. For example, if you wanted to assign an array of values…

      $sql = "SELECT * FROM mytable WHERE….
      $res = mysql_query($sql);
      while($row=mysql_fetch_array($res)) {
      $myOptions[] = $row['myCol'];
      print "var myOptionStr = ‘”.implode(“,”,$myOptions).”‘;n”;

      Then in spinningwheel_load.js, assign the necessary local variable to the global “myOptionStr” that you set with PHP and use JavaScript .split() to turn it into a JS array. (You can, of course, do the same thing with string vars rather than arrays.)

      There are many ways to do this, but this is the method I typically use. Hope that helps.

  118. Sorry about that, LouMazz… Mateo’s blog routines stripped out some of the code. The printout of “var myOptionStr …” WAS surrounded by script tags to be printed as well.

    1. Many thanks – I used your comments to write a client-side version:

      // construct list list for list spinner
      $(‘#listListBody ul li input’).each(function(index) {
      listList[i] = $(this).attr(“menuname”);
      listListString = implode(“,” , listList);

      where “implode” is:

      function implode(delim, ary) {
      out = “”;
      for(i=0; i<ary.length; i++) {
      if(i!=0) { out += delim; }
      out += ary[i];
      return out;

      Works great.

    2. Jack:

      Here’s how to REALLY do it. This will allow a default setting to appear in the spinner. What needs to be constructed is an object, not an array. This allows setting key/value pairs:

      // construct list list for list spinner
      listList=new Object();
      $(‘#listListBody ul li :radio’).each(function(index) {
      listList[$(this).attr(“menuname”)] = $(this).attr(“menuname”); //key : value

      et voila!
      Then one can write:

      SpinningWheel.addSlot(listList, ‘right’, current);

      where “current” is a value, and get the correct behavior. Just using the array approach
      will allow selection, but not default setting.

  119. I discovered something today as I was testing an app that I’m working on… something that may or may not have happened before, but that at least I didn’t didn’t notice previously.

    When I initially made a selection from the spinner the form field from which the spinner was opened was updated immediately. If I then went back to that spinner and changed the value, the actual value was changed, but the “displayed” value was not. This was a bit confusing, because as soon as I clicked on the field again, the displayed value was updated upon opening of the spinner.

    After a bit of playing around, I discovered that I could overcome this by issuing a jQuery .blur() command on the field ID at the end of the done() function. I thought I’d mention it, just in case anyone else had seen the same scenario.


  120. I need to achieve the following:

    1. A mobile webpage for android phone with two parts, the top section for a dynamically loaded image and the bottom section with the spinner.

    2. MYSQL db that contains the following:

    – Country Field
    – Country Image
    – City
    – City Image
    – Team
    – Team Image

    3. PHP server side script that interacts with the javascipt and spinner.

    4. Spinner with 3 sections:

    – Country
    – City
    – Team

    5. When a country is chosen the image of that country is shown above the spinner and the City section is populated with related cities from the MYSQL db via PHP.

    When a city is chosen then the city image is shown above the spinner and the team section is populated with related teams from the MYSQL db via PHP.

    Finally when a team is chosen then the team image is shown above the spinner.

    If a country is rechosen then the city and team sections are returned to blank and the country image is shown aboe the spinner.

    Can anyone help with this or similar example.



  121. Moving from jQtouch r159 to r165 changes Spinning Wheel behavior. In r159, all events except SW ‘cancel’ and ‘done’ are
    blocked while SW is on screen. In r165, everything is enabled even when SW is up. This causes all sorts of badness.

    Any chance of bringing SW in phase with r165? I’m stuck at
    r159 until I can figure a workaround.

  122. Hi,
    I need to execute a JavaScript statement(lets say an alert box) before invoking the methods for “Ok/Cancel” click. I can’t put this statement(alert box as per description) inside the methods specified against Ok/Cancel (due to business constraint).
    What changes will I have to make in JS to make it happen?
    Below is some snippet that i wrote but can’t check bcoz iPhone malfunctioning. Can anyone please confirm?

    tapUp: function (e) {

    if (e.currentTarget.id == ‘sw-cancel’) {
    alert(‘Cancel Clicked.’);
    } else {
    alert(‘Ok Clicked.’);


  123. Hi,
    I am using the spinningwheel on a mobile iPhone jQTouch offline App; when I clear the cache and start my application
    all goes well (of course after all components of the App: css, js,
    html, images etc have been loaded) including the spinningwheel; But if I close the app and reopen it again (all is offline) then the spinningwheel stops functionning and the console sends a js error saying that the variable SpinningWheel
    is undefined. Any idea of what might be causing this?
    Please help; and thanks in advance.

  124. Hi again,
    As I mentioned, my app on iPhone as a WebApp works perfect as long as its not off line (i.e without cache.manifest); Yet, when
    the manifest is added to the tag and the app is loaded for the 1st time it will still work perfectly. But once I add to the iPhone HomeScreen, quit the app, and then inter it through the homeScreen Icon then the SpinningWheeel will no longer work
    giving the console error message : Referrence Error : Can’t find variable : SpinningWheel when it goes to create a dateTime Picker. The only thing I would think of is that it can not coexiste with jQTouch once Offline. Put differently; Did any one manage to make it work within an offline webApp that uses jQtouch without PhoneGap? Knowing that I’m using the lates jQTouch with the #jqt wrapper etc.
    Did Any one have such a problem and how did he solve it?
    thanks to all for their contribution; any example could help.

  125. very strange. have you tried by placing the spinningwheel script into a namespace (function(){})(); ?
    Of course you have to expose public methods

  126. Has anyone managed to get the onscreen keyboard out of the way on the iPhone? blur() succeeds but makes the spinning render oddly and not responding to touch

  127. to hide the kyboard just add the following function call hideKeyBoard() to your javascript just before the SpinningWheel.Open() function call.

    and here is the function :
    function hideKeyBoard() {
    window.setTimeout( function() {
    $(‘:focus’).blur(); //hide kyboard
    }, 5);

    For Matteo Spinelli : I did not manage to make a namesapce
    for the SpinningWheel object yet; have you tried already and any code snippet could help; thanks in advance.

    1. I also found that if triggering this from an input field, making the input field readonly does the trick.

  128. Hi Matteo and all,

    I finally found my error; In fact I forgot to take away the variable :
    ?v=1.4 from the spinningWheel url which explains why it worked well online but not offline; In addition the wrapping as an object within the script spinningwheel.js in the statement :
    var SpinningWheel = { ….} had no conflict with jQTouch and I do not need a special nameSapce for it niether; Hope this could help you all. One final thing for this fantastic extension is that on an iPhone I have the sound effects scrolling a slot but not on the iPad; Any Idea?

  129. Hi,

    I have two questions for someone to help and provide guidance and direction:

    1. Is it possible to dyanmically populate three wheel from a MYSQL DB.

    2. Is it possible to have the wheel choices dependant / Chain selected etc like the example below:


    Any guidance on how to approach the dependency would be great.

  130. Hi,

    How can I make the Spining Wheel appear automatically?

    I am unable to make the Spinning Wheel function when it is not launched specifically by clicking manually a link.

    I tried triggering the launch programmatically upon the app’s launch, as well as faking a click. In both cases the Wheel is correctly displayed, but the slots do not spin.

    How can I make the Spining Wheel appear automatically?


    1. Thank you Matteo.

      If I take your example and trigger swExample() on “deviceready” the slots won’t spin. The wheel is displayed, but the reels don’t move.

      I hope you can help.

    2. Oh, I found the problem.

      I was changing the placement of the SW from


      That seems to be messing up things. Is there a solution to display SW in a specific element?

      Thank you for your time.

  131. Hi,

    Is it possible to trigger the spinning programmatically?

    (I am trying to make a slot machine).

    Thank you for your help.


  132. Why ????

    Is it that other posts get answer but mine do not, there must be someone who can provide some guidance:

    – Is it possible to have the wheel choices dependant / chain selected like with the combobox example below:


    Any advice would be welcomed

  133. Thanks for responding much appreciated……..how would you approach it?

    I assume that the information is stored in a mutli dimensional array and the slot movement tis the trigger.

    How do you distinquish each slot as separate triggers?


  134. It is possible to maintain the picker always shown and enabled on a div, without need to open/close it ?

  135. Hi Matteo,

    I am using your Spinwheel in an app made with PhoneGap.

    When I use the xCode Simulator the SW is displayed correctly.

    But when I display the app on my actual device iPhone4/iOS4 the SW is formatted incorrectly. Only the list items of one column are displayed and that across the whole screen, the other 2 slots are not visible, nor is all the visual formatting…

    Any idea what can cause this rendering difference between the device and the simulator?


    1. I have been doing a few tests and the faulty rendering on the device seems to ne due to the absence of the SW CSS styling.

      I got the same rendering on the Simulator when I do not load the CSS file…

      What could cause the device not to load that file or not use it?

  136. Anyone get this to work using JQuery Mobile and PhoneGap? Seems like it doesn’t want to cooperate for some reason.

    1. Hi Scott. I have it working well in jQuery Mobile (1.0a4.1 with jQuery 1.6.1) and PhoneGap Admittedly only tried it on iOS but it works well in simulator and real iPhone (3GS and 4). One consideration: include the scripts on every physical HTML page, otherwise I’ve found some occasions where a user goes from an internal page to an “external” page (i.e. one without nested “pages” in divs), the spinner stops working.

  137. It would be awesome if in the next version there was some way to put it in debug mode or something, so that it could be tested in a browser on a laptop/desktop and respond to clicks instead of swipe/touch events.

  138. hi,
    i need to put the value of the weel in asp .net form. i wrote this:
    function done() {
    var results = SpinningWheel.getSelectedValues();
    document.getElementById(‘data’).value = results.keys.join(‘/’);

    if i remove runat=server the weel put the value in the form but my asp page don’t read it. whith the parameter runat=server the weel don’t put the value in the form.
    somebody can help me.

    1. sorry but the page read my html as code of page so i have removed
      FORM INPUT id=”data” runat=”server” value=”” /FORM

  139. Hi All. Is ther a way to pipe the “result” into a text field as opposed to a paragraph? TIA.

    1. Jack – this is what I do:

      function timeDone() {
      var results = SpinningWheel.getSelectedValues();
      document.getElementById(‘txtTime’).value = results.values.join(‘:’);

      As you can see, my text field in this instance is called txtTime. For each text field, I create a different ‘done’ function, specifying the HTML control I want the selected results to go to.

  140. I’m using your script with jQTouch 1.4.2
    I added following lines to my own css file to make it work:

    #sw-wrapper { display: block; min-height: 0 !important; }
    #sw-slots ul { font: normal normal bold 16px/normal Helvetica; color: black; border: none; }
    #sw-slots ul li { color: black; background-image: none; border: none; height:24px !important;}

    The line height was about two times too high, now it looks ok.
    Maybe somebody else can use this…
    Sorry for my bad english 😉

  141. Hello, thanks for this post. It is really great!
    I have a question here, how to set the date time to now when user open this spinning-wheel? Thank you.

    1. Wallace – setting date time to now is like so:

      var now = new Date();
      var days= {};
      var months= {};
      var years= {};
      var hours = {};
      var minutes= {};

      SpinningWheel.addSlot(days, ”, now.getDay());
      SpinningWheel.addSlot(months, ”, now.getMonth());
      SpinningWheel.addSlot(years, ”, now.getFullYear());
      SpinningWheel.addSlot(hours, ”, now.getHours());
      SpinningWheel.addSlot(minutes, ”, now.getMinutes());

  142. This is absolutely brilliant, thank you!

    Two questions: I have two spinners, one has month & year – I need year to be displayed as last two digits (i.e 11 instead of 2011) but so far everything I’ve tried doesn’t work.

    Secondly, my other spinner has hours and minutes. My minutes are manually specified in 5 minute intervals (00, 05, 10, 15, etc). How can I round the now.Minutes to the nearest 5 minute interval?

    Thanks again!

  143. I have found a little problem on android: When spinning the wheel very fast, the touch event go to the page behind the wheel.
    Very fast means: Put the finger an bottom, move some pixels up, take finger from screen and repeat it very fast 3 or more times.
    When the page is longer than it is scrolling up.
    I have tested on a htc desire and a zte blade. On the blade it is more easy to show, because it is slower.
    Anybody else with this problem?

    A scrolling page is not a big problem. I can simply fix it. But when buttons behind the whell it will be activated.

  144. @Matteo: I have made a version for iOS Retina and Android HD devices. Are you intressted in the changes (not much) or is it ok for you, when i post it in the phonegap community?

    1. the script would need a complete rewrite, it can be actually done without pictures, but if you have updates, I’ll be glad to review your code. Also feel free to post the code wherever you want (just keep the license intact).

  145. I can’t get it to work after upgrading to the latest version of JQTouch (Beta 3). Does anyone have a fix for this?

    1. Same problem.
      I has modified some css,it looks ok,but i can not choose any item.

  146. very nice! It looks great!
    Just a request: when spinning the wheel, a ‘click’ sound will be also good as in the Iphone’s calendar.

  147. I have modified the tapUp event to allow for cancelling of the event (for validation purposes).
    This allows me to return true/false from the done/cancel events to prevent the spinner from closing (in the event of a validation issue).

    tapUp: function(e) {
    var ok = true;

    if (e.currentTarget.id == ‘sw-cancel’) {
    ok = this.cancelAction();
    } else {
    ok = this.doneAction();

    if (ok) {
    else {

  148. Anyone know if I can use this as a date AND time picker?

    I’m trying to do the following, but without any success…I still only get 3 slots.

    function openDateTime() {
    var now = new Date();
    var minutes = { };
    var hours = { };
    var days = { };
    var years = { };
    var months = { 1: ‘Jan’, 2: ‘Feb’, 3: ‘Mar’, 4: ‘Apr’, 5: ‘May’, 6: ‘Jun’, 7: ‘Jul’, 8: ‘Aug’, 9: ‘Sep’, 10: ‘Oct’, 11: ‘Nov’, 12: ‘Dec’ };

    for( var i = 0; i < 60; i += 1 ) {
    minutes[i] = i;

    for( var i = 1; i < 24; i += 1 ) {
    hours[i] = i;

    for( var i = 1; i < 32; i += 1 ) {
    days[i] = i;

    for( i = now.getFullYear()-10; i < now.getFullYear()+1; i += 1 ) {
    years[i] = i;

    SpinningWheel.addSlot(years, 'right', now.getFullYear());
    SpinningWheel.addSlot(months, '', now.getMonth()+1);
    SpinningWheel.addSlot(days, 'right', now.getDate());
    //SpinningWheel.addSlot(hours, 'right' 1);
    //SpinningWheel.addSlot(minutes, '', 0)



    1. Correction…

      SpinningWheel.addSlot(years, ‘right’, now.getFullYear());
      SpinningWheel.addSlot(months, ”, now.getMonth()+1);
      SpinningWheel.addSlot(days, ‘right’, now.getDate());
      SpinningWheel.addSlot(hours, ‘right’, now.getHours());
      SpinningWheel.addSlot(minutes, ”, now.getMinutes())

      I still only get 3 columns.

      1. Disregard this comment. Please see the comment below on 2011/07/28 at 02:02.

  149. Hello, really nice script you’ve got here. I wanted to ask, is there a way to show the picker right after the window is loaded and place it on specific position? Because I want it permanently on my page right after it loads up and it should be in the middle of the page.


    1. Here same thing. Would like to position the spinner where I like it, and I want to provide my own button for using the value of the spinner. How to switch off the button header ?

  150. So sorry for my newbishness,

    I want to include this in my Hybrid app. I have started programming my Hybrid app with the iWebKit framework because I am in the process of getting the iPhone developers licence. Please let me know if this is the wrong order of doing things, I am very new to this.

    So I understand that this widget requires no HTML. But all the pages created with HTML. How do I include the Javascript into the HTML file? I have tried including the JS file, the CSS file, and a function called openDateWheel which is written based off of the openBirthDate in the demo. But I cannot get it to work. Please help.

  151. Nice work, but when I play around with it for a while on iPhone 4 … it freezes, i just open the demo page, scroll a bit, and it freezes… is there any explanation for this behaviour?

  152. Spinning is way too fast on my iPhone 3GS with iOS 4.

    The native picker has a mode in which it shows day of week, day, month, time, am/pm indicator. Further, if I scroll it down past December and into January of the year after, it correctly updates the year. These would be nice features for your date picker.

  153. Great tool! I am using this as a date picker and want to add a third button between “Cancel” and “Done” that is for “Today”. Clicking the button would return today’s date. I’m having trouble adding code in the .js file that would actually be called when the new “Today” button would be clicked. I’ve attempted copying the “DoneAction” (and modifying), but not having luck.

    Any suggestions for adding a third button ?

  154. Tip: If you’d like to create a date-time picker using this script, it can be done. By default, the output isn’t a correctly formatted date. So, what you need to do is build the results variable manually instead of joining them with a single separator.

    Here’s the code I use to build a date-time in the format of day-month-year(space)hour:minute.

    function DateDone() {
    var results = SpinningWheel.getSelectedValues();
    var day = results.values[0];
    var month = results.values[1];
    var year = results.values[2];
    var hour = results.values[4];
    var minute = results.values[5];
    var datetime = day + '-' + month + '-' + year + ' ' + hour + ':' + minute;
    document.getElementById('Date').value = datetime;

    You just need to change the order of the variables constructing datetime to suit your needs.

    Also, notice that I skip results.values[3]. This is because I have a visual separator in my spinning wheel to separate the date and time values. Currently, it’s a forward slash (/) but I’m looking for a way to just use a null slot instead because I like the way it looks better than without any kind of separator and better than any other separator I’ve tested. That is:

    SpinningWheel.addSlot(years, 'right', now.getFullYear());
    SpinningWheel.addSlot('', 'right', '');
    SpinningWheel.addSlot(hours, 'right', now.getHours());

    However, this presently confuses the spinning wheel into displaying a date different from what it outputs. Specifically, it outputs the date below what is indicated. So, if 27-Jul-2011 19:30 is indicated, it ends up outputting 28-Aug-2012 20:31.

    If anyone has any ideas, I’d appreciate some feedback. You can reach me at highflight at gmail dot (.) com.

  155. Struggling with getting this to display in a custom position (top of screen) and still be functional. Anyone had any luck with this?

    I can re-position it easily enough but once I do slots stop scrolling. Any pointers greatly appreciated.

    Thanks for sharing this with us Matteo!

  156. I wonder if I can modify your plugin for other browsers like IE, FF, Chorme and Safari easily or do I need to write one from scratch?

  157. For some reason this scroller flies from top of the screen on Android 2.2.

    Someone has the same bug?

  158. @Matteo: This widget works very well in iphone and Android phones. I tested it out in an Android tablet (Samsung Galaxy Tab 10.1), and the wheels wont spin. Are tablets not supported ?

  159. How do you put the result into an input field?
    Changing this: results to:

    does not work.


  160. Changing this: results to:

    does not work. (I added spaces before and after the to make them show up here.)


  161. Any easy way to implment it inline? I was thinking to change the document.body.addChild to some container but it still not showing well.

    Great work though, thanks

  162. Very nice script. Here, a video of my adaptation for personnal use and non yet active website, in the second part of the video:


    Quiete easy to enter into the code, thanks to your explanation inside it. Dealing now to try to have slots with icons instead of text. That will be more sexy.
    The other things to be done is to retain the selcted language and to change it inside the slot. Definitely not so complex.
    And maybe from this script, could be done a full adaptation for list scrolling… Just for the pleasure. Will keep u up to date.
    Thanks again.

  163. Thank Cubiq, all your scripts are magical, looking forward your next releases

  164. Is it possible to use this spinning wheel library inline rather than have it as a popup? It would nice if it had two more functions defined show() and hide() so that it could used as an inline component. Does anyone know if someone has forked this library with this functionality?

  165. This is great but how is the positioning of the wrapper determined? I’m trying to use it on my web app and the wrapper appears halfway off the bottom of the screen so it’s unsable.

    Is there and easy way to move it up?

  166. Hi,
    I am using jQtouch with spinnig wheel;
    while at the same pannel and my spinning wheel is still showing i would like, using javascript, to trigger the cancel button ,so as to hide the wheel just before leaving the pannel .
    Is ther any way to do that ??
    knowing that i tried sw.close() that hides the wheel but next time i come to the same pannel my sw.open() wont show the wheel any more,

    Thanks in advance for your reply

  167. This is awesome, not wanting full browser capability but its easy to make the done/cancel buttons at least close it on a browser:

    in handleEvent add:

    else if (e.type == ‘click’) {
    if(e.target.id == ‘sw-cancel’ || e.target.id == ‘sw-done’) {

    and in create() add:

    document.getElementById(‘sw-cancel’).addEventListener(‘click’, this, false);
    document.getElementById(‘sw-done’).addEventListener(‘click’, this, false);

  168. this spinnig wheel doesnot dispatch a change event,
    how can i get that the dates in the control has changed?

  169. Is there anyone successful with creating loop around wheel like the iphone date time picker?

    Any suggestion or guide will be very very appreciated.

    Thanks a lot in advance

  170. I can’t make the defaultValue parameter work right.

    I try giving it one of the values in the values object – but it still starts from the first value when the wheel is shown…

    (this is great work, by the way).

  171. I modified this so that when you update a slot, you can reload that data in other columns. This might be helpful to someone.

    For example, if there are only 28 days in a month, you could have a check for each month and update the wheel accordingly with a check.

    SpinningWheel.slotEl[0].addEventListener(‘webkitTransitionEnd’, checkSlot1ForUpdate, false);

    Because I wanted this to use the transitionEnd event, I added it to the core library to fire when the wheel changed, but doesn’t animate. (For example, when you get it exactly in the right spot, it doesn’t need to move the wheel at all.)

    So, within the scrollEnd function, add an Else statement

    // The drag session was too short
    if (scrollDistance -this.cellHeight / 1.5) {
    if (this.slotEl[this.activeSlot].slotYPosition % this.cellHeight) {
    this.scrollTo(this.activeSlot, Math.round(this.slotEl[this.activeSlot].slotYPosition / this.cellHeight) * this.cellHeight, ‘100ms’);
    // dispatch a custom event because the slotY position won’t animate… this allows me to listen for webkit animation events outside of the class
    var newEvent = document.createEvent(“WebKitAnimationEvent”);
    newEvent.initWebKitAnimationEvent(“webkitTransitionEnd”, true, true, window, 0);

    Then, outside the class. I record the positions, and reload the data, close the wheel, and reopen it.

    function checkSlot1ForUpdate(e)

    if(SpinningWheel.getSelectedValues().keys[0] != currentFirstSlot)
    currentFirstSlot = SpinningWheel.getSelectedValues().keys[0];
    currentSecondSlot = 0;

    var currentSlotPosition = window.getComputedStyle(SpinningWheel.slotEl[0]).webkitTransform;
    currentSlotPosition = new WebKitCSSMatrix(currentSlotPosition).m42;

    updateLetters(sectionNames[currentFirstSlot], cubeNames[0]);

    SpinningWheel.slotEl[0].removeEventListener(‘webkitTransitionEnd’, checkSlot1ForUpdate, false);
    SpinningWheel.slotEl[1].removeEventListener(‘webkitTransitionEnd’, checkSlot2ForUpdate, false);
    SpinningWheel.animationEnabled = false;
    SpinningWheel.addSlot(slot1Array, ‘fixedWidthRight’);
    SpinningWheel.addSlot(slot2Array, ‘fixedWidthRight’);


    SpinningWheel.setPosition(0, currentSlotPosition);

    SpinningWheel.animationEnabled = true;
    SpinningWheel.slotEl[0].addEventListener(‘webkitTransitionEnd’, checkSlot1ForUpdate, false);
    SpinningWheel.slotEl[1].addEventListener(‘webkitTransitionEnd’, checkSlot2ForUpdate, false);

  172. SpinningWheel.getSelectedValues(); it doesn’t work inside ‘Function done’

    How is possible?!


      1. Finally I got solution of it.

        If you have same issue please make sure you have not add any prototype methods to Array like

        Array.prototype.someMethod = function(){


        this will break code at line 264 as

        262 line have code like

        for (i in this.slotEl) {…

      2. I’m having the same issue in iphone with phonegap, worked a few months ago, but now getselectedvaules() inside done no longer works. don’t think i have any prototype methods, as my code has not changed…

  173. great job on the Spinning Wheel. Do you have any plans to add a ‘Next’ button to the spinning wheel that function like a native drop-down box? That would be a nice function to have. I would be happy to do that myself if only I had the javascript skills. 🙂

  174. Any way to provide a button that makes the wheel spin and stop randomly on some value?

    Any help/tip would be appricated

  175. The moment I open the spinning wheen , after selecting the values I press on Done my UI gets blocked after tapping it for a longer time my UI is fine..? any suggestions

  176. Any way to get this to work with desktop Safari?
    Works nicely on i-devices, but cannot respond to mouse
    events on the desktop.

    1. Duh. I just finished getting my mods to run on Safari, and THEN found this. Moral: always check first!

    2. Hey Fred, great work, How do you set the container for the spinning wheel?

      i.e I have an element and I want it to go in there

  177. I am facing totally different behavior on android device. On android device values in slot are either in reverse order or jumbled.

  178. Hi! I resolved the issue. It wasn’t spinwheel fault its android platform which smartly sorts the json object which knowing the developers intention 🙁

  179. Is there anyway to have multiple spinning wheels on a page rather than just 1-for instance i have a departure and arrival dates and need to have the user choose two different dates.

  180. Just wondering what it would take to add Header Title for each Slot. So If I was to have 3 slots for example, Slot 1 title = Score, Slot 2 Title = Sand, and slot 3 = Green.

    Maybe to add the title it would look something like this

    var numbers = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9 };
    SpinningWheel.addSlot(numbers, ‘right’,default, TITLE);

    I am thinking the title would be place between the header and the spinning wheel.

    Any help how to do this would be helpful.


  181. I am trying to get this to work on the iPad but can’t seem to change the window location of the sw-wrapper.

    1. Hi Alex, for ipad check my mod amenoske.com/ipadspinningwheel/ it transforms the spinnigwheel into a popover, not perfect but works. I include both and use one or another depending the target device.

  182. How can we apply spinner inline ? Is there any option to apply picker to a particular div, so it will act more like an inline component rather than a sheet.

  183. Thanks for your Good Solution.
    I’ve applied your spinning wheel to my app, before.
    Now i’m working on new app with spinning wheel.
    How can i apply to new app in landscape mode ?

  184. Anyone, here integrated successfully in a sencha touch application. I am finding difficult to make this as a resusable one to use it in sencha touch.

  185. awesome.. Tested on blackberry playbook! Im doing an app for bb playbook and this comes in handy.. Thank you so much

  186. ups! I’ve just updated to Android 4.0.3 and SpinningWheel doesn’t work anymore in an web app wrapped with phonegap, ¿someone with the same problem?

  187. Any way to get this to take images? Like small icons on one spinner?

    Thanks! This is awesome!

  188. HI Matteo,
    I want to disable selecting dates beyond today. How can we do that. Assume I want to disallow user selecting 2012 Dec. 12. (Today is 2012 June 14).
    Thanks in advance.

  189. When i open the spinningwheel,i can’t find the “cancel” and “done” text,and the button is so small,could some one tell me why,please.

    1. @Philip : can’t you just read the code before asking questions ?

      This code is totally awesome. Thanks for this!

  190. I’m trying to implement the spinning wheel phone gap app with the UI designed using codiqa and I’m having some problems. The first being that the text in the spinning wheel is white like the rest of the text in the app and the second is that the done and cancel buttons give me the error “Cannot set property ‘innerHTML’ of null at file :///android_asset/www/codiqaAppName.html:58”
    How do I fix these?

    1. I’ve found away around the font colours, but would still appreciate help with the cancel and done button errors.

  191. Hi Matteo,

    I see quite a few people have taken your code and developed with it, as have I. Thank you for giving your knowledge to the community. I’ve used this control in my own project at work and hope some of the work I’ve done will also be useful. Here’s what I’ve done:

    – Added mouse events.
    – Added the ability to tap to select an item within a slot.
    – Refactored and created two new methods:
    resetSlots – Removes all slots from the DOM and resets the slotData.
    createSlots – Adds the slots to the DOM and sets the defaultValue. This was simply moved from the create method into a new method.
    – Added an onchange event, which will only fire if data for any of the slots have changed.

    Happy coding all!

    1. Hi Ron,
      Is it possible to get a copy of your changes via public download/website?


      1. Hi Kris,

        Absolutely, just click on my name above and it will take you to a blog entry that has links to a demo and the modified source. Hope it saves you a little time but of course all credit to Matteo for the excellent code!

  192. Hi, I am having an issue on Android 4.0 where if I am in a input and the keyboard is up then I hit a DIV where I have the spinning wheel to be opened, it appends the Spinning wheel ontop of the keyboard as the keyboard slides down so it ends up being halfway on the browsers window. Anyone experience this or have a fix? Thanks!

    1. Try making the input readonly, i.e.:

      Don’t have an Android to test it out, though :-). The other option is to instead of using an input, use a div.

  193. Hi, great plugin!!!
    If there is an “addSlot” Method, is it possible to delete specific slots and re add new slots while spinning weel is open?
    the idea is for example by selecting a value in slot 1 to change the slots and values on the fly in slot 2. anybody an idea?

  194. i Had an UI issue in spinning wheel when working on iOS 6 ,can anyone check this

    1. I think iOS6 removed all mouse events. Make sure you also add touchend to your code that shows the SpinningWheel control.

  195. Hi , i have problem loading this “index.html” page. I have loaded it in UIWebview but it is not displaying me date picker instead it is displayin me that index.html in Webview.I can’t find any way how to load that html page in webview and display date picker instead that html page.

  196. Hi Matteo, on iOS6 devices there are some css problems. While scrolling the wheel the text reach over the blue borders. Kevin

    1. Same here with IO 6, list items are no longer clipped by the #sw-slots or #sw-slots-wrapper element(s).
      I read somewhere that this may have to do with hardware acceleration, which seems to invalidate the z-index stacking.

    2. My solution was to add:
      -webkit-transform: translateZ(0);

      to the
      #sw-frame {

      -webkit-transform: translateZ(0);

      prop in spinning wheel css file.
      This forces the rendering engine to apply 3d hardware acceleration from the get go to all the spinner elements.
      Working properly under older IOS, Android and Playbook.

Comments are closed.