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:
SpinningWheel.open();
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');
SpinningWheel.setCancelAction(cancel);
SpinningWheel.setDoneAction(done);
SpinningWheel.open();
}
function done() {
var results = SpinningWheel.getSelectedValues();
alert('values:' + results.values.join(', ') + ' - keys: ' + results.keys.join(', '));
}
function cancel() {
alert('cancelled!');
}
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'); SpinningWheel.addSlot(values);
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).
Limitations
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.

Looking very nice. Liking the fluid animation when the picker appears. Often for me animation is jumpy.
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!
Beautiful! Can’t wait to try out it out.
This is amazing!
I’ve got a website where I can use it with!
Best regards
Jan
Gummy Media Ltd
awsome as always
congrats dude!!!
[...] zu können. Matteo Spinelli hat auf seiner Seite cubiq.org eine “spinning wheel” Funktion zum download [...]
[...] Spinning wheel on webkit for iPhone/iPod touch | Cubiq.org 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. (tags: iphone javascript) [...]
Genial, hacia tiempo que buscava algo similar, gran trabajo “good job” thanks
Is there a way to get a similar control working on firefox or a non-mobile browser?
@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.
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.
@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.
Great work Matteo. I’ve posted about it on my blog, hope you don’t mind.
http://iphoneized.com/?p=326
Keep up the awesome work!
Cheers,
Chris
it no work in fullscreen mode
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)?
@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.Thx Matteo, and Buona Pasqua
Hi MAtteo, will be an update planned to correct full-screen mode ?
@Steven, I’ll have a look at it this weekend. I bet it can be solved very easily.
@Steven and all, the script seems now compatible with full screen mode.
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?
Thank you very much Matteo, you’re the best
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…
Bye
@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?
@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
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
The reason for returning a 2d matrix is an optimization. A 3d matrix is returned if z-axis is used.
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).
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.
I hope it depends on the “beta” state of OS3.
Dumb question here…
How would I be able to get the single wheel to load a new page when clicked?
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
@Matteo
Hope you are feeling well. Have you had a chance to look at how this works in 3.0GM?
@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.
The spinner still flashes in 3.0 GM seed.
It’s not as fluid as in OS 2.2.1
Pugwash,
Are you saying it works? I wasn’t able to make it work a all. It’d freeze on first item.
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.
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.
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.
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.
I’m investigating on the OS3 laziness. Probably we just have to do things in a slightly different way, but documentation lacks.
@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.
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?
This is actually not the solution we need to re-smooth the ui, but here is a good directive to use in your document css body (or div) to disable the user selection (cut/paste) in the UI :
“-webkit-user-select: none”
Please read this article.
http://groups.google.com/group/iphonewebdev/browse_thread/thread/d49897d5d24718a4#
Fred.
PS: Where are thoses kind of webkit infos/update available ?
I mean a full “API” doc.
Ok, it was a noob question.
http://developer.apple.com/documentation/AppleApplications/Reference/SafariCSSRef/Articles/StandardCSSProperties.html#//apple_ref/doc/uid/TP30001266-SW1
But i really can’t find a table with OS3 webkit enhancements compared to OS2.
Fred.
Script updated guys! Get the latest version for blazing fast performance!
Yeepa ! Thanks a lot. Works now like a charm.
I have te same problem Javier had (http://cubiq.org/spinning-wheel-on-webkit-for-iphone-ipod-touch/11#comment-1727). I can not make it running with iUi which I am using for my app. It’s just not appearing.
Any ideas so far?
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.
Did anyone figure out how to get it to open a html link when the “Done” button is clicked?
Any helpthe above would be HUGELY appreciated
: )
@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 likewindow.location.href="http://example.com?value=" + results.value[0];should work.That’s great - thanks for the help Matteo!
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.
@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).
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?
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.
Dave
Ska, can you share your tweaks?
@Ska
i would also like to see your tweaks, thanks
Thx guys for showing interest… please let me know how and where to send the updated sample?
can send me an email at, mylivingweb (at) gmail.com
i would greatly appreciate it.
matt
ska_iit
please send to dfafard - gmail
thanks!
Dave
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.
-SKA
Thanks SKA …
Still no luck for me in the jQtouch framework.
Dave
I have not tried with the JQtouch..i made it work with the iwebkit only
I’m curious , does anyone make it work in a UIWebView ?
Santangell - I’ve tried it in a UIWebView and it works fine. I’ve also seen it it this app:
http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=325676875&mt=8
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
Doesn’t work with jqtouch (http://www.jqtouch.com/)
Wonderful script!
Any ideas on how to turn off the magnifying glass if you touch and hold?
wow tat was awesome , it really helped me
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!
@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.
The component is great! I modified the script a little so that SW can function within my iui based iPhone app.
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;
left:0;
width:100%;
display:inline !important;
min-height: 0px !important;
font-family:helvetica, sans-serif;
background:rgba(0,0,0,0.7);
text-align:left;
}
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;
height:44px;
overflow:hidden;
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.
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
Brian
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.
The tweak works fine on jqtouch, thanks a lot !!!!
http://www.technetra.com/2009/08/10/countdown-iphone-webapp/ explains the two changes needed for iUI:
#sw-wrapper { display:block; }
and
body[orient="portrait"] #sw-frame { bottom:112px; }
body[orient="landscape"] #sw-frame { bottom:8px; }
This is fantastic, thanks!
[...] application. Unfortunately, due to a bad CSS approach, I faced an issue with the excellent SpinningWheel component which won’t never be displayed unless you open and modify jQTouch CSS. The fact is [...]
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
Brian
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…
Thanx
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?
btw, I LOVE THIS SCRIPT!
Hi
Here is few step to make it works in Safari , Chrome & Android browsers.
Just replace event names
touchstart -> mousedown
touchmove -> mousemove
touchend -> mouseup
Also
e.targetTouches[0].clientX - >e.clientX
e.targetTouches[0].clientY -> e.clientY
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;
}
@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.
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.
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.
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.
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).
I was using the 109 build.
Thanks. That worked great.
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)
Hi ska_iit, Can you e-mail the updates that you made for iWebKit, please..
E:Mail: vijishvanya at gmail
Thanks
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
1
2
3
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?
thx
Jann
@Jann: that is a nice feature, easy to add. I’ll definitely consider that for inclusion.
Hi,
I’m looking at demo at http://cubiq.org/dropbox/sw/ on my iPhone.
I see the page, but when I click on any button like “Birth date” nothing happens. Do I need anything else?
Thanks
oops..For some reason I had JavaScript off on my iPhone Safari Settings. The demo shows good now. Great script. Thanks
@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
Social comments and analytics for this post…
This post was mentioned on Twitter by caolu: http://bit.ly/h9NOt
It’s beautify U/I…
Hi ska_iit:
Could you please send me the code modification you did for it to work with iWebKit?
http://stackoverflow.com/questions/2040042/javascript-array-iteration-using-for-in-with-mootools-included
Since I also use mootools, I had to use this fix in order for the “getSelectedValues” portion of the code to work (run after you click ‘done’).
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.
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.
Thanks
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!
@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.
You can suppress the keyboard by setting the input tag to readonly
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.
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.
Ska_lit,
Can you post or send the mod to make the date valid?
or email me at danbodenstein at g mail dot com
hahahhahaaaaaaaaaaaa!!!
just what i needed.
wonderful.
i love you.
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?
björn