I'm trying to sort items in a list of tasks by both their added date and their listed priority. I've done the sorting by date, but how can I sort the items so that those with the 'HIGH' property are organised first in the list?
EDIT: I need it to sort by HIGH when this option is select from the 'Sort By' select box above the task list.
Codepen: http://codepen.io/anon/pen/ryyQzy .
HTML:
<md-list class="md-padding">
<div layout="row">
<md-input-container class="md-block" flex="70">
<input type="text" ng-model="search" name="search" placeholder="Search by Task Name"></input>
</md-input-container>
<md-input-container flex="30">
<md-select name="priority" ng-model="task.priority" placeholder="Sort By">
<md-option value="Low">Newest First</md-option>
<md-option value="HIGH">High Priority First</md-option>
</md-select>
</md-input-container>
</div>
<md-subheader class="md-no-sticky">Current Tasks ({{taskList.length}})</md-subheader>
<md-list-item class="md-3-line" ng-repeat="task in taskList | orderBy:sortByNewest | filter:search">
<div class="md-list-item-text" layout="column">
<p>{{task.name}}</p>
<p>Priority: {{task.priority}}</p>
<span class="weak">Added {{task.addedOn | date: 'medium'}}</span>
</div>
<md-checkbox class="md-secondary" ng-model="task.completed"></md-checkbox>
<md-divider ng-if="!$last"></md-divider>
</md-list-item>
</md-list>
JS:
var app = angular.module('todoApp', ['ngMaterial']);
function menuController ($scope, $mdDialog) {
var originatorEv;
this.openMenu = function($mdOpenMenu, ev) {
originatorEv = ev;
$mdOpenMenu(ev);
};
};
app.controller('todoController', function($scope, $mdDialog, $mdToast, $filter) {
$scope.sortByNewest = '-addedOn';
//$scope.sortByPriority = ' ';
$scope.taskList = [
{ name: 'Task 1', priority: 'Low', completed: false, addedOn: 1488722128000 },
{ name: 'Task 2', priority: 'HIGH', completed: false, addedOn: 1488722128000 },
];
$scope.addTask = function() {
if (angular.isUndefined($scope.taskName) || $scope.taskName.length === 0) {
var alert = $mdDialog.alert()
.parent(angular.element(document.querySelector('#popupContainer')))
.clickOutsideToClose(true)
.title('Error')
.textContent('You must enter a task name and select a priority level')
.ok('Close');
$mdDialog.show( alert )
.finally(function() {
alert = undefined;
});
}
else {
$scope.taskList.push({name: $scope.taskName, priority: $scope.task.priority, addedOn: Date.now()});
$scope.taskName = "";
$scope.task.priority = "";
var pinTo = $scope.getToastPosition();
$mdToast.show (
$mdToast.simple()
.textContent('Task Added')
.position(pinTo)
.hideDelay(3000)
)
}
};
$scope.selectAll = function() {
angular.forEach($scope.taskList, function(task) {
task.completed = true;
});
};
$scope.selectNone = function() {
angular.forEach($scope.taskList, function(task) {
task.completed = false;
});
};
$scope.delete = function(ev) {
var completedTasks = $filter('filter')($scope.taskList, { completed: true}, true);
if (completedTasks.length > 0) {
console.log('show dialog box to confirm');
var confirm = $mdDialog.confirm()
.title ('Are you sure you want to delete the selected tasks?')
.textContent ('Deleted tasks can\'t be recovered.')
.targetEvent (ev)
.ok ('Confirm')
.cancel ('Cancel')
clickOutsideToClose: false;
$mdDialog.show(confirm).then(function() {
if (completedTasks.length > 1) {
var pinTo = $scope.getToastPosition();
$mdToast.show (
$mdToast.simple()
.textContent('Tasks Deleted')
.position(pinTo)
.hideDelay(3000)
)
}
else {
var pinTo = $scope.getToastPosition();
$mdToast.show (
$mdToast.simple()
.textContent('Task Deleted')
.position(pinTo)
.hideDelay(3000)
)
}
$scope.status = 'Tasks Deleted';
var i = $scope.taskList.length;
while (i--) {
var task = $scope.taskList[i];
if(task.completed) {
$scope.taskList.splice(i, 1);
}
}
},
function() {
$scope.status = 'Deletion Cancelled';
});
}
else {
$mdDialog.show(
$mdDialog.alert()
.parent(angular.element(document.querySelector('#popupContainer')))
.clickOutsideToClose(true)
.title('Error')
.textContent('You must select at least one task to delete.')
.ok('Close')
.targetEvent(ev)
);
}
};
function DialogController($scope, $mdDialog) {
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.answer = function(answer) {
$mdDialog.hide(answer);
};
};
var last = {
bottom: false,
top: true,
left: false,
right: true
};
$scope.toastPosition = angular.extend({},last);
$scope.getToastPosition = function() {
sanitizePosition();
return Object.keys($scope.toastPosition)
.filter(function(pos) { return $scope.toastPosition[pos]; })
.join(' ');
};
function sanitizePosition() {
var current = $scope.toastPosition;
if ( current.bottom && last.top ) current.top = false;
if ( current.top && last.bottom ) current.bottom = false;
if ( current.right && last.left ) current.left = false;
if ( current.left && last.right ) current.right = false;
last = angular.extend({},current);
};
});
app.controller('toastController', function($scope, $mdToast) {
$scope.closeToast = function() {
$mdToast.hide();
}
});
You need to use ng-model="search.name" and ng-model="search.priority"
. then it will read all search criteria from search
object.( filter:search
)
Check out updated Codepen
Please update your view as shown below: Search by Task Name model as ng-model="search.name"
instead of ng-model="search"
Sort By model as ng-model="search.priority"
instead of ng-model="sortBy"
<div layout="row">
<md-input-container class="md-block" flex="70">
<input type="text" ng-model="search.name" name="search" placeholder="Search by Task Name"></input>
</md-input-container>
<md-input-container flex="30">
<md-select name="priority" ng-model="search.priority" placeholder="Sort By">
<md-option value="Low">Newest First</md-option>
<md-option value="HIGH">High Priority First</md-option>
</md-select>
</md-input-container>
</div>
orderBy
needs the property names of the objects it is supposed to sort. So the option
s inside your select
should define these property names like this:
<md-select name="sortBy" placeholder="Sort By" ng-model="sortBy">
<md-option value="addedOn">Newest First</md-option>
<md-option value="priority">High Priority First</md-option>
</md-select>
If orderBy
encounters a string inside these properties it will sort the array alphabetically. So this already conveniently works for you since H igh comes before L ow.
From the Angular Documentation:
The default, built-in comparator should be sufficient for most usecases. In short, it compares numbers numerically, strings alphabetically (and case-insensitively), for objects falls back to using their index in the original collection, and sorts values of different types by type.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.