Songhay Studio: Day Path Index JSON ('-' * 35) ng filter and sort (ascending/descending based on view model) with grouping
A Pen by Bryan Wilhite on CodePen.
<body data-ng-app="rxApp"> | |
<div data-ng-controller="indexController"> | |
<select | |
data-ng-change='vm.setGroups()' | |
data-ng-model="vm.indexGroupingSelected" | |
data-ng-options="i as i.label for i in options"> | |
</select> | |
<button data-ng-click="vm.loadIndex()">Load Index</button> | |
<span class="glyphicon glyphicon-refresh" aria-hidden="true" data-ng-if="vm.isLoadingIndex"></span> | |
<div data-ng-repeat="i in groups | orderBy: 'groupName' : vm.indexGroupingSelected.sortDescending "> | |
<h2 data-ng-bind-html="i.groupName"></h2> | |
<ul> | |
<li data-ng-repeat="j in i.group | orderBy: 'SortOrdinal' : true "> | |
<code>{{ j.SortOrdinal }}</code> <a href="#/{{ j.ItemName }}">{{ j.DisplayText }}</a> | |
</li> | |
</ul> | |
</div> | |
</div> | |
</body> |
/*jslint this, white, browser */ | |
/*global _, angular */ | |
(function() { | |
"use strict"; | |
var rxApp = angular.module('rxApp', ['ngSanitize', 'rxApp.services', 'rxApp.controllers']); | |
/* Services */ | |
var dataService = { | |
getData: function($http) { | |
if (!$http) { | |
return; | |
} | |
var uri = 'http://wordwalkingstick.com/api/SonghayBlog/'; | |
return $http.get(uri).then( | |
function(result) { | |
var getItemCategoryProperties = function(i) { | |
var o = angular.fromJson('{' + i.ItemCategory + '}'); | |
var topics = _(Object.keys(o)).filter(function(v) { | |
return v ? v.indexOf('topic-') === 0 : false; | |
}); | |
o.topic = _(topics).isEmpty() ? | |
'<!--zzz-->[no topic]' : | |
'<!--' + _(topics).first() + '-->' + o[_(topics).first()]; | |
o.topics = _(topics).map(function(v) { | |
return { | |
key: v, | |
value: o[v] | |
}; | |
}); | |
return o; | |
}; | |
var getSortOrdinal = function(i) { | |
var pad = function pad(num, size) { | |
var s = num + ""; | |
while (s.length < size) { | |
s = "0" + s; | |
} | |
return s; | |
}; | |
return i.year + '-' + | |
pad(i.month, 2) + '-' + | |
pad(i.day, 2) + '-' + | |
i.ItemName; | |
}; | |
_(result.data).each(function(i) { | |
_(i).extend(getItemCategoryProperties(i)); | |
i.SortOrdinal = getSortOrdinal(i); | |
}); | |
return result.data; | |
}); | |
} | |
}; | |
var services = angular.module('rxApp.services', []); | |
services.factory('dataService', ['$http', | |
function() { | |
return dataService; | |
} | |
]); | |
/* Controllers */ | |
var doIndexController = function($scope, $http, dataService) { | |
$scope.options = [{ | |
label: 'by Date', | |
sortDescending: true, | |
value: 'dateGroup' | |
}, { | |
label: 'by Topic', | |
sortDescending: false, | |
value: 'topic' | |
}]; | |
$scope.vm = { | |
data: null, | |
indexGroupingSelected: $scope.options[0], | |
isLoadingIndex: false, | |
loadIndex: function() { | |
var that = this; | |
this.isLoadingIndex = true; | |
dataService.getData($http).then(function(data) { | |
$scope.vm.data = data; | |
$scope.vm.setGroups(); | |
that.isLoadingIndex = false; | |
}); | |
}, | |
setGroups: function() { | |
$scope.groups = _($scope.vm.data) | |
.chain() | |
.groupBy(this.indexGroupingSelected.value) | |
.pairs() | |
.map(function(i) { | |
return { | |
groupName: i[0], | |
group: i[1] | |
}; | |
}) | |
.value(); | |
} | |
}; | |
}; | |
var controllers = angular.module('rxApp.controllers', []); | |
controllers | |
.controller('indexController', ['$scope', '$http', 'dataService', doIndexController]); | |
}()); |
Songhay Studio: Day Path Index JSON ('-' * 35) ng filter and sort (ascending/descending based on view model) with grouping
A Pen by Bryan Wilhite on CodePen.
@keyframes infinite-spinning { | |
from { | |
transform: rotate(0deg); | |
} | |
to { | |
transform: rotate(360deg); | |
} | |
} | |
@-webkit-keyframes infinite-spinning { | |
from { | |
-webkit-transform: rotate(0deg); | |
} | |
to { | |
-webkit-transform: rotate(360deg); | |
} | |
} | |
.glyphicon-refresh | |
{ | |
animation-name: infinite-spinning; | |
animation-delay: 0; | |
animation-direction: normal; | |
animation-duration: .5s; | |
animation-fill-mode: forwards; | |
animation-iteration-count: infinite; | |
animation-timing-function: linear; | |
-webkit-animation-name: infinite-spinning; | |
-webkit-animation-delay: 0; | |
-webkit-animation-direction: normal; | |
-webkit-animation-duration: .5s; | |
-webkit-animation-fill-mode: forwards; | |
-webkit-animation-iteration-count: infinite; | |
-webkit-animation-timing-function: linear; | |
font-size: 2em; | |
margin: 1em; | |
} |