The wheel picker is a super classic UI pattern and is used to display a fast selection of data inside your app. With Ionic, we can make use of a nice Cordova Plugin so the wheel picker will feel completely native on all platforms!
Initially I wanted to use this plugin which would even run without Cordova (so also on the web), but I kinda missed the native UI feeling for Android so I changed the topic to using the Ionic Native Wheel Selector.
Create Your App
We start with a blank Ionic app and add only the plugin we need and install the according Ionic Native package:
1 2 3 4 |
ionic start wheelPicker blank cd wheelPicker ionic cordova plugin add cordova-wheel-selector-plugin npm install --save @ionic-native/wheel-selector |
Now we have to hook up everything correctly like always, and we also already load the HttpClient so we can make a request later on. Go ahead and change your app/app.module.ts to:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import { BrowserModule } from '@angular/platform-browser'; import { ErrorHandler, NgModule } from '@angular/core'; import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular'; import { SplashScreen } from '@ionic-native/splash-screen'; import { StatusBar } from '@ionic-native/status-bar'; import { MyApp } from './app.component'; import { HomePage } from '../pages/home/home'; import { WheelSelector } from '@ionic-native/wheel-selector'; import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [ MyApp, HomePage ], imports: [ BrowserModule, IonicModule.forRoot(MyApp), HttpClientModule ], bootstrap: [IonicApp], entryComponents: [ MyApp, HomePage ], providers: [ StatusBar, SplashScreen, {provide: ErrorHandler, useClass: IonicErrorHandler}, WheelSelector ] }) export class AppModule {} |
That all we need to set up the wheel picker!
Displaying Simple Data
We will start with some dummy data, but before we create all the functions let’s start with the most amazing view you will ever see. Open your pages/home/home.html and change it to:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<ion-header> <ion-navbar> <ion-title> Wheel Pickers </ion-title> </ion-navbar> </ion-header> <ion-content padding> <button ion-button full (click)="openPicker()">Open Simple Picker</button> <button ion-button full (click)="openRemotePicker()">Open Remote JSON Picker</button> </ion-content> |
I think I’ve won the award for the most amazing UI now!
Anyhow, we needed 2 buttons to call our functions wich will either display a picker directly from some data we have or from remote data fetched from an API.
The wheel picker expects data with a key description by default. That’s why both arrays inside our dummyJson
have that key, but you could also add in more information just make sure the description is there, which is also what you see once you open the picker.
To open a wheel picker we simply call the show()
function on the plugin and pass in a configuration.
The items array is what will be displayed on the wheels, so the more arrays you pass in the more columns will be created (or wheels).
Besides that, you can configure the texts and then wait for the result, which is an array of information regarding each wheel and the selected index. We simply show that selected information with a Toast to see if everything went well.
Now go ahead and change your pages/home/home.ts to:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
import { WheelSelector } from '@ionic-native/wheel-selector'; import { Component } from '@angular/core'; import { NavController } from 'ionic-angular'; import { ToastController } from 'ionic-angular/components/toast/toast-controller'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { dummyJson = { days: [ {description: 'Mon'}, {description: 'Tue'}, {description: 'Wed'}, {description: 'Thu'}, {description: 'Fri'} ], people: [ {description: 'Mike'}, {description: 'Max'}, {description: 'Adam'}, {description: 'Brandy'}, {description: 'Ben'} ] } constructor(public navCtrl: NavController, private selector: WheelSelector, private toastCtrl: ToastController, private http: HttpClient) { } openPicker() { this.selector.show({ title: 'Select Your Contact', items: [ this.dummyJson.days, this.dummyJson.people ], positiveButtonText: 'Choose', negativeButtonText: 'Nah', defaultItems: [ { index: 0, value: this.dummyJson.days[4].description }, { index: 1, value: this.dummyJson.people[1].description} ] }).then( result => { let msg = `Selected ${result[0].description} with ${result[1].description}`; let toast = this.toastCtrl.create({ message: msg, duration: 4000 }); toast.present(); }, err => console.log('Error: ', err) ); } } |
You can also find all possible configuration values and more examples on the Github page of the Wheel Selector.
Using Remote JSON Data
Not always you have some data you can immediately display, and also your JSON will not always contain a description key. Don’t worry, the plugin has a bit more to offer.
Inside our new function we make a small async request to grab some JSON from the Randomuser API which actually doesn’t contain the key we need.
The solution for this problem is to simply provide a dedicated displayKey to the configuration of the wheel picker which will then use exactly this key of our JSON data to fill the rows!
Go and add this function inside your controller as well now:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
openRemotePicker() { this.http.get('https://randomuser.me/api/?results=5').subscribe(res => { this.selector.show({ title: 'Select Your Contact', items: [ res['results'] ], displayKey: 'email' }).then( result => { let msg = `Selected ${result[0].email}`; let toast = this.toastCtrl.create({ message: msg, duration: 4000 }); toast.present(); }, err => console.log('Error: ', err) ); }); } |
The only limitation I noticed here is that you can only add one displayKey, which means you can’t pick special values from different arrays. Perhaps you would need to somehow map your data before to make it fit the wheel picker style.
Conclusion
The Cordova wheel picker looks and works great, even with non standard JSON data.
Perhaps you give the other plugin a try as well, I’m sure it’s really helpful especially as it allows a deeper relationship between your selected data by allowing to specify different parents and their own custom children.
This is also an open issue on the plugin we used, perhaps we might see a change in that direction int the next time!
You can find a video version of this Quick Win below.
tried calling WheelSelector.show, but Cordova is not available. Make sure to include cordova.js or run in a device/simulator..i am facing this issue.bcoz of this the above program is not running
Is there a way to custom the direction of the wheel selector? Currently it depends on the device (for different devices the direction is different)