├── .npmignore ├── LICENSE ├── README.md ├── examples ├── images │ ├── android-video.gif │ ├── fruit.png │ ├── mac-many-items-video.gif │ ├── mac-single-item-video.gif │ ├── many_items.png │ ├── multiple_items.png │ ├── quantity_complex.png │ ├── quantity_dark_theme.png │ └── single_items.png ├── ionic2 │ ├── README.md │ ├── adb_install.sh │ ├── config.xml │ ├── dist │ │ └── wheel-selector │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ ├── index.metadata.json │ │ │ └── package.json │ ├── ionic.config.json │ ├── link-local.sh │ ├── link-remote.sh │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── app.component.ts │ │ │ ├── app.html │ │ │ ├── app.module.ts │ │ │ ├── app.scss │ │ │ └── main.ts │ │ ├── assets │ │ │ └── icon │ │ │ │ └── favicon.ico │ │ ├── declarations.d.ts │ │ ├── index.html │ │ ├── manifest.json │ │ ├── pages │ │ │ └── home │ │ │ │ ├── home.html │ │ │ │ ├── home.scss │ │ │ │ └── home.ts │ │ ├── service-worker.js │ │ └── theme │ │ │ └── variables.scss │ ├── tsconfig.json │ ├── tslint.json │ └── www │ │ ├── assets │ │ ├── fonts │ │ │ ├── ionicons.eot │ │ │ ├── ionicons.scss │ │ │ ├── ionicons.svg │ │ │ ├── ionicons.ttf │ │ │ ├── ionicons.woff │ │ │ ├── ionicons.woff2 │ │ │ ├── noto-sans-bold.ttf │ │ │ ├── noto-sans-bold.woff │ │ │ ├── noto-sans-regular.ttf │ │ │ ├── noto-sans-regular.woff │ │ │ ├── noto-sans.scss │ │ │ ├── roboto-bold.ttf │ │ │ ├── roboto-bold.woff │ │ │ ├── roboto-bold.woff2 │ │ │ ├── roboto-light.ttf │ │ │ ├── roboto-light.woff │ │ │ ├── roboto-light.woff2 │ │ │ ├── roboto-medium.ttf │ │ │ ├── roboto-medium.woff │ │ │ ├── roboto-medium.woff2 │ │ │ ├── roboto-regular.ttf │ │ │ ├── roboto-regular.woff │ │ │ ├── roboto-regular.woff2 │ │ │ └── roboto.scss │ │ └── icon │ │ │ └── favicon.ico │ │ ├── build │ │ ├── main.css │ │ ├── main.css.map │ │ ├── main.js │ │ ├── main.js.map │ │ ├── polyfills.js │ │ └── sw-toolbox.js │ │ ├── index.html │ │ ├── manifest.json │ │ └── service-worker.js └── testapp │ ├── .bowerrc │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── adb_install.sh │ ├── bower.json │ ├── clean.sh │ ├── config.xml │ ├── gulpfile.js │ ├── init-android.sh │ ├── init-ios.sh │ ├── ionic.config.json │ ├── link-local.sh │ ├── link-remote.sh │ ├── package.json │ ├── resources │ ├── icon.png │ └── splash.png │ ├── scss │ └── ionic.app.scss │ └── www │ ├── css │ └── style.css │ ├── img │ └── ionic.png │ ├── index.html │ ├── js │ └── app.js │ ├── manifest.json │ └── service-worker.js ├── package.json ├── plugin.xml ├── src ├── android │ └── com │ │ └── wellseek │ │ └── cordova │ │ └── SelectorCordovaPlugin.java ├── browser │ └── PluginProxy.js └── ios │ ├── SelectorCordovaPlugin.h │ └── SelectorCordovaPlugin.m └── www └── selectorplugin.js /.npmignore: -------------------------------------------------------------------------------- 1 | /examples -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cordova wheel selector plugin 2 | Native wheel selector for Cordova (Android/iOS). 3 | 4 | Can use in Cordova or Ionic (v1 or v2) frameworks, calls native API's so no clunky javascript used. Can send in as many *data sets* as needed, the UI will *grow* or *shrink* accordingly (see examples for info). 5 | 6 | 7 | 8 | - [Cordova wheel selector plugin](#cordova-wheel-selector-plugin) 9 | - [Installation](#installation) 10 | - [Usage](#usage) 11 | - [The options that can be set](#the-options-that-can-be-set) 12 | - [The functions that can be called](#the-functions-that-can-be-called) 13 | - [Screenshots and Examples](#screenshots-and-examples) 14 | - [Android](#android) 15 | - [iOS](#ios) 16 | - [Sample Data](#sample-data) 17 | - [Single items, white theme](#single-items-white-theme) 18 | - [2 items white theme](#2-items-white-theme) 19 | - [Results:](#results) 20 | - [Ouputs:](#ouputs) 21 | - [2 items dark theme](#2-items-dark-theme) 22 | - [Many items white theme, with 'wheel wrapping'](#many-items-white-theme-with-wheel-wrapping) 23 | - [Default items](#default-items) 24 | - [More complicated usage](#more-complicated-usage) 25 | - [Ionic](#ionic) 26 | - [Development](#development) 27 | - [Android](#android) 28 | - [IOS](#ios) 29 | - [TODO](#todo) 30 | - [Credits](#credits) 31 | 32 | 33 | 34 | # Installation 35 | 36 | This plugin will work in Ionic v1 AND Ionic v2! 37 | 38 | Installation via command line Ionic v1: 39 | 40 | `cordova plugin add cordova-wheel-selector-plugin` 41 | 42 | 43 | Installation (and Docs) via command line Ionic v2: 44 | 45 | [https://ionicframework.com/docs/native/wheelselector-plugin/](https://ionicframework.com/docs/native/wheelselector-plugin/) 46 | 47 | 48 | # Usage 49 | 50 | ## The options that can be set 51 | 52 | ```js 53 | var config = { 54 | title: "The title", 55 | items:[ 56 | //how many items to display, see examples below 57 | //the order of the items dictates the order they are displayed in the UI 58 | //also the result has an index which refers to the ordering (see examples below) 59 | ], 60 | defaultItems: { 61 | //which items to display, example [{"0" :"2"},{"1" :"Apple"}] (index:value} 62 | }, 63 | positiveButtonText: "Yes", 64 | negativeButtonText: "No", 65 | theme: "light | dark", //lighter or darker theme, not available on iOS yet 66 | wrapWheelText: true | false, //wrap the wheel for infinite scroll, not available on iOS 67 | 68 | //advanced usage: 69 | displayKey: "description" //so can send in different json - see examples below 70 | 71 | }; 72 | 73 | ``` 74 | 75 | you can also set `UIUserInterfaceStyle` to Light in your Info.plist file to force the UI to light. 76 | 77 | Copy + Paste this into your `Info.plist` 78 | 79 | ``` 80 | UIUserInterfaceStyle 81 | Light 82 | ``` 83 | 84 | ## The functions that can be called 85 | 86 | ```js 87 | 88 | SelectorCordovaPlugin.showSelector(); //shows the selector 89 | 90 | SelectorCordovaPlugin.hideSelector(); //programatically hides the selector - currently iOS only 91 | 92 | ``` 93 | 94 | # Screenshots and Examples 95 | 96 | ## Android 97 | 98 | android video 99 | 100 | ## iOS 101 | 102 | 103 | iOS video 104 | 105 | 106 | ## Sample Data 107 | 108 | Create your data (or get it from a server API call): 109 | 110 | ```js 111 | var data = { 112 | numbers: [ 113 | {description: "1"}, 114 | {description: "2"}, 115 | {description: "3"}, 116 | {description: "4"}, 117 | {description: "5"}, 118 | {description: "6"}, 119 | {description: "7"}, 120 | {description: "8"}, 121 | {description: "9"}, 122 | {description: "10"} 123 | ], 124 | fruits: [ 125 | {description: "Apple"}, 126 | {description: "Orange"}, 127 | {description: "Pear"}, 128 | {description: "Banana"}, 129 | {description: "Grapefruit"}, 130 | {description: "Tangerine"} 131 | ], 132 | measurements: [ 133 | {description: "Teaspoon"}, 134 | {description: "Tablespoon"}, 135 | {description: "Cup(s)"}, 136 | {description: "Quart(s)"}, 137 | {description: "Packages (7 oz)"}, 138 | {description: "Packages (12 oz)"} 139 | ], 140 | planets: [ 141 | {description: "Venus"}, 142 | {description: "Jupiter"}, 143 | {description: "Earth"}, 144 | {description: "Pluto"}, 145 | {description: "Neptune"} 146 | ] 147 | }; 148 | 149 | //config here... (see config for each screenshot below to get desired results) 150 | var config = {...}; 151 | 152 | //do something useful with the result: 153 | window.SelectorCordovaPlugin.showSelector(config, function(result) { 154 | console.log("result: " + JSON.stringify(result) ); 155 | }, function() { 156 | console.log('Canceled'); 157 | }); 158 | 159 | 160 | ``` 161 | 162 | ## Single items, white theme 163 | Using config: 164 | 165 | ```js 166 | var config = { 167 | title: "Select a quantity", 168 | items:[ 169 | [data.numbers] 170 | ], 171 | positiveButtonText: "Done", 172 | negativeButtonText: "Cancel" 173 | }; 174 | 175 | ``` 176 | Produces: 177 | 178 | single items 179 | 180 | 181 | ## 2 items white theme 182 | Using config: 183 | 184 | ```js 185 | var config = { 186 | title: "How Many Fruit?", 187 | items:[ 188 | [data.numbers], 189 | [data.fruits] 190 | ], 191 | positiveButtonText: "Yes", 192 | negativeButtonText: "No" 193 | }; 194 | 195 | ``` 196 | Produces: 197 | 198 | 199 | fruits 200 | 201 | ### Results: 202 | ```js 203 | window.SelectorCordovaPlugin.showSelector(config, function(result) { 204 | console.log("result: " + JSON.stringify(result) ); 205 | console.log('User chose number: ' + result[0].description + ' at array index: ' + result[0].index); 206 | 207 | //note: as of now in iOS result[1] is ignored 208 | console.log('User chose fruit: ' + result[1].description + ' at array index: ' + result[1].index); 209 | }, function() { 210 | console.log('Canceled'); 211 | }); 212 | 213 | ``` 214 | ### Ouputs: 215 | 216 | ``` 217 | "result: [{"index":2,"description":"3"},{"index":1,"description":"Orange"}]" 218 | "User chose number: 3 at array index: 2" 219 | "User chose fruit: Orange at array index: 1" 220 | 221 | ``` 222 | 223 | 224 | 225 | ## 2 items dark theme 226 | Using config: 227 | 228 | ```js 229 | var config = { 230 | title: "Select a quantity", 231 | items:[ 232 | [data.numbers], 233 | [data.measurements] 234 | ], 235 | theme: "dark", 236 | positiveButtonText: "Done", 237 | negativeButtonText: "Cancel" 238 | }; 239 | 240 | ``` 241 | Produces: 242 | 243 | measurements 244 | 245 | 246 | ## Many items white theme, with 'wheel wrapping' 247 | Using config: 248 | 249 | ```js 250 | var config = { 251 | title: "Select something", 252 | items:[ 253 | [data.numbers], 254 | [data.fruits], 255 | [data.measurements], 256 | [data.planets] 257 | ], 258 | wrapWheelText: true, 259 | positiveButtonText: "Cool", 260 | negativeButtonText: "No way!" 261 | }; 262 | 263 | ``` 264 | Produces: 265 | 266 | 267 | measurements 268 | 269 | 270 | ## Default items 271 | 272 | **Note:** If you have `n` `items`, then you must set `n` `defaultItems`, meaning the number of `items` and number of `defaultItems` must be the same 273 | 274 | Using config: 275 | 276 | ```js 277 | var config = { 278 | title: "Select something", 279 | items:[ 280 | [data.numbers], 281 | [data.fruits] 282 | ], 283 | defaultItems: { 284 | //the number '2' 285 | {index:0, value: data.numbers[2]}, 286 | 287 | //the value 'Pear' 288 | {index:1, value: data.fruits[2]} 289 | } 290 | }; 291 | 292 | ``` 293 | 294 | Will auto select the number "2" and fruit "Pear" (just reference the items in the json array). It could also be hard-coded to the values '2' and 'Pear' but referencing the array is safer (in case a description item isn't in the array), and also avoids duplication of code. 295 | 296 | The index defines which list the default item applies to. In the example the list at index 0 in the items array is `data.numbers`, and the list at index 1 `data.fruits`. 297 | 298 | 299 | ## More complicated usage 300 | 301 | In some cases (i.e. retrieving data from a server API call), you may get back differing JSON, in that case you can specify which *key* to display in the selector using the *displayKey* in the config, for example if we wish to display the *text* fields in the corresponding JSON from the following data set: 302 | 303 | ```js 304 | var data = { 305 | numbers:[ 306 | //intentional blanks - show up in ui as blanks 307 | {id: "", text: "", value: ""}, 308 | {id: "id1", text: "1", value: "one"}, 309 | {id: "id2", text: "2", value:"two"}, 310 | {id: "id3", text: "3", value:"three"}, 311 | {id: "id4", text: "4", value:"four"}, 312 | {id: "id5", text: "5", value:"five"}, 313 | {id: "id6", text: "6", value:"six"}, 314 | {id: "id7", text: "7", value:"seven"}, 315 | {id: "id8", text: "8", value:"eight"}, 316 | {id: "id9", text: "9", value:"nine"}, 317 | {id: "id10", text: "10", value:"ten"} 318 | ], 319 | measurements:[ 320 | //intentional blanks - show up in ui as blanks 321 | {id: "", text: "", value: ""}, 322 | {id: "id-17", text: "Teaspoon", value:"1tsp"}, 323 | {id: "id-23", text: "Tablespoon", value:"1tbsp"}, 324 | {id: "id-88", text: "Cup(s)", value:"1cup"}, 325 | {id: "id-54", text: "Quart(s)", value:"1quart"}, 326 | {id: "id-32", text: "Package (7 oz)", value:"7ozPckg"}, 327 | {id: "id-58", text: "Package (12 oz)", value:"12ozPckg"} 328 | ] 329 | }; 330 | 331 | ``` 332 | 333 | We would use the config, specifying the `displayKey` field to use `text` (if no `displayKey` is defined, the default is `description`): 334 | 335 | ```js 336 | var config = { 337 | title: "Select quantity", 338 | items:[ 339 | [data.numbers], 340 | [data.measurements] 341 | ], 342 | wrapWheelText: true, 343 | positiveButtonText: "Done", 344 | negativeButtonText: "Cancel", 345 | displayKey: "text" 346 | }; 347 | 348 | 349 | ``` 350 | Which produces: 351 | 352 | 353 | measurements 354 | 355 | 356 | And the corresponding results, you can use the index to retrieve any other values in the original JSON: 357 | 358 | ```js 359 | window.SelectorCordovaPlugin.showSelector(config, function(result) { 360 | console.log("result: " + JSON.stringify(result) ); 361 | console.log('User chose number: ' + result[0].text + ' at array index: ' + result[0].index + 362 | ' which has value: ' + data.numbers[result[0].index].value + ' and id: ' + data.numbers[result[0].index].id); 363 | console.log('User chose measurement: ' + result[1].text + ' at array index: ' + result[1].index + 364 | ' which has value: ' + data.measurements[result[1].index].value + ' and id: ' + data.measurements[result[1].index].id); 365 | }, function() { 366 | console.log('Canceled'); 367 | }); 368 | 369 | ``` 370 | 371 | Which outputs: 372 | 373 | ```js 374 | "result: [{"index":4,"text":"4"},{"index":4,"text":"Quart(s)"}]" 375 | "User chose number: 4 at array index: 4 which has value: four and id: id4" 376 | "User chose measurement: Quart(s) at array index: 4 which has value: 1quart and id: id-54" 377 | ``` 378 | 379 | Note, in the `result` return value, there is `index` which is the index in the original JSON to the item the user selected (this allows for *reverse-lookups*). 380 | 381 | 382 | # Ionic 383 | To use this plugin together with Ionic you can use the offical [@ionic-native/wheel-selector](https://ionicframework.com/docs/native/wheelselector-plugin/) plugin wrapper 384 | 385 | # Development 386 | 387 | Kinda a pain to develop these plugins (i.e. haven't figured a good way to unit test). 388 | 389 | Clone this project, say you cloned into `/home/myuser/git/cordova-wheel-selector-plugin` 390 | 391 | Install Ionic framework (could create Cordova project as well), and create a project: 392 | 393 | `ionic start myapp` 394 | 395 | `cd myapp` 396 | 397 | ## Android 398 | 399 | Install platforms: 400 | 401 | `ionic platform add android` 402 | 403 | Install the cordova-wheel-selector-plugin: 404 | 405 | `cordova plugin add --link /home/myuser/git/cordova-wheel-selector-plugin` 406 | 407 | (this createss symlinks to the plugin, in the ionic project directory) 408 | 409 | Install android studio, and open it, then create a blank project, then: 410 | 411 | `File->new->import project` and browse to the `examples/testapp/platforms/android` directory and import from that directory (there's a gradle script in there). 412 | 413 | This should allow for IDE auto-completion, etc. 414 | 415 | If you modify any file other than the `.java` file you need to uninstall the plugin and re-install it: 416 | 417 | `cordova plugin rm cordova-wheel-selector-plugin` 418 | 419 | Then 420 | 421 | `cordova plugin add --link /home/myuser/git/cordova-wheel-selector-plugin` 422 | 423 | 424 | ## IOS 425 | 426 | Assumes you already have ionic, cordova, npm installed. 427 | 428 | cd to `cordova-wheel-selector-plugin/examples/testapp` dir, type: 429 | 430 | 431 | `./init-ios` 432 | 433 | which will build it. 434 | 435 | Link to local files for the plugin: 436 | 437 | `./link-local.sh` 438 | 439 | Can now open the project in Xcode: 440 | 441 | `cordova-wheel-selector-plugin/examples/testapp/platforms/ios/WheelSelector.xcodeproj` 442 | 443 | Then build/install/develop as usual in Xcode. 444 | 445 | 446 | 447 | # Notes: 448 | To publish to npm 449 | 450 | increment version in `./package.json` 451 | 452 | `npm adduser` 453 | 454 | `npm publish` 455 | 456 | 457 | # TODO 458 | * implement more of the ios portion 459 | * implement normal web browser portion so can run locally in desktop browser 460 | * add more error handling on weird cases 461 | 462 | # Credits 463 | 464 | A lot of this was inspired (and used, especially for the iOS) from this project: 465 | 466 | [https://github.com/roberthovhannisyan/PhoneGap-Plugin-ListPicker](https://github.com/roberthovhannisyan/PhoneGap-Plugin-ListPicker) 467 | -------------------------------------------------------------------------------- /examples/images/android-video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/images/android-video.gif -------------------------------------------------------------------------------- /examples/images/fruit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/images/fruit.png -------------------------------------------------------------------------------- /examples/images/mac-many-items-video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/images/mac-many-items-video.gif -------------------------------------------------------------------------------- /examples/images/mac-single-item-video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/images/mac-single-item-video.gif -------------------------------------------------------------------------------- /examples/images/many_items.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/images/many_items.png -------------------------------------------------------------------------------- /examples/images/multiple_items.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/images/multiple_items.png -------------------------------------------------------------------------------- /examples/images/quantity_complex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/images/quantity_complex.png -------------------------------------------------------------------------------- /examples/images/quantity_dark_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/images/quantity_dark_theme.png -------------------------------------------------------------------------------- /examples/images/single_items.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/images/single_items.png -------------------------------------------------------------------------------- /examples/ionic2/README.md: -------------------------------------------------------------------------------- 1 | # Ionic 2 Wheel Selector Example 2 | 3 | This is still in the works, once it's pushed into the @ionic-native core project, there will be no need to build 4 | 5 | ## Building 6 | 7 | In the future once the WheelSelector is pushed into the ionic-native project, these build steps will become obsolete. 8 | 9 | Clone the ionic-native project: 10 | 11 | `git clone https://github.com/driftyco/ionic-native.git` 12 | 13 | copy the wheel selector wrapper into the above cloned plugins directory: 14 | 15 | `cp -R ./ionic-native/wheel-selector ~/native_cloned_dir/src/@ionic-native/plugins` 16 | 17 | Build the plugins above: 18 | 19 | `cd ~/native_cloned_dir` 20 | 21 | `npm run build` 22 | 23 | The plugin can now be 'installed' to your Ionic2 project: 24 | 25 | `cp ~/native_cloned_dir/dist/@ionic-native/wheel-selector/ ./node_modules/@ionic-native` 26 | 27 | 28 | ## Usage 29 | Then can use like: 30 | ``` 31 | import { WheelSelector } from '@ionic-native/wheel-selector'; 32 | 33 | @Component({ 34 | selector: 'xxx', 35 | templateUrl: 'xxx', 36 | providers: [WheelSelector] 37 | }) 38 | 39 | constructor(... public selector: WheelSelector) 40 | 41 | simpleExample() { 42 | 43 | let jsonData = { 44 | numbers: [ 45 | { description: "1" }, 46 | { description: "2" }, 47 | { description: "3" } 48 | ], 49 | fruits: [ 50 | { description: "Apple" }, 51 | { description: "Banana" }, 52 | { description: "Tangerine" } 53 | ], 54 | }; 55 | 56 | this.selector.show({ 57 | title: "Select some Fruit", 58 | items: [ 59 | [jsonData.numbers], 60 | [jsonData.fruits] 61 | ], 62 | }).then( 63 | result => { 64 | console.log('Selected: ' + result[0].description + ' at index: ' + result[0].index 65 | + ' and ' + result[1].description + ' at index: ' + result[1].index); 66 | }, 67 | err => console.log('Error occurred while getting result: ', err) 68 | ); 69 | } 70 | ``` 71 | 72 | That's it, it should work assuming no errors. 73 | -------------------------------------------------------------------------------- /examples/ionic2/adb_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | $ANDROID_HOME/platform-tools/adb uninstall com.ionicframework.wheelselector.app 4 | ionic cordova build android 5 | $ANDROID_HOME/platform-tools/adb install platforms/android/build/outputs/apk/android-debug.apk 6 | $ANDROID_HOME/platform-tools/adb shell am start -n io.appium.unlock/.Unlock 7 | $ANDROID_HOME/platform-tools/adb shell am start -n com.ionicframework.wheelselector.app/.MainActivity 8 | 9 | -------------------------------------------------------------------------------- /examples/ionic2/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | WheelSelector2 4 | Wheel selector demo for Ionic2. 5 | Ionic Framework Team 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 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /examples/ionic2/dist/wheel-selector/index.d.ts: -------------------------------------------------------------------------------- 1 | import { IonicNativePlugin } from '@ionic-native/core'; 2 | export interface WheelSelectorItem { 3 | description?: string; 4 | } 5 | export interface WheelSelectorOptions { 6 | /** 7 | * The title of the selector's input box 8 | */ 9 | title: string; 10 | /** 11 | * The items to display (array of items). 12 | */ 13 | items: Array>; 14 | /** 15 | * Which items to display by default, example ["2","Apple"] (if items.length is 2 for instance) 16 | */ 17 | defaultItems?: Array; 18 | /** 19 | * The 'ok' button text 20 | * Default: Done 21 | */ 22 | positiveButtonText?: string; 23 | /** 24 | * The 'cancel' button text 25 | * Default: Cancel 26 | */ 27 | negativeButtonText?: string; 28 | /** 29 | * Android only - theme color, 'light' or 'dark'. 30 | * Default: light 31 | */ 32 | theme?: string; 33 | /** 34 | * Whether to have the wheels 'wrap' (Android only) 35 | * Default: false 36 | */ 37 | wrapWheelText?: boolean; 38 | /** 39 | * The json key to display, by default it is description, this allows for setting any 40 | * key/value to be displayed 41 | * Default: description 42 | */ 43 | displayKey?: string; 44 | } 45 | export interface WheelSelectorData { 46 | data: any; 47 | } 48 | /** 49 | * @beta 50 | * @name WheelSelector Plugin 51 | * @description Native wheel selector for Cordova (Android/iOS). 52 | * 53 | * @usage 54 | * ``` 55 | * import { WheelSelector } from '@ionic-native/wheel-selector'; 56 | * 57 | * 58 | * constructor(private selector: WheelSelector) { } 59 | * 60 | * ... 61 | * 62 | * let jsonData = { 63 | * numbers: [ 64 | * { description: "1" }, 65 | * { description: "2" }, 66 | * { description: "3" } 67 | * ], 68 | * fruits: [ 69 | * { description: "Apple" }, 70 | * { description: "Banana" }, 71 | * { description: "Tangerine" } 72 | * ], 73 | * firstNames: [ 74 | * { name: "Fred", id: '1' }, 75 | * { name: "Jane", id: '2' }, 76 | * { name: "Bob", id: '3' }, 77 | * { name: "Earl", id: '4' }, 78 | * { name: "Eunice", id: '5' } 79 | * ], 80 | * lastNames: [ 81 | * { name: "Johnson", id: '100' }, 82 | * { name: "Doe", id: '101' }, 83 | * { name: "Kinishiwa", id: '102' }, 84 | * { name: "Gordon", id: '103' }, 85 | * { name: "Smith", id: '104' } 86 | * ] 87 | * }; 88 | * 89 | * ... 90 | * 91 | * //basic number selection, index is always returned in the result 92 | * selectANumber() { 93 | * this.selector.show({ 94 | * title: "How Many?", 95 | * items: [ 96 | * this.jsonData.numbers 97 | * ], 98 | * }).then( 99 | * result => { 100 | * console.log(result[0].description + ' at index: ' + result[0].index); 101 | * }, 102 | * err => console.log('Error: ', err) 103 | * ); 104 | * } 105 | * 106 | * ... 107 | * 108 | * //basic selection, setting initial displayed default values: '3' 'Banana' 109 | * selectFruit() { 110 | * this.selector.show({ 111 | * title: "How Much?", 112 | * items: [ 113 | * this.jsonData.numbers, this.jsonData.fruits 114 | * ], 115 | * positiveButtonText: "Ok", 116 | * negativeButtonText: "Nope", 117 | * defaultItems: [ 118 | * this.jsonData.numbers[2], // '3' 119 | * this.jsonData.fruits[3] // 'Banana' 120 | * ] 121 | * }).then( 122 | * result => { 123 | * console.log(result[0].description + ' ' + result[1].description); 124 | * }, 125 | * err => console.log('Error: ' + JSON.stringify(err)) 126 | * ); 127 | * } 128 | * 129 | * ... 130 | * 131 | * //more complex as overrides which key to display 132 | * //then retrieve properties from original data 133 | * selectNamesUsingDisplayKey() { 134 | * this.selector.show({ 135 | * title: "Who?", 136 | * items: [ 137 | * this.jsonData.firstNames, this.jsonData.lastNames 138 | * ], 139 | * displayKey: 'name', 140 | * defaultItems: [ 141 | * this.jsonData.firstNames[2], 142 | * this.jsonData.lastNames[3] 143 | * ] 144 | * }).then( 145 | * result => { 146 | * console.log(result[0].name + ' (id= ' + this.jsonData.firstNames[result[0].index].id + '), ' + 147 | * result[1].name + ' (id=' + this.jsonData.lastNames[result[1].index].id + ')'); 148 | * }, 149 | * err => console.log('Error: ' + JSON.stringify(err)) 150 | * ); 151 | * } 152 | * 153 | * ``` 154 | * 155 | * @interfaces 156 | * WheelSelectorOptions 157 | */ 158 | export declare class WheelSelector extends IonicNativePlugin { 159 | /** 160 | * Shows the wheel selector 161 | * @param {WheelSelectorOptions} options Options for the wheel selector 162 | * @returns {Promise} Returns a promise that resolves with the selected items, or an error. 163 | */ 164 | show(options: WheelSelectorOptions): Promise; 165 | /** 166 | * Hide the selector 167 | * @returns {Promise} 168 | */ 169 | hideSelector(): Promise; 170 | } 171 | -------------------------------------------------------------------------------- /examples/ionic2/dist/wheel-selector/index.js: -------------------------------------------------------------------------------- 1 | var __extends = (this && this.__extends) || (function () { 2 | var extendStatics = Object.setPrototypeOf || 3 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 4 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 5 | return function (d, b) { 6 | extendStatics(d, b); 7 | function __() { this.constructor = d; } 8 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 9 | }; 10 | })(); 11 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 12 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 13 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 14 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 15 | return c > 3 && r && Object.defineProperty(target, key, r), r; 16 | }; 17 | var __metadata = (this && this.__metadata) || function (k, v) { 18 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 19 | }; 20 | import { Injectable } from '@angular/core'; 21 | import { Cordova, Plugin, IonicNativePlugin } from '@ionic-native/core'; 22 | /** 23 | * @beta 24 | * @name WheelSelector Plugin 25 | * @description Native wheel selector for Cordova (Android/iOS). 26 | * 27 | * @usage 28 | * ``` 29 | * import { WheelSelector } from '@ionic-native/wheel-selector'; 30 | * 31 | * 32 | * constructor(private selector: WheelSelector) { } 33 | * 34 | * ... 35 | * 36 | * let jsonData = { 37 | * numbers: [ 38 | * { description: "1" }, 39 | * { description: "2" }, 40 | * { description: "3" } 41 | * ], 42 | * fruits: [ 43 | * { description: "Apple" }, 44 | * { description: "Banana" }, 45 | * { description: "Tangerine" } 46 | * ], 47 | * firstNames: [ 48 | * { name: "Fred", id: '1' }, 49 | * { name: "Jane", id: '2' }, 50 | * { name: "Bob", id: '3' }, 51 | * { name: "Earl", id: '4' }, 52 | * { name: "Eunice", id: '5' } 53 | * ], 54 | * lastNames: [ 55 | * { name: "Johnson", id: '100' }, 56 | * { name: "Doe", id: '101' }, 57 | * { name: "Kinishiwa", id: '102' }, 58 | * { name: "Gordon", id: '103' }, 59 | * { name: "Smith", id: '104' } 60 | * ] 61 | * }; 62 | * 63 | * ... 64 | * 65 | * //basic number selection, index is always returned in the result 66 | * selectANumber() { 67 | * this.selector.show({ 68 | * title: "How Many?", 69 | * items: [ 70 | * this.jsonData.numbers 71 | * ], 72 | * }).then( 73 | * result => { 74 | * console.log(result[0].description + ' at index: ' + result[0].index); 75 | * }, 76 | * err => console.log('Error: ', err) 77 | * ); 78 | * } 79 | * 80 | * ... 81 | * 82 | * //basic selection, setting initial displayed default values: '3' 'Banana' 83 | * selectFruit() { 84 | * this.selector.show({ 85 | * title: "How Much?", 86 | * items: [ 87 | * this.jsonData.numbers, this.jsonData.fruits 88 | * ], 89 | * positiveButtonText: "Ok", 90 | * negativeButtonText: "Nope", 91 | * defaultItems: [ 92 | * this.jsonData.numbers[2], // '3' 93 | * this.jsonData.fruits[3] // 'Banana' 94 | * ] 95 | * }).then( 96 | * result => { 97 | * console.log(result[0].description + ' ' + result[1].description); 98 | * }, 99 | * err => console.log('Error: ' + JSON.stringify(err)) 100 | * ); 101 | * } 102 | * 103 | * ... 104 | * 105 | * //more complex as overrides which key to display 106 | * //then retrieve properties from original data 107 | * selectNamesUsingDisplayKey() { 108 | * this.selector.show({ 109 | * title: "Who?", 110 | * items: [ 111 | * this.jsonData.firstNames, this.jsonData.lastNames 112 | * ], 113 | * displayKey: 'name', 114 | * defaultItems: [ 115 | * this.jsonData.firstNames[2], 116 | * this.jsonData.lastNames[3] 117 | * ] 118 | * }).then( 119 | * result => { 120 | * console.log(result[0].name + ' (id= ' + this.jsonData.firstNames[result[0].index].id + '), ' + 121 | * result[1].name + ' (id=' + this.jsonData.lastNames[result[1].index].id + ')'); 122 | * }, 123 | * err => console.log('Error: ' + JSON.stringify(err)) 124 | * ); 125 | * } 126 | * 127 | * ``` 128 | * 129 | * @interfaces 130 | * WheelSelectorOptions 131 | */ 132 | var WheelSelector = (function (_super) { 133 | __extends(WheelSelector, _super); 134 | function WheelSelector() { 135 | return _super !== null && _super.apply(this, arguments) || this; 136 | } 137 | /** 138 | * Shows the wheel selector 139 | * @param {WheelSelectorOptions} options Options for the wheel selector 140 | * @returns {Promise} Returns a promise that resolves with the selected items, or an error. 141 | */ 142 | WheelSelector.prototype.show = function (options) { 143 | return; 144 | }; 145 | /** 146 | * Hide the selector 147 | * @returns {Promise} 148 | */ 149 | WheelSelector.prototype.hideSelector = function () { return; }; 150 | return WheelSelector; 151 | }(IonicNativePlugin)); 152 | WheelSelector.decorators = [ 153 | { type: Injectable }, 154 | ]; 155 | /** @nocollapse */ 156 | WheelSelector.ctorParameters = function () { return []; }; 157 | __decorate([ 158 | Cordova(), 159 | __metadata("design:type", Function), 160 | __metadata("design:paramtypes", [Object]), 161 | __metadata("design:returntype", Promise) 162 | ], WheelSelector.prototype, "show", null); 163 | __decorate([ 164 | Cordova({ 165 | platforms: ['iOS'] 166 | }), 167 | __metadata("design:type", Function), 168 | __metadata("design:paramtypes", []), 169 | __metadata("design:returntype", Promise) 170 | ], WheelSelector.prototype, "hideSelector", null); 171 | WheelSelector = __decorate([ 172 | Plugin({ 173 | pluginName: 'WheelSelector', 174 | plugin: 'cordova-wheel-selector-plugin', 175 | pluginRef: 'SelectorCordovaPlugin', 176 | repo: 'https://github.com/jasonmamy/cordova-wheel-selector-plugin', 177 | platforms: ['Android', 'iOS'] 178 | }) 179 | ], WheelSelector); 180 | export { WheelSelector }; 181 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /examples/ionic2/dist/wheel-selector/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../../../src/@ionic-native/plugins/wheel-selector/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,UAAA,EAAW,MAAO,eAAA,CAAgB;AAC3C,OAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,iBAAA,EAAkB,MAAO,oBAAA,CAAqB;AA0DxE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6GG;AAUH,IAAa,aAAa;IAAS,iCAAiB;IAApD;;IA2BA,CAAC;IAzBC;;;;OAIG;IAEH,4BAAI,GAAJ,UAAK,OAA6B;QAChC,MAAM,CAAC;IACT,CAAC;IAED;;;OAGG;IAIH,oCAAY,GAAZ,cAAgC,MAAM,CAAC,CAAC,CAAC;IAQ3C,oBAAC;AAAD,CA3BA,AA2BC,CA3BkC,iBAAiB,GA2BnD;AANM,wBAAU,GAA0B;IAC3C,EAAE,IAAI,EAAE,UAAU,EAAE;CACnB,CAAC;AACF,kBAAkB;AACX,4BAAc,GAAmE,cAAM,OAAA,EAC7F,EAD6F,CAC7F,CAAC;AAlBA;IADC,OAAO,EAAE;;;;yCAGT;AASD;IAHC,OAAO,CAAC;QACP,SAAS,EAAE,CAAC,KAAK,CAAC;KACnB,CAAC;;;;iDACuC;AAnB9B,aAAa;IATzB,MAAM,CAAC;QACN,UAAU,EAAE,eAAe;QAC3B,MAAM,EAAE,+BAA+B;QACvC,SAAS,EAAE,uBAAuB;QAClC,IAAI,EAAE,4DAA4D;QAClE,SAAS,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC;KAC9B,CAAC;GAGW,aAAa,CA2BzB;SA3BY,aAAa","file":"index.js","sourceRoot":"","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Cordova, Plugin, IonicNativePlugin } from '@ionic-native/core';\n\nexport interface WheelSelectorItem {\n description?: string;\n}\n\nexport interface WheelSelectorOptions {\n /**\n * The title of the selector's input box\n */\n title: string;\n\n /**\n * The items to display (array of items).\n */\n items: Array>;\n\n /**\n * Which items to display by default, example [\"2\",\"Apple\"] (if items.length is 2 for instance)\n */\n defaultItems?: Array;\n\n /**\n * The 'ok' button text\n * Default: Done\n */\n positiveButtonText?: string;\n\n /**\n * The 'cancel' button text\n * Default: Cancel\n */\n negativeButtonText?: string;\n\n /**\n * Android only - theme color, 'light' or 'dark'.\n * Default: light\n */\n theme?: string;\n\n /**\n * Whether to have the wheels 'wrap' (Android only)\n * Default: false\n */\n wrapWheelText?: boolean;\n\n /**\n * The json key to display, by default it is description, this allows for setting any\n * key/value to be displayed\n * Default: description\n */\n displayKey?: string;\n}\n\nexport interface WheelSelectorData {\n data: any;\n}\n\n/**\n * @beta\n * @name WheelSelector Plugin\n * @description Native wheel selector for Cordova (Android/iOS).\n *\n * @usage\n * ```\n * import { WheelSelector } from '@ionic-native/wheel-selector';\n *\n *\n * constructor(private selector: WheelSelector) { }\n *\n * ...\n *\n * let jsonData = {\n * numbers: [\n * { description: \"1\" },\n * { description: \"2\" },\n * { description: \"3\" }\n * ],\n * fruits: [\n * { description: \"Apple\" },\n * { description: \"Banana\" },\n * { description: \"Tangerine\" }\n * ],\n * firstNames: [\n * { name: \"Fred\", id: '1' },\n * { name: \"Jane\", id: '2' },\n * { name: \"Bob\", id: '3' },\n * { name: \"Earl\", id: '4' },\n * { name: \"Eunice\", id: '5' }\n * ],\n * lastNames: [\n * { name: \"Johnson\", id: '100' },\n * { name: \"Doe\", id: '101' },\n * { name: \"Kinishiwa\", id: '102' },\n * { name: \"Gordon\", id: '103' },\n * { name: \"Smith\", id: '104' }\n * ]\n * };\n *\n * ...\n *\n * //basic number selection, index is always returned in the result\n * selectANumber() {\n * this.selector.show({\n * title: \"How Many?\",\n * items: [\n * this.jsonData.numbers\n * ],\n * }).then(\n * result => {\n * console.log(result[0].description + ' at index: ' + result[0].index);\n * },\n * err => console.log('Error: ', err)\n * );\n * }\n * \n * ...\n *\n * //basic selection, setting initial displayed default values: '3' 'Banana'\n * selectFruit() {\n * this.selector.show({\n * title: \"How Much?\",\n * items: [\n * this.jsonData.numbers, this.jsonData.fruits\n * ],\n * positiveButtonText: \"Ok\",\n * negativeButtonText: \"Nope\",\n * defaultItems: [\n * this.jsonData.numbers[2], // '3'\n * this.jsonData.fruits[3] // 'Banana'\n * ]\n * }).then(\n * result => {\n * console.log(result[0].description + ' ' + result[1].description);\n * },\n * err => console.log('Error: ' + JSON.stringify(err))\n * );\n * }\n * \n * ...\n *\n * //more complex as overrides which key to display\n * //then retrieve properties from original data\n * selectNamesUsingDisplayKey() {\n * this.selector.show({\n * title: \"Who?\",\n * items: [\n * this.jsonData.firstNames, this.jsonData.lastNames\n * ],\n * displayKey: 'name',\n * defaultItems: [\n * this.jsonData.firstNames[2],\n * this.jsonData.lastNames[3]\n * ]\n * }).then(\n * result => {\n * console.log(result[0].name + ' (id= ' + this.jsonData.firstNames[result[0].index].id + '), ' +\n * result[1].name + ' (id=' + this.jsonData.lastNames[result[1].index].id + ')');\n * },\n * err => console.log('Error: ' + JSON.stringify(err))\n * );\n * }\n *\n * ```\n *\n * @interfaces\n * WheelSelectorOptions\n */\n@Plugin({\n pluginName: 'WheelSelector',\n plugin: 'cordova-wheel-selector-plugin',\n pluginRef: 'SelectorCordovaPlugin',\n repo: 'https://github.com/jasonmamy/cordova-wheel-selector-plugin',\n platforms: ['Android', 'iOS']\n})\n\n\nexport class WheelSelector extends IonicNativePlugin {\n\n /**\n * Shows the wheel selector\n * @param {WheelSelectorOptions} options Options for the wheel selector\n * @returns {Promise} Returns a promise that resolves with the selected items, or an error.\n */\n @Cordova()\n show(options: WheelSelectorOptions): Promise {\n return;\n }\n\n /**\n * Hide the selector\n * @returns {Promise}\n */\n @Cordova({\n platforms: ['iOS']\n })\n hideSelector(): Promise { return; }\n\nstatic decorators: DecoratorInvocation[] = [\n{ type: Injectable },\n];\n/** @nocollapse */\nstatic ctorParameters: () => ({type: any, decorators?: DecoratorInvocation[]}|null)[] = () => [\n];\n}\n\ninterface DecoratorInvocation {\n type: Function;\n args?: any[];\n}\n"]} -------------------------------------------------------------------------------- /examples/ionic2/dist/wheel-selector/index.metadata.json: -------------------------------------------------------------------------------- 1 | [{"__symbolic":"module","version":3,"metadata":{"WheelSelectorItem":{"__symbolic":"interface"},"WheelSelectorOptions":{"__symbolic":"interface"},"WheelSelectorData":{"__symbolic":"interface"},"WheelSelector":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"@ionic-native/core","name":"IonicNativePlugin"},"decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@ionic-native/core","name":"Plugin"},"arguments":[{"pluginName":"WheelSelector","plugin":"cordova-wheel-selector-plugin","pluginRef":"SelectorCordovaPlugin","repo":"https://github.com/jasonmamy/cordova-wheel-selector-plugin","platforms":["Android","iOS"]}]},{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable"}}],"members":{"show":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@ionic-native/core","name":"Cordova"}}]}],"hideSelector":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@ionic-native/core","name":"Cordova"},"arguments":[{"platforms":["iOS"]}]}]}]}}}},{"__symbolic":"module","version":1,"metadata":{"WheelSelectorItem":{"__symbolic":"interface"},"WheelSelectorOptions":{"__symbolic":"interface"},"WheelSelectorData":{"__symbolic":"interface"},"WheelSelector":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"@ionic-native/core","name":"IonicNativePlugin"},"decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@ionic-native/core","name":"Plugin"},"arguments":[{"pluginName":"WheelSelector","plugin":"cordova-wheel-selector-plugin","pluginRef":"SelectorCordovaPlugin","repo":"https://github.com/jasonmamy/cordova-wheel-selector-plugin","platforms":["Android","iOS"]}]},{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable"}}],"members":{"show":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@ionic-native/core","name":"Cordova"}}]}],"hideSelector":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@ionic-native/core","name":"Cordova"},"arguments":[{"platforms":["iOS"]}]}]}]}}}}] -------------------------------------------------------------------------------- /examples/ionic2/dist/wheel-selector/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ionic-native/wheel-selector", 3 | "version": "3.10.2", 4 | "description": "Ionic Native - Native plugins for ionic apps", 5 | "module": "index.js", 6 | "typings": "index.d.ts", 7 | "author": "ionic", 8 | "license": "MIT", 9 | "peerDependencies": { 10 | "@ionic-native/core": "^3.6.0", 11 | "@angular/core": "*", 12 | "rxjs": "^5.0.1" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/driftyco/ionic-native.git" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/ionic2/ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WheelSelector2", 3 | "app_id": "", 4 | "type": "ionic-angular" 5 | } 6 | -------------------------------------------------------------------------------- /examples/ionic2/link-local.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #link to the plugin rather than getting the installed on out on npm registry 4 | cordova plugin rm cordova-wheel-selector-plugin 5 | cordova plugin add --link ../../ 6 | -------------------------------------------------------------------------------- /examples/ionic2/link-remote.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #get the released plugin in npm registry 4 | cordova plugin rm cordova-wheel-selector-plugin 5 | cordova plugin add cordova-wheel-selector-plugin 6 | -------------------------------------------------------------------------------- /examples/ionic2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic-hello-world", 3 | "version": "0.0.0", 4 | "author": "Ionic Framework", 5 | "homepage": "http://ionicframework.com/", 6 | "private": true, 7 | "scripts": { 8 | "clean": "ionic-app-scripts clean", 9 | "build": "ionic-app-scripts build", 10 | "lint": "ionic-app-scripts lint", 11 | "ionic:build": "ionic-app-scripts build", 12 | "ionic:serve": "ionic-app-scripts serve" 13 | }, 14 | "dependencies": { 15 | "@angular/common": "4.0.2", 16 | "@angular/compiler": "4.0.2", 17 | "@angular/compiler-cli": "4.0.2", 18 | "@angular/core": "4.0.2", 19 | "@angular/forms": "4.0.2", 20 | "@angular/http": "4.0.2", 21 | "@angular/platform-browser": "4.0.2", 22 | "@angular/platform-browser-dynamic": "4.0.2", 23 | "@ionic-native/core": "3.6.1", 24 | "@ionic-native/splash-screen": "3.6.1", 25 | "@ionic-native/status-bar": "3.6.1", 26 | "@ionic/storage": "2.0.1", 27 | "ionic-angular": "3.1.1", 28 | "ionicons": "3.0.0", 29 | "rxjs": "5.1.1", 30 | "sw-toolbox": "3.4.0", 31 | "zone.js": "^0.8.10" 32 | }, 33 | "devDependencies": { 34 | "@ionic/app-scripts": "1.3.7", 35 | "@ionic/cli-plugin-cordova": "1.4.0", 36 | "@ionic/cli-plugin-ionic-angular": "1.3.1", 37 | "typescript": "~2.2.1" 38 | }, 39 | "cordovaPlugins": [ 40 | "cordova-plugin-console", 41 | "cordova-plugin-whitelist", 42 | "cordova-plugin-device", 43 | "cordova-plugin-statusbar", 44 | "cordova-plugin-splashscreen", 45 | "ionic-plugin-keyboard" 46 | ], 47 | "cordovaPlatforms": [], 48 | "description": "myBlank: An Ionic project" 49 | } 50 | -------------------------------------------------------------------------------- /examples/ionic2/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { Platform } from 'ionic-angular'; 3 | import { StatusBar } from '@ionic-native/status-bar'; 4 | import { SplashScreen } from '@ionic-native/splash-screen'; 5 | 6 | import { HomePage } from '../pages/home/home'; 7 | @Component({ 8 | templateUrl: 'app.html' 9 | }) 10 | export class MyApp { 11 | rootPage:any = HomePage; 12 | 13 | constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) { 14 | platform.ready().then(() => { 15 | // Okay, so the platform is ready and our plugins are available. 16 | // Here you can do any higher level native things you might need. 17 | statusBar.styleDefault(); 18 | splashScreen.hide(); 19 | }); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /examples/ionic2/src/app/app.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/ionic2/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { ErrorHandler, NgModule } from '@angular/core'; 3 | import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular'; 4 | import { SplashScreen } from '@ionic-native/splash-screen'; 5 | import { StatusBar } from '@ionic-native/status-bar'; 6 | 7 | import { MyApp } from './app.component'; 8 | import { HomePage } from '../pages/home/home'; 9 | 10 | @NgModule({ 11 | declarations: [ 12 | MyApp, 13 | HomePage 14 | ], 15 | imports: [ 16 | BrowserModule, 17 | IonicModule.forRoot(MyApp) 18 | ], 19 | bootstrap: [IonicApp], 20 | entryComponents: [ 21 | MyApp, 22 | HomePage 23 | ], 24 | providers: [ 25 | StatusBar, 26 | SplashScreen, 27 | {provide: ErrorHandler, useClass: IonicErrorHandler} 28 | ] 29 | }) 30 | export class AppModule {} 31 | -------------------------------------------------------------------------------- /examples/ionic2/src/app/app.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/v2/theming/ 2 | 3 | 4 | // App Global Sass 5 | // -------------------------------------------------- 6 | // Put style rules here that you want to apply globally. These 7 | // styles are for the entire app and not just one component. 8 | // Additionally, this file can be also used as an entry point 9 | // to import other Sass files to be included in the output CSS. 10 | // 11 | // Shared Sass variables, which can be used to adjust Ionic's 12 | // default Sass variables, belong in "theme/variables.scss". 13 | // 14 | // To declare rules for a specific mode, create a child rule 15 | // for the .md, .ios, or .wp mode classes. The mode class is 16 | // automatically applied to the element in the app. 17 | -------------------------------------------------------------------------------- /examples/ionic2/src/app/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | 3 | import { AppModule } from './app.module'; 4 | 5 | platformBrowserDynamic().bootstrapModule(AppModule); 6 | -------------------------------------------------------------------------------- /examples/ionic2/src/assets/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/src/assets/icon/favicon.ico -------------------------------------------------------------------------------- /examples/ionic2/src/declarations.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Declaration files are how the Typescript compiler knows about the type information(or shape) of an object. 3 | They're what make intellisense work and make Typescript know all about your code. 4 | 5 | A wildcard module is declared below to allow third party libraries to be used in an app even if they don't 6 | provide their own type declarations. 7 | 8 | To learn more about using third party libraries in an Ionic app, check out the docs here: 9 | http://ionicframework.com/docs/v2/resources/third-party-libs/ 10 | 11 | For more info on type definition files, check out the Typescript docs here: 12 | https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html 13 | */ 14 | declare module '*'; -------------------------------------------------------------------------------- /examples/ionic2/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ionic App 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/ionic2/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Ionic", 3 | "short_name": "Ionic", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "icons": [{ 7 | "src": "assets/imgs/logo.png", 8 | "sizes": "512x512", 9 | "type": "image/png" 10 | }], 11 | "background_color": "#4e8ef7", 12 | "theme_color": "#4e8ef7" 13 | } -------------------------------------------------------------------------------- /examples/ionic2/src/pages/home/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Ionic2 Wheel Selector Example 5 | 6 | 7 | 8 | 9 | 10 | 11 | Selected: {{selected}} 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/ionic2/src/pages/home/home.scss: -------------------------------------------------------------------------------- 1 | page-home { 2 | .selected-tag{ 3 | font-weight: bold; 4 | font-size: 18px; 5 | } 6 | .selected{ 7 | font-size: 18px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/ionic2/src/pages/home/home.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NavController } from 'ionic-angular'; 3 | import { WheelSelector } from '@ionic-native/wheel-selector'; 4 | 5 | @Component({ 6 | selector: 'page-home', 7 | templateUrl: 'home.html', 8 | providers: [WheelSelector] 9 | }) 10 | 11 | 12 | export class HomePage { 13 | jsonData = { 14 | numbers: [ 15 | { description: "1" }, 16 | { description: "2" }, 17 | { description: "3" }, 18 | { description: "4" }, 19 | { description: "5" }, 20 | { description: "6" }, 21 | { description: "7" }, 22 | { description: "8" }, 23 | { description: "9" }, 24 | { description: "10" } 25 | ], 26 | fruits: [ 27 | { description: "Apple" }, 28 | { description: "Orange" }, 29 | { description: "Pear" }, 30 | { description: "Banana" }, 31 | { description: "Grapefruit" }, 32 | { description: "Tangerine" } 33 | ], 34 | measurements: [ 35 | { description: "Teaspoon" }, 36 | { description: "Tablespoon" }, 37 | { description: "Cup(s)" }, 38 | { description: "Quart(s)" }, 39 | { description: "Packages (7 oz)" }, 40 | { description: "Packages (12 oz)" } 41 | ], 42 | planets: [ 43 | { description: "Venus" }, 44 | { description: "Jupiter" }, 45 | { description: "Earth" }, 46 | { description: "Pluto" }, 47 | { description: "Neptune" } 48 | ], 49 | firstNames: [ 50 | { name: "Fred", id: '1' }, 51 | { name: "Jane", id: '2' }, 52 | { name: "Bob", id: '3' }, 53 | { name: "Earl", id: '4' }, 54 | { name: "Eunice", id: '5' } 55 | ], 56 | lastNames: [ 57 | { name: "Johnson", id: '100' }, 58 | { name: "Doe", id: '101' }, 59 | { name: "Kinishiwa", id: '102' }, 60 | { name: "Gordon", id: '103' }, 61 | { name: "Smith", id: '104' } 62 | ], 63 | uuids: [ 64 | { id: "f70432b8-db2a-4cc3-a3a1-1e06c09cf814" }, 65 | { id: "435e01f1-77c1-4154-9a2f-531b64297db2" }, 66 | { id: "652b4ff5-c8a0-480e-bfd1-abb47c983914" }, 67 | { id: "8ef9abe3-0968-4265-a6b2-dec270a85920" }, 68 | { id: "c064fcb5-49e6-4976-bc60-c2eeda601f4b" } 69 | ], 70 | } 71 | 72 | selected: string; 73 | 74 | constructor(public navCtrl: NavController, public selector: WheelSelector) { 75 | } 76 | 77 | //more complex as overrides which key to display 78 | //then retrieve properties from original data 79 | selectNames() { 80 | this.selector.show({ 81 | title: "Who?", 82 | items: [ 83 | this.jsonData.firstNames, this.jsonData.lastNames 84 | ], 85 | displayKey: 'name', 86 | defaultItems: [ 87 | {index: 0, value: this.jsonData.firstNames[2].name}, 88 | {index: 1, value: this.jsonData.lastNames[3].name} 89 | ] 90 | }).then( 91 | result => { 92 | this.selected = result[0].name + ' (id= ' + this.jsonData.firstNames[result[0].index].id + '), ' + 93 | result[1].name + ' (id=' + this.jsonData.lastNames[result[1].index].id + ')'; 94 | }, 95 | err => console.log('Error occurred while getting result: ' + JSON.stringify(err)) 96 | ); 97 | } 98 | 99 | selectUuids() { 100 | this.selector.show({ 101 | title: "Select a UUID", 102 | items: [ 103 | this.jsonData.uuids 104 | ], 105 | displayKey: 'id' 106 | }).then( 107 | result => { 108 | this.selected = result[0].id; 109 | }, 110 | err => console.log('Error occurred while getting result: ' + JSON.stringify(err)) 111 | ); 112 | } 113 | 114 | simpleFruit() { 115 | this.selector.show({ 116 | title: "How Much?", 117 | items: [ 118 | this.jsonData.numbers, this.jsonData.fruits 119 | ], 120 | positiveButtonText: "Ok", 121 | negativeButtonText: "Nope", 122 | wrapWheelText: true, 123 | }).then( 124 | result => { 125 | this.selected = result[0].description + ' ' + result[1].description; 126 | }, 127 | err => console.log('Error occurred while getting result: ' + JSON.stringify(err)) 128 | ); 129 | } 130 | 131 | selectNumber() { 132 | this.selector.show({ 133 | title: "How Many?", 134 | items: [ 135 | this.jsonData.numbers 136 | ], 137 | }).then( 138 | result => { 139 | this.selected = result[0].description; 140 | }, 141 | err => console.log('Error occurred while getting result: ', err) 142 | ); 143 | } 144 | 145 | selectFruitQuantity() { 146 | this.selector.show({ 147 | title: "How Many?", 148 | items: [ 149 | this.jsonData.numbers, 150 | this.jsonData.measurements, 151 | this.jsonData.fruits 152 | ], 153 | }).then( 154 | result => { 155 | this.selected = result[0].description + ' ' + result[1].description + ' ' + result[2].description; 156 | }, 157 | err => console.log('Error occurred while getting result: ', err) 158 | ); 159 | } 160 | 161 | selectFruitQuantityFromPlanet() { 162 | this.selector.show({ 163 | title: "How Many?", 164 | items: [ 165 | this.jsonData.numbers, 166 | this.jsonData.measurements, 167 | this.jsonData.fruits, 168 | this.jsonData.planets 169 | ], 170 | wrapWheelText: true 171 | }).then( 172 | result => { 173 | this.selected = result[0].description + ' ' + result[1].description + ' ' + result[2].description + ' ' + result[3].description; 174 | }, 175 | err => console.log('Error occurred while getting result: ', err) 176 | ); 177 | } 178 | selectQuanity() { 179 | this.selector.show({ 180 | title: "How Many?", 181 | items: [ 182 | this.jsonData.numbers, 183 | this.jsonData.measurements 184 | ], 185 | wrapWheelText: true 186 | }).then( 187 | result => { 188 | this.selected = result[0].description + ' ' + result[1].description; 189 | }, 190 | err => console.log('Error occurred while getting result: ', err) 191 | ); 192 | } 193 | 194 | selectWithDefaultValues() { 195 | this.selector.show({ 196 | title: "Default selected values should be: 3 Grapefruit", 197 | items: [ 198 | this.jsonData.numbers, 199 | this.jsonData.fruits 200 | ], 201 | wrapWheelText: true, 202 | defaultItems: [ 203 | {index:0 , value: "3"}, 204 | {index:1 , value: "Grapefruit"} 205 | ] 206 | }).then( 207 | result => { 208 | this.selected = result[0].description + ' ' + result[1].description; 209 | }, 210 | err => console.log('Error occurred while getting result: ', err) 211 | ); 212 | } 213 | 214 | selectDefaultValuesThatDontExist(){ 215 | this.selector.show({ 216 | title: "Default selected values should be: 1 Apple", 217 | items: [ 218 | this.jsonData.numbers, 219 | this.jsonData.fruits 220 | ], 221 | wrapWheelText: true, 222 | defaultItems: [ 223 | {index:0 , value: "50"}, 224 | {index:1 , value: "Kiwi"} 225 | ] 226 | }).then( 227 | result => { 228 | this.selected = result[0].description + ' ' + result[1].description; 229 | }, 230 | err => console.log('Error occurred while getting result: ', err) 231 | ); 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /examples/ionic2/src/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check out https://googlechrome.github.io/sw-toolbox/ for 3 | * more info on how to use sw-toolbox to custom configure your service worker. 4 | */ 5 | 6 | 7 | 'use strict'; 8 | importScripts('./build/sw-toolbox.js'); 9 | 10 | self.toolbox.options.cache = { 11 | name: 'ionic-cache' 12 | }; 13 | 14 | // pre-cache our key assets 15 | self.toolbox.precache( 16 | [ 17 | './build/main.js', 18 | './build/main.css', 19 | './build/polyfills.js', 20 | 'index.html', 21 | 'manifest.json' 22 | ] 23 | ); 24 | 25 | // dynamically cache any other local assets 26 | self.toolbox.router.any('/*', self.toolbox.cacheFirst); 27 | 28 | // for any other requests go to the network, cache, 29 | // and then only use that cached resource if your user goes offline 30 | self.toolbox.router.default = self.toolbox.networkFirst; 31 | -------------------------------------------------------------------------------- /examples/ionic2/src/theme/variables.scss: -------------------------------------------------------------------------------- 1 | // Ionic Variables and Theming. For more info, please see: 2 | // http://ionicframework.com/docs/v2/theming/ 3 | $font-path: "../assets/fonts"; 4 | 5 | @import "ionic.globals"; 6 | 7 | 8 | // Shared Variables 9 | // -------------------------------------------------- 10 | // To customize the look and feel of this app, you can override 11 | // the Sass variables found in Ionic's source scss files. 12 | // To view all the possible Ionic variables, see: 13 | // http://ionicframework.com/docs/v2/theming/overriding-ionic-variables/ 14 | 15 | 16 | 17 | 18 | // Named Color Variables 19 | // -------------------------------------------------- 20 | // Named colors makes it easy to reuse colors on various components. 21 | // It's highly recommended to change the default colors 22 | // to match your app's branding. Ionic uses a Sass map of 23 | // colors so you can add, rename and remove colors as needed. 24 | // The "primary" color is the only required color in the map. 25 | 26 | $colors: ( 27 | primary: #488aff, 28 | secondary: #32db64, 29 | danger: #f53d3d, 30 | light: #f4f4f4, 31 | dark: #222 32 | ); 33 | 34 | 35 | // App iOS Variables 36 | // -------------------------------------------------- 37 | // iOS only Sass variables can go here 38 | 39 | 40 | 41 | 42 | // App Material Design Variables 43 | // -------------------------------------------------- 44 | // Material Design only Sass variables can go here 45 | 46 | 47 | 48 | 49 | // App Windows Variables 50 | // -------------------------------------------------- 51 | // Windows only Sass variables can go here 52 | 53 | 54 | 55 | 56 | // App Theme 57 | // -------------------------------------------------- 58 | // Ionic apps can have different themes applied, which can 59 | // then be future customized. This import comes last 60 | // so that the above variables are used and Ionic's 61 | // default are overridden. 62 | 63 | @import "ionic.theme.default"; 64 | 65 | 66 | // Ionicons 67 | // -------------------------------------------------- 68 | // The premium icon font for Ionic. For more info, please see: 69 | // http://ionicframework.com/docs/v2/ionicons/ 70 | 71 | @import "ionic.ionicons"; 72 | 73 | 74 | // Fonts 75 | // -------------------------------------------------- 76 | 77 | @import "roboto"; 78 | @import "noto-sans"; 79 | -------------------------------------------------------------------------------- /examples/ionic2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": false, 5 | "emitDecoratorMetadata": true, 6 | "experimentalDecorators": true, 7 | "lib": [ 8 | "dom", 9 | "es2015" 10 | ], 11 | "module": "es2015", 12 | "moduleResolution": "node", 13 | "sourceMap": true, 14 | "target": "es5" 15 | }, 16 | "include": [ 17 | "src/**/*.ts" 18 | ], 19 | "exclude": [ 20 | "node_modules" 21 | ], 22 | "compileOnSave": false, 23 | "atom": { 24 | "rewriteTsconfig": false 25 | } 26 | } -------------------------------------------------------------------------------- /examples/ionic2/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-duplicate-variable": true, 4 | "no-unused-variable": [ 5 | true 6 | ] 7 | }, 8 | "rulesDirectory": [ 9 | "node_modules/tslint-eslint-rules/dist/rules" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/ionicons.eot -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/ionicons.scss: -------------------------------------------------------------------------------- 1 | 2 | // Ionicons Icon Font CSS 3 | // -------------------------- 4 | // Ionicons CSS for Ionic's element 5 | // ionicons-icons.scss has the icons and their unicode characters 6 | 7 | $ionicons-font-path: $font-path !default; 8 | 9 | @import "ionicons-icons"; 10 | @import "ionicons-variables"; 11 | 12 | 13 | @font-face { 14 | font-family: "Ionicons"; 15 | src: url("#{$ionicons-font-path}/ionicons.woff2?v=#{$ionicons-version}") format("woff2"), 16 | url("#{$ionicons-font-path}/ionicons.woff?v=#{$ionicons-version}") format("woff"), 17 | url("#{$ionicons-font-path}/ionicons.ttf?v=#{$ionicons-version}") format("truetype"); 18 | font-weight: normal; 19 | font-style: normal; 20 | } 21 | 22 | ion-icon { 23 | display: inline-block; 24 | 25 | font-family: "Ionicons"; 26 | -moz-osx-font-smoothing: grayscale; 27 | -webkit-font-smoothing: antialiased; 28 | font-style: normal; 29 | font-variant: normal; 30 | font-weight: normal; 31 | line-height: 1; 32 | text-rendering: auto; 33 | text-transform: none; 34 | speak: none; 35 | } 36 | -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/ionicons.ttf -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/ionicons.woff -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/ionicons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/ionicons.woff2 -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/noto-sans-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/noto-sans-bold.ttf -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/noto-sans-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/noto-sans-bold.woff -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/noto-sans-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/noto-sans-regular.ttf -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/noto-sans-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/noto-sans-regular.woff -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/noto-sans.scss: -------------------------------------------------------------------------------- 1 | // Noto Sans Font 2 | // Google 3 | // Apache License, version 2.0 4 | // http://www.apache.org/licenses/LICENSE-2.0.html 5 | 6 | $noto-sans-font-path: $font-path !default; 7 | 8 | @font-face { 9 | font-family: "Noto Sans"; 10 | font-style: normal; 11 | font-weight: 300; 12 | src: local("Noto Sans"), local("Noto-Sans-Regular"), url("#{$noto-sans-font-path}/noto-sans-regular.woff") format("woff"), url("#{$noto-sans-font-path}/noto-sans-regular.ttf") format("truetype"); 13 | } 14 | 15 | @font-face { 16 | font-family: "Noto Sans"; 17 | font-style: normal; 18 | font-weight: 400; 19 | src: local("Noto Sans"), local("Noto-Sans-Regular"), url("#{$noto-sans-font-path}/noto-sans-regular.woff") format("woff"), url("#{$noto-sans-font-path}/noto-sans-regular.ttf") format("truetype"); 20 | } 21 | 22 | @font-face { 23 | font-family: "Noto Sans"; 24 | font-style: normal; 25 | font-weight: 500; 26 | src: local("Noto Sans Bold"), local("Noto-Sans-Bold"), url("#{$noto-sans-font-path}/noto-sans-bold.woff") format("woff"), url("#{$noto-sans-font-path}/noto-sans-bold.ttf") format("truetype"); 27 | } 28 | 29 | @font-face { 30 | font-family: "Noto Sans"; 31 | font-style: normal; 32 | font-weight: 700; 33 | src: local("Noto Sans Bold"), local("Noto-Sans-Bold"), url("#{$noto-sans-font-path}/noto-sans-bold.woff") format("woff"), url("#{$noto-sans-font-path}/noto-sans-bold.ttf") format("truetype"); 34 | } 35 | -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-bold.ttf -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-bold.woff -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-bold.woff2 -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-light.ttf -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-light.woff -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-light.woff2 -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-medium.ttf -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-medium.woff -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-medium.woff2 -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-regular.ttf -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-regular.woff -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/fonts/roboto-regular.woff2 -------------------------------------------------------------------------------- /examples/ionic2/www/assets/fonts/roboto.scss: -------------------------------------------------------------------------------- 1 | // Roboto Font 2 | // Google 3 | // Apache License, version 2.0 4 | // http://www.apache.org/licenses/LICENSE-2.0.html 5 | 6 | $roboto-font-path: $font-path !default; 7 | 8 | @font-face { 9 | font-family: "Roboto"; 10 | font-style: normal; 11 | font-weight: 300; 12 | src: local("Roboto Light"), local("Roboto-Light"), url("#{$roboto-font-path}/roboto-light.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-light.woff") format("woff"), url("#{$roboto-font-path}/roboto-light.ttf") format("truetype"); 13 | } 14 | 15 | @font-face { 16 | font-family: "Roboto"; 17 | font-style: normal; 18 | font-weight: 400; 19 | src: local("Roboto"), local("Roboto-Regular"), url("#{$roboto-font-path}/roboto-regular.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-regular.woff") format("woff"), url("#{$roboto-font-path}/roboto-regular.ttf") format("truetype"); 20 | } 21 | 22 | @font-face { 23 | font-family: "Roboto"; 24 | font-style: normal; 25 | font-weight: 500; 26 | src: local("Roboto Medium"), local("Roboto-Medium"), url("#{$roboto-font-path}/roboto-medium.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-medium.woff") format("woff"), url("#{$roboto-font-path}/roboto-medium.ttf") format("truetype"); 27 | } 28 | 29 | @font-face { 30 | font-family: "Roboto"; 31 | font-style: normal; 32 | font-weight: 700; 33 | src: local("Roboto Bold"), local("Roboto-Bold"), url("#{$roboto-font-path}/roboto-bold.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-bold.woff") format("woff"), url("#{$roboto-font-path}/roboto-bold.ttf") format("truetype"); 34 | } 35 | -------------------------------------------------------------------------------- /examples/ionic2/www/assets/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/ionic2/www/assets/icon/favicon.ico -------------------------------------------------------------------------------- /examples/ionic2/www/build/main.css.map: -------------------------------------------------------------------------------- 1 | null -------------------------------------------------------------------------------- /examples/ionic2/www/build/sw-toolbox.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.toolbox=e()}}(function(){return function e(t,n,r){function o(c,s){if(!n[c]){if(!t[c]){var a="function"==typeof require&&require;if(!s&&a)return a(c,!0);if(i)return i(c,!0);var u=new Error("Cannot find module '"+c+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[c]={exports:{}};t[c][0].call(f.exports,function(e){var n=t[c][1][e];return o(n?n:e)},f,f.exports,e,t,n,r)}return n[c].exports}for(var i="function"==typeof require&&require,c=0;ct.value[l]){var r=t.value[p];c.push(r),a.delete(r),t.continue()}},s.oncomplete=function(){r(c)},s.onabort=o}):Promise.resolve([])}function s(e,t){return t?new Promise(function(n,r){var o=[],i=e.transaction(h,"readwrite"),c=i.objectStore(h),s=c.index(l),a=s.count();s.count().onsuccess=function(){var e=a.result;e>t&&(s.openCursor().onsuccess=function(n){var r=n.target.result;if(r){var i=r.value[p];o.push(i),c.delete(i),e-o.length>t&&r.continue()}})},i.oncomplete=function(){n(o)},i.onabort=r}):Promise.resolve([])}function a(e,t,n,r){return c(e,n,r).then(function(n){return s(e,t).then(function(e){return n.concat(e)})})}var u="sw-toolbox-",f=1,h="store",p="url",l="timestamp",d={};t.exports={getDb:o,setTimestampForUrl:i,expireEntries:a}},{}],3:[function(e,t,n){"use strict";function r(e){var t=a.match(e.request);t?e.respondWith(t(e.request)):a.default&&"GET"===e.request.method&&0===e.request.url.indexOf("http")&&e.respondWith(a.default(e.request))}function o(e){s.debug("activate event fired");var t=u.cache.name+"$$$inactive$$$";e.waitUntil(s.renameCache(t,u.cache.name))}function i(e){return e.reduce(function(e,t){return e.concat(t)},[])}function c(e){var t=u.cache.name+"$$$inactive$$$";s.debug("install event fired"),s.debug("creating cache ["+t+"]"),e.waitUntil(s.openCache({cache:{name:t}}).then(function(e){return Promise.all(u.preCacheItems).then(i).then(s.validatePrecacheInput).then(function(t){return s.debug("preCache list: "+(t.join(", ")||"(none)")),e.addAll(t)})}))}e("serviceworker-cache-polyfill");var s=e("./helpers"),a=e("./router"),u=e("./options");t.exports={fetchListener:r,activateListener:o,installListener:c}},{"./helpers":1,"./options":4,"./router":6,"serviceworker-cache-polyfill":16}],4:[function(e,t,n){"use strict";var r;r=self.registration?self.registration.scope:self.scope||new URL("./",self.location).href,t.exports={cache:{name:"$$$toolbox-cache$$$"+r+"$$$",maxAgeSeconds:null,maxEntries:null},debug:!1,networkTimeoutSeconds:null,preCacheItems:[],successResponses:/^0|([123]\d\d)|(40[14567])|410$/}},{}],5:[function(e,t,n){"use strict";var r=new URL("./",self.location),o=r.pathname,i=e("path-to-regexp"),c=function(e,t,n,r){t instanceof RegExp?this.fullUrlRegExp=t:(0!==t.indexOf("/")&&(t=o+t),this.keys=[],this.regexp=i(t,this.keys)),this.method=e,this.options=r,this.handler=n};c.prototype.makeHandler=function(e){var t;if(this.regexp){var n=this.regexp.exec(e);t={},this.keys.forEach(function(e,r){t[e.name]=n[r+1]})}return function(e){return this.handler(e,t,this.options)}.bind(this)},t.exports=c},{"path-to-regexp":15}],6:[function(e,t,n){"use strict";function r(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var o=e("./route"),i=e("./helpers"),c=function(e,t){for(var n=e.entries(),r=n.next(),o=[];!r.done;){var i=new RegExp(r.value[0]);i.test(t)&&o.push(r.value[1]),r=n.next()}return o},s=function(){this.routes=new Map,this.routes.set(RegExp,new Map),this.default=null};["get","post","put","delete","head","any"].forEach(function(e){s.prototype[e]=function(t,n,r){return this.add(e,t,n,r)}}),s.prototype.add=function(e,t,n,c){c=c||{};var s;t instanceof RegExp?s=RegExp:(s=c.origin||self.location.origin,s=s instanceof RegExp?s.source:r(s)),e=e.toLowerCase();var a=new o(e,t,n,c);this.routes.has(s)||this.routes.set(s,new Map);var u=this.routes.get(s);u.has(e)||u.set(e,new Map);var f=u.get(e),h=a.regexp||a.fullUrlRegExp;f.has(h.source)&&i.debug('"'+t+'" resolves to same regex as existing route.'),f.set(h.source,a)},s.prototype.matchMethod=function(e,t){var n=new URL(t),r=n.origin,o=n.pathname;return this._match(e,c(this.routes,r),o)||this._match(e,[this.routes.get(RegExp)],t)},s.prototype._match=function(e,t,n){if(0===t.length)return null;for(var r=0;r0)return s[0].makeHandler(n)}}return null},s.prototype.match=function(e){return this.matchMethod(e.method,e.url)||this.matchMethod("any",e.url)},t.exports=new s},{"./helpers":1,"./route":5}],7:[function(e,t,n){"use strict";function r(e,t,n){return o.debug("Strategy: cache first ["+e.url+"]",n),o.openCache(n).then(function(t){return t.match(e).then(function(t){return t?t:o.fetchAndCache(e,n)})})}var o=e("../helpers");t.exports=r},{"../helpers":1}],8:[function(e,t,n){"use strict";function r(e,t,n){return o.debug("Strategy: cache only ["+e.url+"]",n),o.openCache(n).then(function(t){return t.match(e)})}var o=e("../helpers");t.exports=r},{"../helpers":1}],9:[function(e,t,n){"use strict";function r(e,t,n){return o.debug("Strategy: fastest ["+e.url+"]",n),new Promise(function(r,c){var s=!1,a=[],u=function(e){a.push(e.toString()),s?c(new Error('Both cache and network failed: "'+a.join('", "')+'"')):s=!0},f=function(e){e instanceof Response?r(e):u("No result returned")};o.fetchAndCache(e.clone(),n).then(f,u),i(e,t,n).then(f,u)})}var o=e("../helpers"),i=e("./cacheOnly");t.exports=r},{"../helpers":1,"./cacheOnly":8}],10:[function(e,t,n){t.exports={networkOnly:e("./networkOnly"),networkFirst:e("./networkFirst"),cacheOnly:e("./cacheOnly"),cacheFirst:e("./cacheFirst"),fastest:e("./fastest")}},{"./cacheFirst":7,"./cacheOnly":8,"./fastest":9,"./networkFirst":11,"./networkOnly":12}],11:[function(e,t,n){"use strict";function r(e,t,n){n=n||{};var r=n.successResponses||o.successResponses,c=n.networkTimeoutSeconds||o.networkTimeoutSeconds;return i.debug("Strategy: network first ["+e.url+"]",n),i.openCache(n).then(function(t){var o,s,a=[];if(c){var u=new Promise(function(n){o=setTimeout(function(){t.match(e).then(function(e){e&&n(e)})},1e3*c)});a.push(u)}var f=i.fetchAndCache(e,n).then(function(e){if(o&&clearTimeout(o),r.test(e.status))return e;throw i.debug("Response was an HTTP error: "+e.statusText,n),s=e,new Error("Bad response")}).catch(function(r){return i.debug("Network or response error, fallback to cache ["+e.url+"]",n),t.match(e).then(function(e){if(e)return e;if(s)return s;throw r})});return a.push(f),Promise.race(a)})}var o=e("../options"),i=e("../helpers");t.exports=r},{"../helpers":1,"../options":4}],12:[function(e,t,n){"use strict";function r(e,t,n){return o.debug("Strategy: network only ["+e.url+"]",n),fetch(e)}var o=e("../helpers");t.exports=r},{"../helpers":1}],13:[function(e,t,n){"use strict";var r=e("./options"),o=e("./router"),i=e("./helpers"),c=e("./strategies"),s=e("./listeners");i.debug("Service Worker Toolbox is loading"),self.addEventListener("install",s.installListener),self.addEventListener("activate",s.activateListener),self.addEventListener("fetch",s.fetchListener),t.exports={networkOnly:c.networkOnly,networkFirst:c.networkFirst,cacheOnly:c.cacheOnly,cacheFirst:c.cacheFirst,fastest:c.fastest,router:o,options:r,cache:i.cache,uncache:i.uncache,precache:i.precache}},{"./helpers":1,"./listeners":3,"./options":4,"./router":6,"./strategies":10}],14:[function(e,t,n){t.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},{}],15:[function(e,t,n){function r(e){for(var t,n=[],r=0,o=0,i="";null!=(t=x.exec(e));){var c=t[0],s=t[1],a=t.index;if(i+=e.slice(o,a),o=a+c.length,s)i+=s[1];else{var f=e[o],h=t[2],p=t[3],l=t[4],d=t[5],g=t[6],m=t[7];i&&(n.push(i),i="");var v=null!=h&&null!=f&&f!==h,w="+"===g||"*"===g,y="?"===g||"*"===g,b=t[2]||"/",E=l||d||(m?".*":"[^"+b+"]+?");n.push({name:p||r++,prefix:h||"",delimiter:b,optional:y,repeat:w,partial:v,asterisk:!!m,pattern:u(E)})}}return o=46||"Chrome"===n&&r>=50)||(Cache.prototype.addAll=function(e){function t(e){this.name="NetworkError",this.code=19,this.message=e}var n=this;return t.prototype=Object.create(Error.prototype),Promise.resolve().then(function(){if(arguments.length<1)throw new TypeError;return e=e.map(function(e){return e instanceof Request?e:String(e)}),Promise.all(e.map(function(e){"string"==typeof e&&(e=new Request(e));var n=new URL(e.url).protocol;if("http:"!==n&&"https:"!==n)throw new t("Invalid scheme");return fetch(e.clone())}))}).then(function(r){if(r.some(function(e){return!e.ok}))throw new t("Incorrect response status");return Promise.all(r.map(function(t,r){return n.put(e[r],t)}))}).then(function(){})},Cache.prototype.add=function(e){return this.addAll([e])})}()},{}]},{},[13])(13)}); 16 | //# sourceMappingURL=sw-toolbox.js.map 17 | -------------------------------------------------------------------------------- /examples/ionic2/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | Ionic App 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /examples/ionic2/www/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Ionic", 3 | "short_name": "Ionic", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "icons": [{ 7 | "src": "assets/imgs/logo.png", 8 | "sizes": "512x512", 9 | "type": "image/png" 10 | }], 11 | "background_color": "#4e8ef7", 12 | "theme_color": "#4e8ef7" 13 | } -------------------------------------------------------------------------------- /examples/ionic2/www/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check out https://googlechrome.github.io/sw-toolbox/ for 3 | * more info on how to use sw-toolbox to custom configure your service worker. 4 | */ 5 | 6 | 7 | 'use strict'; 8 | importScripts('./build/sw-toolbox.js'); 9 | 10 | self.toolbox.options.cache = { 11 | name: 'ionic-cache' 12 | }; 13 | 14 | // pre-cache our key assets 15 | self.toolbox.precache( 16 | [ 17 | './build/main.js', 18 | './build/main.css', 19 | './build/polyfills.js', 20 | 'index.html', 21 | 'manifest.json' 22 | ] 23 | ); 24 | 25 | // dynamically cache any other local assets 26 | self.toolbox.router.any('/*', self.toolbox.cacheFirst); 27 | 28 | // for any other requests go to the network, cache, 29 | // and then only use that cached resource if your user goes offline 30 | self.toolbox.router.default = self.toolbox.networkFirst; 31 | -------------------------------------------------------------------------------- /examples/testapp/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "www/lib" 3 | } 4 | -------------------------------------------------------------------------------- /examples/testapp/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | insert_final_newline = false 14 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /examples/testapp/.gitignore: -------------------------------------------------------------------------------- 1 | # Specifies intentionally untracked files to ignore when using Git 2 | # http://git-scm.com/docs/gitignore 3 | 4 | node_modules/ 5 | platforms/ 6 | plugins/ 7 | -------------------------------------------------------------------------------- /examples/testapp/README.md: -------------------------------------------------------------------------------- 1 | # Test App 2 | 3 | Simple ionic test app to show usage of wheel selector 4 | 5 | run the `./init.sh` after cloning. 6 | 7 | build as usual: 8 | 9 | ``` 10 | ionic platform add android 11 | ionic build android 12 | ``` 13 | 14 | Then can install the apk. 15 | 16 | The `adb_install.sh` will build and push to a device hooked to your local machine. 17 | 18 | The `link.sh` will link to the local plugin rather than the one out on npm registry, after running that can use android studio: 19 | 20 | Install android studio, and open it, then create a blank project, then: 21 | 22 | `File->new->import project` and browse to the `platforms/android` directory and import from that directory (there's a gradle script in there). 23 | 24 | This should allow for IDE auto-completion, etc. 25 | 26 | If you modify any file other than the `.java` file you need to uninstall the plugin and re-install it, re-run the `link.sh` script. 27 | 28 | -------------------------------------------------------------------------------- /examples/testapp/adb_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | $ANDROID_HOME/platform-tools/adb uninstall com.ionicframework.myapp417044 4 | ionic cordova build android 5 | $ANDROID_HOME/platform-tools/adb install platforms/android/build/outputs/apk/android-debug.apk 6 | $ANDROID_HOME/platform-tools/adb shell am start -n io.appium.unlock/.Unlock 7 | $ANDROID_HOME/platform-tools/adb shell am start -n com.ionicframework.myapp417044/.MainActivity 8 | 9 | -------------------------------------------------------------------------------- /examples/testapp/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HelloIonic", 3 | "private": "true", 4 | "devDependencies": { 5 | "ionic": "driftyco/ionic-bower#1.3.2" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/testapp/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -rf ./hooks/ ./node_modules/ ./platforms/ ./res/ ./resources/android ./resources/ios ./www/lib ./plugins 4 | -------------------------------------------------------------------------------- /examples/testapp/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | WheelSelector 4 | 5 | An Ionic Framework and Cordova project. 6 | 7 | 8 | Your Name Here 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 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/testapp/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var gutil = require('gulp-util'); 3 | var bower = require('bower'); 4 | var concat = require('gulp-concat'); 5 | var sass = require('gulp-sass'); 6 | var minifyCss = require('gulp-minify-css'); 7 | var rename = require('gulp-rename'); 8 | var sh = require('shelljs'); 9 | 10 | var paths = { 11 | sass: ['./scss/**/*.scss'] 12 | }; 13 | 14 | gulp.task('default', ['sass']); 15 | 16 | gulp.task('sass', function(done) { 17 | gulp.src('./scss/ionic.app.scss') 18 | .pipe(sass()) 19 | .on('error', sass.logError) 20 | .pipe(gulp.dest('./www/css/')) 21 | .pipe(minifyCss({ 22 | keepSpecialComments: 0 23 | })) 24 | .pipe(rename({ extname: '.min.css' })) 25 | .pipe(gulp.dest('./www/css/')) 26 | .on('end', done); 27 | }); 28 | 29 | gulp.task('watch', ['sass'], function() { 30 | gulp.watch(paths.sass, ['sass']); 31 | }); 32 | 33 | gulp.task('install', ['git-check'], function() { 34 | return bower.commands.install() 35 | .on('log', function(data) { 36 | gutil.log('bower', gutil.colors.cyan(data.id), data.message); 37 | }); 38 | }); 39 | 40 | gulp.task('git-check', function(done) { 41 | if (!sh.which('git')) { 42 | console.log( 43 | ' ' + gutil.colors.red('Git is not installed.'), 44 | '\n Git, the version control system, is required to download Ionic.', 45 | '\n Download git here:', gutil.colors.cyan('http://git-scm.com/downloads') + '.', 46 | '\n Once git is installed, run \'' + gutil.colors.cyan('gulp install') + '\' again.' 47 | ); 48 | process.exit(1); 49 | } 50 | done(); 51 | }); 52 | -------------------------------------------------------------------------------- /examples/testapp/init-android.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | npm install 4 | bower install 5 | ionic cordova resources android 6 | ionic cordova platform add android 7 | ionic cordova resources 8 | 9 | echo 'Can now install and run the app...' 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/testapp/init-ios.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | npm install 4 | bower install 5 | ionic resources ios 6 | ionic platform add ios 7 | ionic resources 8 | 9 | echo 'Can now install and run the app...' 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/testapp/ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WheelSelector", 3 | "app_id": "", 4 | "type": "ionic1", 5 | "watchPatterns": [ 6 | "scss/**/*" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/testapp/link-local.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #link to the plugin rather than getting the installed on out on npm registry 4 | cordova plugin rm cordova-wheel-selector-plugin 5 | cordova plugin add --link ../../ 6 | -------------------------------------------------------------------------------- /examples/testapp/link-remote.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #get the released plugin in npm registry 4 | cordova plugin rm cordova-wheel-selector-plugin 5 | cordova plugin add cordova-wheel-selector-plugin 6 | -------------------------------------------------------------------------------- /examples/testapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WheelSelector", 3 | "version": "1.1.1", 4 | "description": "Wheel Selector example", 5 | "dependencies": { 6 | "gulp": "^3.5.6", 7 | "gulp-sass": "^2.0.4", 8 | "gulp-concat": "^2.2.0", 9 | "gulp-minify-css": "^0.3.0", 10 | "gulp-rename": "^1.2.0" 11 | }, 12 | "devDependencies": { 13 | "@ionic/cli-plugin-cordova": "1.4.0", 14 | "@ionic/cli-plugin-gulp": "1.0.1", 15 | "@ionic/cli-plugin-ionic1": "2.0.0", 16 | "bower": "^1.3.3", 17 | "gulp-util": "^2.2.14", 18 | "shelljs": "^0.3.0" 19 | }, 20 | "cordovaPlugins": [ 21 | "cordova-plugin-whitelist", 22 | "cordova-plugin-console", 23 | "cordova-plugin-statusbar", 24 | "cordova-plugin-device", 25 | "cordova-plugin-splashscreen", 26 | "ionic-plugin-keyboard" 27 | ], 28 | "cordovaPlatforms": [ 29 | "android", 30 | "ios" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /examples/testapp/resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/testapp/resources/icon.png -------------------------------------------------------------------------------- /examples/testapp/resources/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/testapp/resources/splash.png -------------------------------------------------------------------------------- /examples/testapp/scss/ionic.app.scss: -------------------------------------------------------------------------------- 1 | /* 2 | To customize the look and feel of Ionic, you can override the variables 3 | in ionic's _variables.scss file. 4 | 5 | For example, you might change some of the default colors: 6 | 7 | $light: #fff !default; 8 | $stable: #f8f8f8 !default; 9 | $positive: #387ef5 !default; 10 | $calm: #11c1f3 !default; 11 | $balanced: #33cd5f !default; 12 | $energized: #ffc900 !default; 13 | $assertive: #ef473a !default; 14 | $royal: #886aea !default; 15 | $dark: #444 !default; 16 | */ 17 | 18 | // The path for our ionicons font files, relative to the built CSS in www/css 19 | $ionicons-font-path: "../lib/ionic/fonts" !default; 20 | 21 | // Include all of Ionic 22 | @import "www/lib/ionic/scss/ionic"; 23 | 24 | -------------------------------------------------------------------------------- /examples/testapp/www/css/style.css: -------------------------------------------------------------------------------- 1 | /* Empty. Add your own CSS if you like */ 2 | -------------------------------------------------------------------------------- /examples/testapp/www/img/ionic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonmamy/cordova-wheel-selector-plugin/4c326a79e6221e563d213056619bce5d094c5ea2/examples/testapp/www/img/ionic.png -------------------------------------------------------------------------------- /examples/testapp/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |

Cordova wheel selector example

45 |
46 | 47 | 48 |
49 | 50 |
51 | 57 |
58 | 59 |
60 | 66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | 76 |
77 |
78 | 79 | 80 | -------------------------------------------------------------------------------- /examples/testapp/www/js/app.js: -------------------------------------------------------------------------------- 1 | angular.module('starter', ['ionic']) 2 | 3 | .run(function($ionicPlatform) { 4 | $ionicPlatform.ready(function() { 5 | if(window.cordova && window.cordova.plugins.Keyboard) { 6 | cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); 7 | cordova.plugins.Keyboard.disableScroll(true); 8 | } 9 | if(window.StatusBar) { 10 | StatusBar.styleDefault(); 11 | } 12 | }); 13 | }) 14 | .constant('testdata', { 15 | simpledata: { 16 | numbers: [ 17 | {description: "1"}, 18 | {description: "2"}, 19 | {description: "3"}, 20 | {description: "4"}, 21 | {description: "5"}, 22 | {description: "6"}, 23 | {description: "7"}, 24 | {description: "8"}, 25 | {description: "9"}, 26 | {description: "10"} 27 | ], 28 | fruits: [ 29 | {description: "Apple"}, 30 | {description: "Orange"}, 31 | {description: "Pear"}, 32 | {description: "Banana"}, 33 | {description: "Grapefruit"}, 34 | {description: "Tangerine"} 35 | ], 36 | measurements: [ 37 | {description: "Teaspoon"}, 38 | {description: "Tablespoon"}, 39 | {description: "Cup(s)"}, 40 | {description: "Quart(s)"}, 41 | {description: "Packages (7 oz)"}, 42 | {description: "Packages (12 oz)"} 43 | ], 44 | planets: [ 45 | {description: "Venus"}, 46 | {description: "Jupiter"}, 47 | {description: "Earth"}, 48 | {description: "Pluto"}, 49 | {description: "Neptune"} 50 | ] 51 | } 52 | , 53 | complex: { 54 | numbers:[ 55 | //intentional blanks - show up in ui as blanks 56 | {id: "", text: "", value: ""}, 57 | {id: "id1", text: "1", value: "one"}, 58 | {id: "id2", text: "2", value:"two"}, 59 | {id: "id3", text: "3", value:"three"}, 60 | {id: "id4", text: "4", value:"four"}, 61 | {id: "id5", text: "5", value:"five"}, 62 | {id: "id6", text: "6", value:"six"}, 63 | {id: "id7", text: "7", value:"seven"}, 64 | {id: "id8", text: "8", value:"eight"}, 65 | {id: "id9", text: "9", value:"nine"}, 66 | {id: "id10", text: "10", value:"ten"} 67 | ], 68 | measurements:[ 69 | //intentional blanks - show up in ui as blanks 70 | {id: "", text: "", value: ""}, 71 | {id: "id-17", text: "Teaspoon", value:"1tsp"}, 72 | {id: "id-23", text: "Tablespoon", value:"1tbsp"}, 73 | {id: "id-88", text: "Cup(s)", value:"1cup"}, 74 | {id: "id-54", text: "Quart(s)", value:"1quart"}, 75 | {id: "id-32", text: "Package (7 oz)", value:"7ozPckg"}, 76 | {id: "id-58", text: "Package (12 oz)", value:"12ozPckg"} 77 | ] 78 | } 79 | }) 80 | .controller('main', function ($scope, $ionicModal, $ionicPopup, testdata) { 81 | var themeColor = 'light'; 82 | var wrapWheelText = false; 83 | 84 | $scope.selectTheme = function(userSelected) { 85 | 86 | if(userSelected.length == 0) { 87 | themeColor = 'light'; 88 | }else{ 89 | themeColor = userSelected; 90 | } 91 | } 92 | 93 | $scope.selectWrapWheelText = function(toWrap) { 94 | 95 | if(toWrap.length == 0) { 96 | wrapWheelText = false; 97 | }else{ 98 | wrapWheelText = true; 99 | } 100 | console.log('wrap is: ' + wrapWheelText); 101 | } 102 | 103 | $scope.selectSomeFruit = function() { 104 | 105 | if (window.SelectorCordovaPlugin) { 106 | var configSimple1 = { 107 | title: "How Many Fruit?", 108 | items: [ 109 | [testdata.simpledata.numbers], 110 | [testdata.simpledata.fruits] 111 | ], 112 | positiveButtonText: "Ok", 113 | negativeButtonText: "Cancel", 114 | theme: themeColor, 115 | wrapWheelText: wrapWheelText 116 | } 117 | window.SelectorCordovaPlugin.showSelector(configSimple1, function(result) { 118 | console.log("result: " + JSON.stringify(result)); 119 | var alertPopup = $ionicPopup.alert({ 120 | title: 'You Selected', 121 | template: '
' + result[0].description + ' ' + result[1].description + '(s)' + '
' 122 | }); 123 | }); 124 | } else { 125 | console.log('no plugin'); 126 | alert('cordova-wheel-selector-plugin not available in browser, install and run on device!'); 127 | } 128 | } 129 | 130 | $scope.selectNumber = function() { 131 | 132 | if (window.SelectorCordovaPlugin) { 133 | var configSimple2 = { 134 | title: "How Many?", 135 | items: [ 136 | [testdata.simpledata.numbers] 137 | ], 138 | positiveButtonText: "Ok", 139 | negativeButtonText: "No way", 140 | theme: themeColor, 141 | wrapWheelText: wrapWheelText 142 | } 143 | 144 | window.SelectorCordovaPlugin.showSelector(configSimple2, function(result) { 145 | console.log("result: " + JSON.stringify(result)); 146 | var alertPopup = $ionicPopup.alert({ 147 | title: 'You Selected', 148 | template: '
' + result[0].description + '
' 149 | }); 150 | }); 151 | } else { 152 | console.log('no plugin'); 153 | alert('cordova-wheel-selector-plugin not available in browser, install and run on device!'); 154 | } 155 | } 156 | 157 | $scope.selectQuantityNormal = function() { 158 | 159 | if (window.SelectorCordovaPlugin) { 160 | var configSimple3 = { 161 | title: "How Many?", 162 | items: [ 163 | [testdata.simpledata.numbers], 164 | [testdata.simpledata.measurements], 165 | [testdata.simpledata.fruits] 166 | ], 167 | positiveButtonText: "Done", 168 | negativeButtonText: "Cancel", 169 | theme: themeColor, 170 | wrapWheelText: wrapWheelText 171 | } 172 | 173 | window.SelectorCordovaPlugin.showSelector(configSimple3, function(result) { 174 | console.log("result: " + JSON.stringify(result)); 175 | var alertPopup = $ionicPopup.alert({ 176 | title: 'You Selected', 177 | template: '
' + result[0].description + ' ' + result[1].description + ' of ' + result[2].description + '
' 178 | }); 179 | }); 180 | } else { 181 | console.log('no plugin'); 182 | alert('cordova-wheel-selector-plugin not available in browser, install and run on device!'); 183 | } 184 | } 185 | 186 | $scope.selectQuantity = function() { 187 | 188 | if (window.SelectorCordovaPlugin) { 189 | var configSimple3 = { 190 | title: "How Many?", 191 | items: [ 192 | [testdata.simpledata.numbers], 193 | [testdata.simpledata.measurements], 194 | [testdata.simpledata.fruits], 195 | [testdata.simpledata.planets] 196 | ], 197 | positiveButtonText: "Done", 198 | negativeButtonText: "Cancel", 199 | theme: themeColor, 200 | wrapWheelText: wrapWheelText 201 | } 202 | 203 | window.SelectorCordovaPlugin.showSelector(configSimple3, function(result) { 204 | console.log("result: " + JSON.stringify(result)); 205 | var alertPopup = $ionicPopup.alert({ 206 | title: 'You Selected', 207 | template: '
' + result[0].description + ' ' + result[1].description + ' of ' + result[2].description + ' from ' + result[3].description + '
' 208 | }); 209 | }); 210 | } else { 211 | console.log('no plugin'); 212 | alert('cordova-wheel-selector-plugin not available in browser, install and run on device!'); 213 | } 214 | } 215 | 216 | $scope.selectQuantityComplex = function() { 217 | 218 | if (window.SelectorCordovaPlugin) { 219 | var configSimple4 = { 220 | title: "How Many?", 221 | items: [ 222 | [testdata.complex.numbers], 223 | [testdata.complex.measurements] 224 | ], 225 | positiveButtonText: "Yes", 226 | negativeButtonText: "No", 227 | displayKey: "text", 228 | theme: themeColor, 229 | wrapWheelText: wrapWheelText 230 | } 231 | 232 | window.SelectorCordovaPlugin.showSelector(configSimple4, function(result) { 233 | console.log("result: " + JSON.stringify(result)); 234 | var alertPopup = $ionicPopup.alert({ 235 | title: 'You Selected', 236 | template: '
' + testdata.complex.numbers[result[0].index].value + ' ' + testdata.complex.measurements[result[1].index].text + '
' 237 | }); 238 | }); 239 | } else { 240 | console.log('no plugin'); 241 | alert('cordova-wheel-selector-plugin not available in browser, install and run on device!'); 242 | } 243 | } 244 | 245 | $scope.selectFruitWithDefaultValues = function() { 246 | 247 | if (window.SelectorCordovaPlugin) { 248 | var configSimple1 = { 249 | title: "new Default values should be: 3 Pear ", 250 | items: [ 251 | [testdata.simpledata.numbers], 252 | [testdata.simpledata.fruits] 253 | ], 254 | positiveButtonText: "Ok", 255 | negativeButtonText: "Cancel", 256 | theme: themeColor, 257 | defaultItems: {"0": "3", "1": "Pear"}, //0=index, 3=value, 1=index, Pear=value 258 | wrapWheelText: wrapWheelText 259 | } 260 | 261 | window.SelectorCordovaPlugin.showSelector(configSimple1, function(result) { 262 | console.log("result: " + JSON.stringify(result)); 263 | var alertPopup = $ionicPopup.alert({ 264 | title: 'You Selected', 265 | template: '
' + result[0].description + ' ' + result[1].description + '(s)' + '
' 266 | }); 267 | }); 268 | } else { 269 | console.log('no plugin'); 270 | alert('cordova-wheel-selector-plugin not available in browser, install and run on device!'); 271 | } 272 | } 273 | 274 | $scope.selectFruitWithDefaultValuesThatDontExist = function() { 275 | 276 | if (window.SelectorCordovaPlugin) { 277 | var configSimple1 = { 278 | title: "Default values should be: 1 Apple", 279 | items: [ 280 | [testdata.simpledata.numbers], 281 | [testdata.simpledata.fruits] 282 | ], 283 | positiveButtonText: "Ok", 284 | negativeButtonText: "Cancel", 285 | theme: themeColor, 286 | defaultItems: {"0": "22", "1": "Apricot"}, //if not found default to 1st items in list 287 | wrapWheelText: wrapWheelText 288 | } 289 | 290 | window.SelectorCordovaPlugin.showSelector(configSimple1, function(result) { 291 | console.log("result: " + JSON.stringify(result)); 292 | var alertPopup = $ionicPopup.alert({ 293 | title: 'You Selected', 294 | template: '
' + result[0].description + ' ' + result[1].description + '(s)' + '
' 295 | }); 296 | }); 297 | } else { 298 | console.log('no plugin'); 299 | alert('cordova-wheel-selector-plugin not available in browser, install and run on device!'); 300 | } 301 | } 302 | }) 303 | -------------------------------------------------------------------------------- /examples/testapp/www/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "My Ionic App", 3 | "short_name": "My Ionic App", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "icons": [{ 7 | "src": "icon.png", 8 | "sizes": "512x512", 9 | "type": "image/png" 10 | }] 11 | } -------------------------------------------------------------------------------- /examples/testapp/www/service-worker.js: -------------------------------------------------------------------------------- 1 | self.addEventListener('activate', function (event) { 2 | 3 | }); 4 | 5 | self.addEventListener('fetch', function (event) { 6 | 7 | }); 8 | 9 | self.addEventListener('push', function (event) { 10 | 11 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cordova-wheel-selector-plugin", 3 | "version": "1.1.7", 4 | "cordova": { 5 | "id": "cordova-wheel-selector-plugin", 6 | "platforms": [ 7 | "android", 8 | "ios" 9 | ] 10 | }, 11 | "description": "A native Android/iOS wheel selector plugin for Cordova or Ionic projects (pick numbers, strings, etc)", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/jasonmamy/cordova-wheel-selector-plugin" 15 | }, 16 | "keywords": [ 17 | "picker", 18 | "numberpicker", 19 | "stringpicker", 20 | "wheelpicker", 21 | "ios", 22 | "android", 23 | "wheelselector" 24 | ], 25 | "author": "Jason Amy", 26 | "license": "MIT" 27 | } 28 | -------------------------------------------------------------------------------- /plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | Cordova Wheel Selector Plugin 7 | A simple wheel selector plugin 8 | MIT 9 | 10 | https://github.com/driftyco/cordova-plugin-template.git 11 | https://github.com/driftyco/cordova-plugin-template/issues 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 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/android/com/wellseek/cordova/SelectorCordovaPlugin.java: -------------------------------------------------------------------------------- 1 | /** 2 | */ 3 | package com.wellseek.cordova; 4 | 5 | import android.app.Activity; 6 | import android.app.AlertDialog; 7 | import android.content.DialogInterface; 8 | import android.graphics.Color; 9 | import android.graphics.Paint; 10 | import android.os.Build; 11 | import android.util.Log; 12 | import android.view.Gravity; 13 | import android.view.View; 14 | import android.widget.EditText; 15 | import android.widget.LinearLayout; 16 | import android.widget.NumberPicker; 17 | 18 | import org.apache.cordova.CallbackContext; 19 | import org.apache.cordova.CordovaInterface; 20 | import org.apache.cordova.CordovaPlugin; 21 | import org.apache.cordova.CordovaWebView; 22 | import org.apache.cordova.PluginResult; 23 | import org.json.JSONArray; 24 | import org.json.JSONException; 25 | import org.json.JSONObject; 26 | 27 | import java.lang.reflect.Field; 28 | import java.lang.reflect.InvocationTargetException; 29 | import java.lang.reflect.Method; 30 | import java.util.ArrayList; 31 | import java.util.Arrays; 32 | import java.util.List; 33 | 34 | import static com.wellseek.cordova.SelectorCordovaPlugin.SELECTOR_THEME; 35 | import static com.wellseek.cordova.SelectorCordovaPlugin.setNumberPickerTextColor; 36 | 37 | public class SelectorCordovaPlugin extends CordovaPlugin { 38 | public static final String TAG = "SelectorCordovaPlugin"; 39 | public static final String BLANK_STRING = ""; 40 | public static final String SPACE = " "; 41 | public static final int WIDTH = 50; 42 | public static final int HEIGHT = 50; 43 | 44 | public static boolean WHEEL_WRAP; 45 | public static final String LIGHT_THEME = "light"; 46 | public static final String DARK_THEME = "dark"; 47 | public static SelectorTheme SELECTOR_THEME = null; 48 | 49 | private static final String INDEX_KEY = "index"; 50 | private static final String DISPLAY_ITEMS_KEY = "displayItems"; 51 | private static final String DEFAULT_SELECTED_ITEMS_KEY = "defaultItems"; 52 | private static final String DISPLAY_KEY = "displayKey"; 53 | private static final String TITLE_KEY = "title"; 54 | private static final String POSITIVE_BUTTON_TEXT_KEY = "positiveButtonText"; 55 | private static final String NEGATIVE_BUTTON_TEXT_KEY = "negativeButtonText"; 56 | private static final String WRAP_WHEEL_TEXT_KEY = "wrapWheelText"; 57 | private static final String THEME_KEY = "theme"; 58 | 59 | public void initialize(CordovaInterface cordova, CordovaWebView webView) { 60 | super.initialize(cordova, webView); 61 | } 62 | 63 | public boolean execute(final String action, JSONArray args, final CallbackContext callbackContext) throws JSONException { 64 | 65 | final CordovaInterface cordova = this.cordova; 66 | 67 | if (action.equals("showSelector")) { 68 | 69 | Log.d(TAG, "************Showing Wheel Selector"); 70 | final JSONObject options = args.getJSONObject(0); 71 | 72 | String config = args.getString(0); 73 | Log.d(TAG, "Config options: " + config); 74 | final JSONArray items = options.getJSONArray(DISPLAY_ITEMS_KEY); 75 | JSONObject tmpDefaultItemsMightNotBeSet = null; 76 | 77 | try { 78 | tmpDefaultItemsMightNotBeSet = options.getJSONObject(DEFAULT_SELECTED_ITEMS_KEY); 79 | } 80 | catch(JSONException je) { 81 | tmpDefaultItemsMightNotBeSet = null; 82 | } 83 | 84 | final JSONObject defaultSelectedItems = tmpDefaultItemsMightNotBeSet; 85 | final String displayKey = options.getString(DISPLAY_KEY); 86 | final String title = options.getString(TITLE_KEY); 87 | final String positiveButton = options.getString(POSITIVE_BUTTON_TEXT_KEY); 88 | final String negativeButton = options.getString(NEGATIVE_BUTTON_TEXT_KEY); 89 | final String wrapSelectorText = options.getString(WRAP_WHEEL_TEXT_KEY); 90 | final String theme = options.getString(THEME_KEY); 91 | 92 | WHEEL_WRAP = Boolean.parseBoolean(wrapSelectorText); 93 | SELECTOR_THEME = new SelectorTheme(theme); 94 | 95 | //Log.d(TAG, "Config options: " + config); 96 | 97 | Runnable runnable = new Runnable() { 98 | public void run() { 99 | 100 | AlertDialog.Builder builder = new AlertDialog.Builder(cordova.getActivity(), SELECTOR_THEME.getAlertBuilderTheme()); 101 | builder.setTitle(title); 102 | builder.setCancelable(true); 103 | List views = null; 104 | try { 105 | views = getPickerViews(cordova.getActivity(), items, defaultSelectedItems); 106 | } catch (JSONException je) { 107 | Log.v(TAG, "Exception: " + je.getMessage()); 108 | } 109 | 110 | final List asFinal = views; 111 | LinearLayout layout = new LinearLayout(cordova.getActivity()); 112 | layout.setOrientation(LinearLayout.HORIZONTAL); 113 | 114 | LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(WIDTH, HEIGHT); 115 | params.gravity = Gravity.CENTER; 116 | layout.setLayoutParams(params); 117 | 118 | if (views != null) { 119 | for (int i = 0; i < views.size(); ++i) { 120 | 121 | layout.addView(views.get(i).getNumberPicker(), views.get(i).getLayoutParams()); 122 | } 123 | } else { 124 | Log.d(TAG, "error, views is null"); 125 | } 126 | 127 | builder 128 | .setCancelable(false) 129 | .setPositiveButton(positiveButton, 130 | new DialogInterface.OnClickListener() { 131 | public void onClick(DialogInterface dialog, 132 | int id) { 133 | JSONArray userSelectedValues = new JSONArray(); 134 | 135 | JSONObject jsonValue = null; 136 | try { 137 | 138 | String value; 139 | for (int i = 0; i < asFinal.size(); ++i) { 140 | jsonValue = new JSONObject(); 141 | 142 | value = asFinal.get(i).getDataToShow(asFinal.get(i).getNumberPicker().getValue()); 143 | jsonValue.put(INDEX_KEY, asFinal.get(i).getNumberPicker().getValue()); 144 | 145 | if (value != null && value.equalsIgnoreCase(SPACE)) 146 | jsonValue.put(displayKey, BLANK_STRING); 147 | else 148 | jsonValue.put(displayKey, value); 149 | 150 | userSelectedValues.put(jsonValue); 151 | } 152 | } catch (JSONException je) { 153 | 154 | } 155 | 156 | final PluginResult resultToReturnToJS = new PluginResult(PluginResult.Status.OK, (userSelectedValues)); 157 | callbackContext.sendPluginResult(resultToReturnToJS); 158 | dialog.dismiss(); 159 | 160 | } 161 | }) 162 | .setNegativeButton(negativeButton, 163 | new DialogInterface.OnClickListener() { 164 | public void onClick(DialogInterface dialog, 165 | int id) { 166 | Log.d(TAG, "User canceled"); 167 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR)); 168 | dialog.cancel(); 169 | } 170 | }); 171 | 172 | builder.setView(layout); 173 | 174 | AlertDialog alert = builder.create(); 175 | 176 | alert.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog; 177 | alert.show(); 178 | } 179 | }; 180 | 181 | this.cordova.getActivity().runOnUiThread(runnable); 182 | } 183 | 184 | return true; 185 | } 186 | 187 | public static List getPickerViews(Activity activity, JSONArray items, JSONObject defaultSelectedValues) throws JSONException { 188 | List views = new ArrayList(); 189 | for (int i = 0; i < items.length(); ++i) { 190 | if(defaultSelectedValues != null && defaultSelectedValues.length() == items.length()){ 191 | 192 | try { 193 | String defaultSelctedValue = defaultSelectedValues.getString(Integer.toString(i)); 194 | views.add(new PickerView(activity, items.getJSONArray(i), defaultSelctedValue)); 195 | }catch(JSONException je) { 196 | views.add(new PickerView(activity, items.getJSONArray(i), "")); 197 | } 198 | }else { 199 | views.add(new PickerView(activity, items.getJSONArray(i), "")); 200 | } 201 | } 202 | return views; 203 | } 204 | 205 | public static String[] toStringArray(JSONArray array) { 206 | if (array == null) 207 | return null; 208 | 209 | String[] arr = new String[array.length()]; 210 | for (int i = 0; i < arr.length; i++) { 211 | if (array.optString(i) != null && array.optString(i).equalsIgnoreCase(BLANK_STRING)) 212 | arr[i] = SPACE; 213 | else 214 | arr[i] = array.optString(i); 215 | } 216 | return arr; 217 | } 218 | 219 | public static boolean setNumberPickerTextColor(NumberPicker numberPicker, int color) { 220 | float myTextSize = 10; 221 | try{ 222 | if (android.os.Build.VERSION.SDK_INT >= 29){ 223 | // API >= 29 224 | Method setColorMethod = numberPicker.getClass().getMethod("setTextColor", int.class); 225 | setColorMethod.invoke(numberPicker, color); 226 | // numberPicker.setTextColor(color); 227 | // numberPicker.setOutlineAmbientShadowColor(color); 228 | } else{ 229 | // API < 29 230 | Field selectorWheelPaintField = numberPicker.getClass() 231 | .getDeclaredField("mSelectorWheelPaint"); 232 | selectorWheelPaintField.setAccessible(true); 233 | ((Paint) selectorWheelPaintField.get(numberPicker)).setColor(color); 234 | numberPicker.invalidate(); 235 | } 236 | } catch (NoSuchFieldException e) { 237 | System.out.println("setNumberPickerTextColor"); 238 | } catch (IllegalAccessException e) { 239 | System.out.println("setNumberPickerTextColor"); 240 | } catch (NoSuchMethodException e){ 241 | System.out.println("setNumberPickerTextColor"); 242 | }catch (InvocationTargetException e){ 243 | System.out.println("setNumberPickerTextColor"); 244 | } 245 | final int count = numberPicker.getChildCount(); 246 | for (int i = 0; i < count; i++) { 247 | View child = numberPicker.getChildAt(i); 248 | if (child instanceof EditText) { 249 | try { 250 | ((EditText) child).setTextColor(color); 251 | //this setTextSize works, but given the 'mTextSize' variable is set in ctor 252 | //the initial values are small, once activated they get larger 253 | //https://android.googlesource.com/platform/frameworks/base.git/+/android-cts-4.2_r1/core/java/android/widget/NumberPicker.java 254 | //((Paint) selectorWheelPaintField.get(numberPicker)).setTextSize(48); 255 | 256 | // return true; 257 | }catch (IllegalArgumentException e) { 258 | System.out.println("setNumberPickerTextColor"); 259 | } 260 | } 261 | } 262 | return false; 263 | } 264 | } 265 | 266 | 267 | class PickerView { 268 | private String[] dataToShow; 269 | private String defaultSelectedItemValue; 270 | private Activity activity; 271 | private NumberPicker picker; 272 | 273 | private LinearLayout.LayoutParams numPicerParams; 274 | 275 | public PickerView(Activity activity, JSONArray args, String defaulSelectedtItem) { 276 | dataToShow = SelectorCordovaPlugin.toStringArray(args); 277 | defaultSelectedItemValue = defaulSelectedtItem; 278 | this.activity = activity; 279 | } 280 | 281 | public NumberPicker getNumberPicker() { 282 | if (picker == null) { 283 | picker = new NumberPicker(activity); 284 | picker.setMinValue(0); 285 | picker.setMaxValue(dataToShow.length - 1); 286 | 287 | int index = -1; 288 | 289 | if(defaultSelectedItemValue != null && defaultSelectedItemValue.length() > 0) 290 | index = Arrays.asList(dataToShow).indexOf(defaultSelectedItemValue); 291 | 292 | if(index < 0) 293 | picker.setValue(0); 294 | else 295 | picker.setValue(index); 296 | 297 | picker.setDisplayedValues(dataToShow); 298 | picker.setWrapSelectorWheel(SelectorCordovaPlugin.WHEEL_WRAP); 299 | picker.setFocusable(false); 300 | 301 | picker.setFocusableInTouchMode(true); 302 | 303 | //turn off soft keyboard 304 | picker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); 305 | 306 | setNumberPickerTextColor(picker, SELECTOR_THEME.getNumberPickerTextColor()); 307 | } 308 | 309 | return picker; 310 | } 311 | 312 | 313 | public LinearLayout.LayoutParams getLayoutParams() { 314 | if (numPicerParams == null) { 315 | numPicerParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); 316 | numPicerParams.weight = 1; 317 | } 318 | return numPicerParams; 319 | } 320 | 321 | public String getDataToShow(int index) { 322 | return dataToShow[index]; 323 | } 324 | } 325 | 326 | 327 | class SelectorTheme { 328 | private String themeColors; 329 | 330 | public SelectorTheme(String theme) { 331 | themeColors = theme; 332 | } 333 | 334 | public int getNumberPickerTextColor() { 335 | if (themeColors.equalsIgnoreCase(SelectorCordovaPlugin.LIGHT_THEME)) { 336 | return Color.BLACK; 337 | } 338 | 339 | return Color.WHITE; 340 | } 341 | 342 | public int getAlertBuilderTheme() { 343 | if (themeColors.equalsIgnoreCase(SelectorCordovaPlugin.LIGHT_THEME)) { 344 | return android.R.style.Theme_DeviceDefault_Light_Dialog_Alert; 345 | } 346 | 347 | return android.R.style.Theme_DeviceDefault_Dialog_Alert; 348 | } 349 | } 350 | 351 | 352 | 353 | 354 | 355 | 356 | -------------------------------------------------------------------------------- /src/browser/PluginProxy.js: -------------------------------------------------------------------------------- 1 | function echo(success, error, opts) { 2 | 3 | console.log('********in browser echo for MyCordovaPlugin!'); 4 | var toast = undefined, 5 | toastId = undefined; 6 | 7 | if (opts && typeof(opts[0]) === 'string' && opts[0].length > 0) { 8 | toastId = 'toast' + Date.now(); 9 | toast = document.createElement('div'); 10 | toast.appendChild(document.createTextNode(opts[0])); 11 | toast.id = toastId; 12 | toast.style.width = '30%'; 13 | toast.style.borderStyle = 'solid'; 14 | toast.style.borderColor = '#777777'; 15 | toast.style.borderRadius = '5px'; 16 | toast.style.borderWidth = '2px'; 17 | toast.style.margin = '0 auto'; 18 | toast.style.marginTop = '30px'; 19 | toast.style.backgroundColor = '#999999'; 20 | toast.style.padding = '5px'; 21 | toast.style.fontSize = '1.5em'; 22 | toast.style.fontWeight = 'bold'; 23 | toast.style.textAlign = 'center'; 24 | toast.style.zIndex = 2147483647; 25 | 26 | document.body.appendChild(toast); 27 | 28 | setTimeout(function() { 29 | document 30 | .body 31 | .removeChild(document.getElementById(toastId)); 32 | }, 3000); 33 | 34 | success(opts[0]); 35 | } else { 36 | error('Empty message!'); 37 | } 38 | } 39 | 40 | module.exports = { 41 | echo: echo 42 | }; 43 | 44 | require('cordova/exec/proxy').add('MyCordovaPlugin', module.exports); 45 | -------------------------------------------------------------------------------- /src/ios/SelectorCordovaPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface SelectorCordovaPlugin : CDVPlugin 5 | 6 | - (void)showSelector:(CDVInvokedUrlCommand *)command; 7 | - (void)hideSelector:(CDVInvokedUrlCommand *)command; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /src/ios/SelectorCordovaPlugin.m: -------------------------------------------------------------------------------- 1 | #import "SelectorCordovaPlugin.h" 2 | 3 | #import 4 | 5 | 6 | #define IS_WIDESCREEN ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON ) 7 | #define IS_IPAD UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad 8 | #define DEVICE_ORIENTATION [UIDevice currentDevice].orientation 9 | 10 | // UIInterfaceOrientationMask vs. UIInterfaceOrientation 11 | // A function like this isn't available in the API. It is derived from the enum def for 12 | // UIInterfaceOrientationMask. 13 | #define OrientationMaskSupportsOrientation(mask, orientation) ((mask & (1 << orientation)) != 0) 14 | 15 | typedef NS_ENUM(NSInteger, SelectorResultType) { 16 | SelectorResultTypeCanceled = 0, 17 | SelectorResultTypeDone = 1 18 | }; 19 | 20 | @interface SelectorCordovaPlugin () 21 | 22 | @property (nonatomic, copy) NSString* callbackId; 23 | @property (nonatomic, strong) NSMutableDictionary *options; 24 | @property (nonatomic, strong) UIPickerView *pickerView; 25 | @property (nonatomic, strong) UIPopoverController *popoverController; 26 | @property (nonatomic, strong) UIView *modalView; 27 | @property (nonatomic, strong) NSArray *items; 28 | @property (nonatomic, strong) NSMutableDictionary *itemsSelectedIndexes; 29 | 30 | @end 31 | 32 | @implementation SelectorCordovaPlugin 33 | 34 | - (void)showSelector:(CDVInvokedUrlCommand *)command { 35 | _callbackId = command.callbackId; 36 | 37 | // NOTE: All default options are assumed to be set in JS code 38 | _options = [command.arguments objectAtIndex:0]; 39 | _items = [_options objectForKey:@"displayItems"]; 40 | 41 | UIView *view = [self createPickerView]; 42 | 43 | NSDictionary *defaultItems = [_options objectForKey:@"defaultItems"]; 44 | _itemsSelectedIndexes = [@{} mutableCopy]; 45 | 46 | for (int columnIndex = 0; columnIndex < _items.count; columnIndex++) { 47 | NSString *columnIndexString = [NSString stringWithFormat:@"%i", columnIndex]; 48 | NSInteger initialValueIndex = 0; 49 | 50 | if (defaultItems) { 51 | NSString *value = [defaultItems objectForKey:columnIndexString]; 52 | NSUInteger index = [[_items objectAtIndex:columnIndex] indexOfObject:value]; 53 | if (NSNotFound != index) { 54 | initialValueIndex = index; 55 | } 56 | } 57 | [_itemsSelectedIndexes setValue:@(initialValueIndex) forKey:columnIndexString]; 58 | [_pickerView selectRow:initialValueIndex inComponent:columnIndex animated:NO]; 59 | } 60 | 61 | if (IS_IPAD) { 62 | return [self presentPopoverForView:view]; 63 | } else { 64 | return [self presentModalViewForView:view]; 65 | } 66 | } 67 | 68 | - (void)hideSelector:(CDVInvokedUrlCommand *)command { 69 | if (_callbackId) { 70 | [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR] callbackId:_callbackId]; 71 | _callbackId = nil; 72 | } 73 | 74 | _callbackId = command.callbackId; 75 | [self didDismissWithCancelButton:self]; 76 | } 77 | 78 | - (UIView *)createPickerView { 79 | // Initialize container view 80 | UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, [self getSafeBottomPadding], self.viewSize.width, 260 + [self getSafeBottomPadding])]; 81 | if (@available(iOS 13, *)) { 82 | [view setBackgroundColor:[UIColor systemBackgroundColor]]; 83 | } 84 | else if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { 85 | [view setBackgroundColor:[UIColor colorWithRed:0.97 green:0.97 blue:0.97 alpha:1.0]]; 86 | } 87 | 88 | // Initialize toolbar 89 | UIToolbar *toolbar = [self createToolbar]; 90 | [view addSubview:toolbar]; 91 | 92 | // Initialize picker 93 | _pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 40.0f, self.viewSize.width, 260 - [self getSafeBottomPadding])]; 94 | [_pickerView setShowsSelectionIndicator:YES]; 95 | [_pickerView setDelegate:self]; 96 | 97 | // iOS7 picker draws a darkened alpha-only region on the first and last 8 pixels horizontally, but blurs the rest of its background. 98 | // To make the whole popup appear to be edge-to-edge, add blurring to the remaining left and right edges. 99 | if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { 100 | CGRect f = CGRectMake(0, toolbar.frame.origin.y, 8, view.frame.size.height - toolbar.frame.origin.y); 101 | 102 | UIToolbar *leftEdge = [[UIToolbar alloc] initWithFrame:f]; 103 | f.origin.x = view.frame.size.width - 8; 104 | 105 | UIToolbar *rightEdge = [[UIToolbar alloc] initWithFrame:f]; 106 | [view insertSubview:leftEdge atIndex:0]; 107 | [view insertSubview:rightEdge atIndex:0]; 108 | } 109 | 110 | [view addSubview:self.pickerView]; 111 | 112 | return view; 113 | } 114 | 115 | - (UIToolbar *)createToolbar { 116 | UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, self.viewSize.width, 44)]; 117 | toolbar.barStyle = (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) ? UIBarStyleDefault : UIBarStyleBlackTranslucent; 118 | NSMutableArray *buttons =[[NSMutableArray alloc] init]; 119 | 120 | // Create Cancel button 121 | UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:[_options objectForKey:@"negativeButtonText"] style:UIBarButtonItemStylePlain target:self action:@selector(didDismissWithCancelButton:)]; 122 | [buttons addObject:cancelButton]; 123 | 124 | // Create title label aligned to center and appropriate spacers 125 | UILabel *label =[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 180, 30)]; 126 | [label setTextAlignment:NSTextAlignmentCenter]; 127 | [label setTextColor:(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) ? [UIColor blackColor] : [UIColor whiteColor]]; 128 | [label setFont:[UIFont boldSystemFontOfSize:[[_options objectForKey:@"fontSize"] floatValue]]]; 129 | [label setBackgroundColor:[UIColor clearColor]]; 130 | [label setText:[_options objectForKey:@"title"]]; 131 | 132 | UIBarButtonItem *labelButton = [[UIBarButtonItem alloc] initWithCustomView:label]; 133 | UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 134 | [buttons addObject:flexSpace]; 135 | [buttons addObject:labelButton]; 136 | [buttons addObject:flexSpace]; 137 | 138 | // Create Done button 139 | UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:[_options objectForKey:@"positiveButtonText"] style:UIBarButtonItemStyleDone target:self action:@selector(didDismissWithDoneButton:)]; 140 | [buttons addObject:doneButton]; 141 | [toolbar setItems:buttons animated:YES]; 142 | 143 | return toolbar; 144 | } 145 | 146 | - (void)sendResultsFromPickerView:(UIPickerView *)pickerView resultType:(SelectorResultType)resultType { 147 | CDVPluginResult *pluginResult; 148 | 149 | if (resultType == SelectorResultTypeDone) { 150 | NSMutableArray *arr = [[NSMutableArray alloc] init]; 151 | NSArray *sortedKeys = [[_itemsSelectedIndexes allKeys] sortedArrayUsingSelector: @selector(compare:)]; 152 | 153 | for (NSString *key in sortedKeys) { 154 | NSString *theKey = key; 155 | NSInteger indexInDict = [theKey integerValue]; 156 | NSInteger index = [[_itemsSelectedIndexes objectForKey:key] integerValue]; 157 | NSString *indexAsString = [@(index) stringValue]; 158 | 159 | NSString *valueFound = _items[indexInDict][index]; 160 | NSDictionary *tmpDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 161 | indexAsString, @"index", 162 | valueFound, [_options objectForKey:@"displayKey"], nil]; 163 | 164 | [arr addObject:tmpDictionary]; 165 | } 166 | 167 | pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:arr]; 168 | } 169 | 170 | if (resultType == SelectorResultTypeCanceled) { 171 | pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; 172 | } 173 | 174 | [self.commandDelegate sendPluginResult:pluginResult callbackId:_callbackId]; 175 | _callbackId = nil; 176 | } 177 | 178 | #pragma mark - Show picker 179 | 180 | - (void)presentModalViewForView:(UIView *)view { 181 | [[NSNotificationCenter defaultCenter] addObserver:self 182 | selector:@selector(didRotate:) 183 | name:UIApplicationWillChangeStatusBarOrientationNotification 184 | object:nil]; 185 | 186 | CGRect viewFrame = CGRectMake(0, [self getSafeBottomPadding], self.viewSize.width, self.viewSize.height); 187 | [view setFrame:CGRectMake(0, viewFrame.size.height, viewFrame.size.width, 260 + [self getSafeBottomPadding])]; 188 | 189 | _modalView = [[UIView alloc] initWithFrame:viewFrame]; 190 | [_modalView setBackgroundColor:[UIColor clearColor]]; 191 | [_modalView addSubview:view]; 192 | 193 | // Add the modal view to current controller 194 | [self.webView.superview addSubview:self.modalView]; 195 | [self.webView.superview bringSubviewToFront:self.modalView]; 196 | 197 | // Present the view animated 198 | [UIView animateWithDuration:0.3 199 | delay:0.0 200 | options: 0 201 | animations:^{ 202 | [_modalView.subviews[0] setFrame: CGRectOffset(viewFrame, 0, viewFrame.size.height - (260 + [self getSafeBottomPadding]) - [self getSafeBottomPadding])]; 203 | [_modalView setBackgroundColor:[UIColor colorWithWhite:0.0 alpha:0.5]]; 204 | } 205 | completion:nil]; 206 | } 207 | 208 | - (void)presentPopoverForView:(UIView *)view { 209 | UIViewController *popoverContent = [[UIViewController alloc] initWithNibName:nil bundle:nil]; 210 | popoverContent.view = view; 211 | popoverContent.preferredContentSize = view.frame.size; 212 | 213 | self.popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent]; 214 | self.popoverController.delegate = self; 215 | 216 | // Present the popover view non-modal with a refrence to the button pressed within the current view 217 | // Display picker at the center of the view 218 | CGRect sourceRect = CGRectMake(self.webView.superview.center.x, self.webView.superview.center.y, 1, 1); 219 | [self.popoverController presentPopoverFromRect:sourceRect 220 | inView:self.webView.superview 221 | permittedArrowDirections: 0 222 | animated:YES]; 223 | } 224 | 225 | # pragma mark - Dismiss picker 226 | 227 | - (void)didRotate:(NSNotification *)notification { 228 | UIInterfaceOrientationMask supportedInterfaceOrientations = (UIInterfaceOrientationMask) [[UIApplication sharedApplication] supportedInterfaceOrientationsForWindow:[UIApplication sharedApplication].keyWindow]; 229 | 230 | if (OrientationMaskSupportsOrientation(supportedInterfaceOrientations, DEVICE_ORIENTATION)) { 231 | if (IS_IPAD) { 232 | [self dismissPopoverController:_popoverController animated:YES]; 233 | } else { 234 | [self dismissModalView:_modalView animated:YES]; 235 | } 236 | 237 | [self sendResultsFromPickerView:_pickerView resultType:SelectorResultTypeCanceled]; 238 | } 239 | } 240 | 241 | - (IBAction)didDismissWithDoneButton:(id)sender { 242 | if (IS_IPAD) { 243 | [self dismissPopoverController:_popoverController animated:YES]; 244 | } else { 245 | [self dismissModalView:_modalView animated:YES]; 246 | } 247 | 248 | [self sendResultsFromPickerView:_pickerView resultType:SelectorResultTypeDone]; 249 | } 250 | 251 | - (IBAction)didDismissWithCancelButton:(id)sender { 252 | if (IS_IPAD) { 253 | [self dismissPopoverController:_popoverController animated:YES]; 254 | } else { 255 | [self dismissModalView:_modalView animated:YES]; 256 | } 257 | 258 | [self sendResultsFromPickerView:_pickerView resultType:SelectorResultTypeCanceled]; 259 | } 260 | 261 | - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { 262 | [self sendResultsFromPickerView:_pickerView resultType:SelectorResultTypeCanceled]; 263 | } 264 | 265 | - (void)dismissPopoverController:(UIPopoverController *)popoverController animated:(Boolean)animated { 266 | [popoverController dismissPopoverAnimated:animated]; 267 | } 268 | 269 | - (void)dismissModalView:(UIView *)modalView animated:(Boolean)animated { 270 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillChangeStatusBarOrientationNotification object:nil]; 271 | 272 | // Hide the view animated 273 | [UIView animateWithDuration:0.3 274 | delay:0.0 275 | options: 0 276 | animations:^{ 277 | CGRect viewFrame = CGRectMake(0, 0, self.viewSize.width, self.viewSize.height); 278 | [_modalView.subviews[0] setFrame: CGRectOffset(viewFrame, 0, viewFrame.size.height)]; 279 | [_modalView setBackgroundColor:[UIColor clearColor]]; 280 | } 281 | completion:^(BOOL finished) { 282 | [_modalView removeFromSuperview]; 283 | }]; 284 | } 285 | 286 | #pragma mark - UIPickerViewDelegate 287 | 288 | - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { 289 | // The parameters named row and component represents what was selected. 290 | NSString* key = [NSString stringWithFormat:@"%li", (long)component]; 291 | [_itemsSelectedIndexes setValue:@(row) forKey:key]; 292 | } 293 | 294 | - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { 295 | UILabel* pickerLabel = (UILabel*)view; 296 | if (!pickerLabel) { 297 | pickerLabel = [[UILabel alloc] init]; 298 | pickerLabel.font = [UIFont fontWithName:@"SourceSansPro-Semibold" size:[[_options objectForKey:@"fontSize"] floatValue]]; 299 | pickerLabel.textAlignment=NSTextAlignmentCenter; 300 | } 301 | [pickerLabel setText:_items[component][row]]; 302 | return pickerLabel; 303 | } 304 | 305 | - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { 306 | return [_items[component] count]; 307 | } 308 | 309 | - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { 310 | return _items.count; 311 | } 312 | 313 | - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { 314 | return _items[component][row]; 315 | } 316 | 317 | - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component { 318 | if (self.items.count >= 2) { 319 | return (pickerView.frame.size.width) / self.items.count; 320 | } else { 321 | return pickerView.frame.size.width - 20; 322 | } 323 | } 324 | 325 | #pragma mark - Uitilities 326 | 327 | - (CGSize)viewSize { 328 | if (IS_IPAD) { 329 | return CGSizeMake(500, 320); 330 | } 331 | 332 | #if defined(__IPHONE_8_0) 333 | if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { 334 | //iOS 7.1 or earlier 335 | if ([self isViewPortrait]) 336 | return CGSizeMake(320 , IS_WIDESCREEN ? 568 : 480); 337 | return CGSizeMake(IS_WIDESCREEN ? 568 : 480, 320); 338 | } else { 339 | //iOS 8 or later 340 | return [[UIScreen mainScreen] bounds].size; 341 | } 342 | #else 343 | if ([self isViewPortrait]) { 344 | return CGSizeMake(320 , IS_WIDESCREEN ? 568 : 480); 345 | } 346 | return CGSizeMake(IS_WIDESCREEN ? 568 : 480, 320); 347 | #endif 348 | } 349 | 350 | - (CGFloat) getSafeBottomPadding { 351 | CGFloat bottomPadding = 0.0f; 352 | if (@available(iOS 11.0, *)) { 353 | UIWindow *window = UIApplication.sharedApplication.keyWindow; 354 | bottomPadding = window.safeAreaInsets.bottom; 355 | } 356 | 357 | return bottomPadding; 358 | } 359 | 360 | - (BOOL)isViewPortrait { 361 | return UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation); 362 | } 363 | 364 | @end 365 | -------------------------------------------------------------------------------- /www/selectorplugin.js: -------------------------------------------------------------------------------- 1 | var PLUGIN_NAME = 'SelectorCordovaPlugin'; 2 | var SelectorCordovaPlugin = function() {}; 3 | 4 | SelectorCordovaPlugin.prototype.showSelector = function(options, success_callback, error_callback) { 5 | options || (options = {}); 6 | var scope = options.scope || null; 7 | 8 | function Create2DArray(rows) { 9 | var arr = []; 10 | 11 | for (var i=0;i 0) { 95 | for (i in options.defaultItems) { 96 | defaultItemsList[options.defaultItems[i].index] = options.defaultItems[i].value; 97 | } 98 | } 99 | 100 | var _success_callback = function() { 101 | if(typeof success_callback == 'function') { 102 | success_callback.apply(scope, arguments); 103 | } 104 | }; 105 | 106 | var _error_callback = function() { 107 | if(typeof error_callback == 'function') { 108 | error_callback.apply(scope, arguments); 109 | } 110 | } 111 | 112 | return cordova.exec(_success_callback, _error_callback, PLUGIN_NAME, 'showSelector', [config]); 113 | }; 114 | 115 | SelectorCordovaPlugin.prototype.hideSelector = function(success_callback, error_callback) { 116 | return cordova.exec(success_callback, error_callback, PLUGIN_NAME, 'hideSelector', []); 117 | }; 118 | 119 | module.exports = new SelectorCordovaPlugin(); 120 | --------------------------------------------------------------------------------