A directive to select multiple options on Ionic
A Pen by Gil Furtado on CodePen.
<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>Side Menus</title> | |
<link href="//code.ionicframework.com/1.3.1/css/ionic.css" rel="stylesheet"> | |
<script src="//code.ionicframework.com/1.3.1/js/ionic.bundle.js"></script> | |
</head> | |
<body ng-controller="MainCtrl"> | |
<ion-nav-view></ion-nav-view> | |
<script id="templates/event-menu.html" type="text/ng-template"> | |
<ion-side-menus enable-menu-with-back-views="false"> | |
<ion-side-menu-content> | |
<ion-nav-bar class="bar-positive"> | |
<ion-nav-back-button> | |
</ion-nav-back-button> | |
<ion-nav-buttons side="left"> | |
<button class="button button-icon button-clear ion-navicon" menu-toggle="left"> | |
</button> | |
</ion-nav-buttons> | |
</ion-nav-bar> | |
<ion-nav-view name="menuContent"></ion-nav-view> | |
</ion-side-menu-content> | |
<ion-side-menu side="left"> | |
<ion-header-bar class="bar-assertive"> | |
<h1 class="title">Left Menu</h1> | |
</ion-header-bar> | |
<ion-content> | |
</ion-content> | |
</ion-side-menu> | |
</ion-side-menus> | |
</script> | |
<script id="templates/home.html" type="text/ng-template"> | |
<ion-view view-title="Directive to Select multiple options"> | |
<ion-content scroll="false"> | |
<ion-multiple-select title="Select Users" options="users" key-property="id" value-property="name" selected-property="selected" class="item item-input item-icon-right"> | |
<div class="input-label"> | |
User | |
</div> | |
<i class="icon ion-android-arrow-dropdown"></i> | |
</ion-multiple-select> | |
<textarea class="padding" disabled="disabled">{{ getOptionsSelected(users, 'name', 'selected') }}</textarea> | |
<ion-multiple-select title="Select Groups" template-url="templates/multipleSelect.html" options="groups" key-property="Id" value-property="Name" selected-property="Selected" class="item item-input item-icon-right" render-checkbox="false" animation="slide-in-left"> | |
<div class="input-label"> | |
Group | |
</div> | |
<i class="icon ion-android-arrow-dropdown"></i> | |
</ion-multiple-select> | |
<textarea class="padding" disabled="disabled">{{ getOptionsSelected(groups, 'Name', 'Selected') }}</textarea> | |
</ion-content> | |
</ion-view> | |
</script> | |
<script id="templates/multipleSelect.html" type="text/ng-template"> | |
<ion-modal-view> | |
<ion-header-bar align-title="center"> | |
<button class="button button-icon ion-close" ng-click="closeModal();"></button> | |
<h1 class="title">{{multipleSelect.title}}</h1> | |
<button class="button button-icon ion-checkmark" ng-click="saveOptions();"></button> | |
</ion-header-bar> | |
<ion-content scroll="false"> | |
<ul class="list"> | |
<li class="item item-toggle" ng-repeat="option in multipleSelect.tempOptions" ng-if="!multipleSelect.renderCheckbox"> | |
{{ option[multipleSelect.valueProperty] }} | |
<label class="toggle toggle-assertive"> | |
<input type="checkbox" ng-model="option[multipleSelect.selectedProperty]"> | |
<div class="track"> | |
<div class="handle"></div> | |
</div> | |
</label> | |
</li> | |
<li class="item item-checkbox" ng-repeat="option in multipleSelect.tempOptions" ng-if="multipleSelect.renderCheckbox"> | |
<label class="checkbox"> | |
<input type="checkbox" ng-model="option[multipleSelect.selectedProperty]"> | |
</label> | |
{{ option[multipleSelect.valueProperty] }} | |
</li> | |
</ul> | |
</ion-content> | |
</ion-modal-view> | |
</script> | |
</body> | |
</html> |
A directive to select multiple options on Ionic
A Pen by Gil Furtado on CodePen.
angular.module('ionicApp', ['ionic']) | |
.config(function($stateProvider, $urlRouterProvider) { | |
$stateProvider | |
.state('eventmenu', { | |
url: "/event", | |
abstract: true, | |
templateUrl: "templates/event-menu.html" | |
}) | |
.state('eventmenu.home', { | |
url: "/home", | |
views: { | |
'menuContent' :{ | |
templateUrl: "templates/home.html" | |
} | |
} | |
}); | |
$urlRouterProvider.otherwise("/event/home"); | |
}) | |
.controller('MainCtrl', function($scope, $timeout, $filter) { | |
$scope.users = [ | |
{id: 1, name: "Valentina", selected: true}, | |
{id: 2, name: "Juan David", selected: false}, | |
{id: 3, name: "Osman", selected: false}, | |
{id: 4, name: "Silva1", selected: false}, | |
{id: 5, name: "Silva2", selected: false}, | |
{id: 6, name: "Silva3", selected: false}, | |
{id: 7, name: "Silva4", selected: false}, | |
{id: 8, name: "Silva5", selected: false} | |
]; | |
$scope.groups = [ | |
{Id: 1, Name: "Admin", Selected: false}, | |
{Id: 2, Name: "Developers", Selected: false}, | |
{Id: 3, Name: "Testers", Selected: false}, | |
{Id: 4, Name: "Users", Selected: false} | |
, | |
{Id: 5, Name: "Users2", Selected: false} | |
, | |
{Id: 6, Name: "Users3", Selected: false} | |
, | |
{Id: 7, Name: "Users4", Selected: false} | |
]; | |
$scope.getOptionsSelected = function(options, valueProperty, selectedProperty){ | |
var optionsSelected = $filter('filter')(options, function(option) {return option[selectedProperty] == true; }); | |
return optionsSelected.map(function(group){ return group[valueProperty]; }).join(", "); | |
}; | |
}) | |
.directive('ionMultipleSelect', ['$ionicModal', '$ionicGesture', function ($ionicModal, $ionicGesture) { | |
return { | |
restrict: 'E', | |
scope: { | |
options : "=" | |
}, | |
controller: function ($scope, $element, $attrs) { | |
$scope.multipleSelect = { | |
title: $attrs.title || "Select Options", | |
tempOptions: [], | |
keyProperty: $attrs.keyProperty || "id", | |
valueProperty: $attrs.valueProperty || "value", | |
selectedProperty: $attrs.selectedProperty || "selected", | |
templateUrl: $attrs.templateUrl || 'templates/multipleSelect.html', | |
renderCheckbox: $attrs.renderCheckbox ? $attrs.renderCheckbox == "true" : true, | |
animation: $attrs.animation || 'slide-in-up' | |
}; | |
$scope.OpenModalFromTemplate = function (templateUrl) { | |
$ionicModal.fromTemplateUrl(templateUrl, { | |
scope: $scope, | |
animation: $scope.multipleSelect.animation | |
}).then(function (modal) { | |
$scope.modal = modal; | |
$scope.modal.show(); | |
}); | |
}; | |
$ionicGesture.on('tap', function (e) { | |
$scope.multipleSelect.tempOptions = $scope.options.map(function(option){ | |
var tempOption = { }; | |
tempOption[$scope.multipleSelect.keyProperty] = option[$scope.multipleSelect.keyProperty]; | |
tempOption[$scope.multipleSelect.valueProperty] = option[$scope.multipleSelect.valueProperty]; | |
tempOption[$scope.multipleSelect.selectedProperty] = option[$scope.multipleSelect.selectedProperty]; | |
return tempOption; | |
}); | |
$scope.OpenModalFromTemplate($scope.multipleSelect.templateUrl); | |
}, $element); | |
$scope.saveOptions = function(){ | |
for(var i = 0; i < $scope.multipleSelect.tempOptions.length; i++){ | |
var tempOption = $scope.multipleSelect.tempOptions[i]; | |
for(var j = 0; j < $scope.options.length; j++){ | |
var option = $scope.options[j]; | |
if(tempOption[$scope.multipleSelect.keyProperty] == option[$scope.multipleSelect.keyProperty]){ | |
option[$scope.multipleSelect.selectedProperty] = tempOption[$scope.multipleSelect.selectedProperty]; | |
break; | |
} | |
} | |
} | |
$scope.closeModal(); | |
}; | |
$scope.closeModal = function () { | |
$scope.modal.remove(); | |
}; | |
$scope.$on('$destroy', function () { | |
if ($scope.modal){ | |
$scope.modal.remove(); | |
} | |
}); | |
} | |
}; | |
}]); |
body { | |
cursor: url('https://ionicframework.com/img/finger.png'), auto; | |
} | |
textarea{ | |
width: 100%; | |
height: 120px; | |
border: 3px solid #cccccc !important; | |
} | |
.slide-in-left { | |
-webkit-transform: translate3d(100%, 0, 0); | |
-moz-transform: translate3d(100%, 0, 0); | |
-o-transform: translate3d(100%, 0, 0); | |
-ms-transform: translate3d(100%, 0, 0); | |
transform: translate3d(100%, 0, 0); } | |
.slide-in-left.ng-enter, .slide-in-left > .ng-enter { | |
-webkit-transition: all cubic-bezier(0.1, 0.7, 0.1, 1) 400ms; | |
-moz-transition: all cubic-bezier(0.1, 0.7, 0.1, 1) 400ms; | |
-o-transition: all cubic-bezier(0.1, 0.7, 0.1, 1) 400ms; | |
-ms-transition: all cubic-bezier(0.1, 0.7, 0.1, 1) 400ms; | |
transition: all cubic-bezier(0.1, 0.7, 0.1, 1) 400ms; | |
} | |
.slide-in-left.ng-enter-active, .slide-in-left > .ng-enter-active { | |
-webkit-transform: translate3d(0, 0, 0); | |
-moz-transform: translate3d(0, 0, 0); | |
-o-transform: translate3d(0, 0, 0); | |
-ms-transform: translate3d(0, 0, 0); | |
transform: translate3d(0, 0, 0); } | |
.slide-in-left.ng-leave, .slide-in-left > .ng-leave { | |
-webkit-transition: all ease-in-out 250ms; | |
-moz-transition: all ease-in-out 250ms; | |
-o-transition: all ease-in-out 250ms; | |
-ms-transition: all ease-in-out 250ms; | |
transition: all ease-in-out 250ms; | |
-webkit-transform: translate3d(-100%, 0, 0); | |
-moz-transform: translate3d(-100%, 0, 0); | |
-o-transform: translate3d(-100%, 0, 0); | |
-ms-transform: translate3d(-100%, 0, 0); | |
transform: translate3d(-100%, 0, 0); } |