Skip to content

Instantly share code, notes, and snippets.

@shaoner
Created September 12, 2015 21:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shaoner/009a6618f74773c061ea to your computer and use it in GitHub Desktop.
Save shaoner/009a6618f74773c061ea to your computer and use it in GitHub Desktop.
Select spinning wheel with ionic
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Select</title>
<link href="http://code.ionicframework.com/1.1.0/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.1.0/js/ionic.bundle.min.js"></script>
</head>
<body>
<ion-nav-bar></ion-nav-bar>
<ion-nav-view></ion-nav-view>
<script id="main.html" type="text/ng-template">
<ion-view view-title="Main">
<ion-content>
<div>Selected: {{data.month}}</div>
<div style="width:200px; background-color:#eee">
<select-wheel ng-model="data.month" item-height="50" amplitude="5" options="monthOptions"></select-wheel>
</div>
</ion-content>
</ion-view>
</script>
<script id="select-wheel.html" type="text/ng-template">
<div class="select-wheel">
<div class="select-wheel-sel"></div>
<ion-scroll zooming="false" on-scroll="onScroll(event, scrollTop)" direction="y" scrollbar-y="false">
<div class="select-wheel-list">
<div class="select-wheel-item">
</div>
<div class="select-wheel-item" ng-repeat="option in options">
<div ng-class="{'active': $index === _index}" data-value="option.value">{{option.label}}</div>
</div>
<div class="select-wheel-item">
</div>
</div>
</ion-scroll>
</div>
</script>
</body>
</html>
angular.module('ionicApp', ['ionic'])
.directive('selectWheel', [
'$ionicScrollDelegate',
'$ionicGesture',
function($ionicScrollDelegate, $ionicGesture) {
return {
restrict: 'E',
scope: {
itemHeight: '@',
amplitude: '@',
ngModel: '=',
options: '='
},
templateUrl: 'select-wheel.html',
link: function(scope, element) {
var _fixed = false,
_touched = false;
scope.itemHeight = scope.itemHeight || 50;
scope.amplitude = scope.amplitude || 5;
scope._index = 0;
// Try to identify the model to an option value
if (scope.ngModel !== 'undefined') {
for (var i = 0, len = scope.options.length; i < len; ++i) {
if (scope.options[i].value === scope.ngModel) {
scope._index = i;
break;
}
}
}
scope.onScroll = function(event, scrollTop) {
scrollTop = Math.round(scrollTop);
var height = scope.itemHeight,
amplitude = scope.amplitude,
remainder = scrollTop % height,
distance, nearestPos,
middle = Math.floor(height / 2),
index,
minDist = middle - amplitude;
// Find the distance between the item and the center of the wheel
// So if the height of the item is 50, it finds the nearest
// integer for scrollTop to reach a multiple of 50
// 160 = 3 * 50 + 10 => For 160, the distance is 10
// 145 = 3 * 50 - 5 => For 145, the distance is 5
if (remainder > middle) {
distance = height - remainder;
nearestPos = scrollTop + distance;
index = Math.floor(scrollTop / height) + 1;
} else {
distance = remainder;
nearestPos = scrollTop - distance;
index = Math.floor(scrollTop / height);
}
if (!_touched && !_fixed) {
$ionicScrollDelegate.scrollTo(0, nearestPos);
_fixed = true;
scope._index = index;
scope.$apply(function() {
scope.ngModel = scope.options[index].value;
});
}
};
// Detect when the wheel is touched
$ionicGesture.on('touch', function() {
_touched = true;
_fixed = false;
}, element, {});
$ionicGesture.on('release', function() {
_touched = false;
}, element, {});
// Scroll to the right value (depends on how ngModel was set)
$ionicScrollDelegate.scrollTo(0, scope._index * scope.itemHeight);
}
};
}
])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('main', {
url: "/home",
templateUrl: "main.html",
controller: 'MainCtrl'
});
$urlRouterProvider.otherwise("/home");
})
.controller('MainCtrl', function($scope) {
$scope.data = {};
$scope.data.month = 'march';
$scope.monthOptions = [{
label: 'Jan',
value: 'january'
}, {
label: 'Fev',
value: 'february'
}, {
label: 'Mar',
value: 'march'
}, {
label: 'Apr',
value: 'april'
}, {
label: 'May',
value: 'may'
}, {
label: 'Jun',
value: 'june'
}, {
label: 'Jul',
value: 'july'
}, {
label: 'Aug',
value: 'august'
}, {
label: 'Sep',
value: 'september'
}, {
label: 'Oct',
value: 'october'
}, {
label: 'Nov',
value: 'november'
}, {
label: 'Dec',
value: 'december'
}];
});
.select-wheel > ion-scroll {
height: 150px;
}
select-wheel {
position: relative;
}
.select-wheel-item {
height: 50px;
padding: 10px;
text-align: center;
display: block;
}
.select-wheel-item > * {
color: #aaa;
}
.select-wheel-item .active {
color: inherit;
}
.select-wheel {
position: relative;
}
.select-wheel-sel {
z-index: 1;
position: absolute;
top: 50px;
height: 50px;
left: 50%;
width: 100px;
margin-left: -50px;
border-top: 1px solid #3232d4;
border-bottom: 1px solid #3232d4;
}
@gppraveena
Copy link

Does this work with ionic 2

@welcomedk
Copy link

How can we perform this to Ionic2?

@safi9
Copy link

safi9 commented Feb 4, 2019

How to migrate this to angular 6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment