A Pen by Alexandre Laurent on CodePen.
Created
September 12, 2015 21:57
-
-
Save shaoner/009a6618f74773c061ea to your computer and use it in GitHub Desktop.
Select spinning wheel with ionic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' | |
}]; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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; | |
} |
How can we perform this to Ionic2?
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
Does this work with ionic 2