A Pen by Alexandre Laurent on CodePen.
Forked from shaoner/Select spinning wheel with ionic.markdown
Created
July 21, 2016 14:11
-
-
Save wolfg1969/468e65273654a52b92c45cd604e974f5 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment