Skip to content

Commit da4fb18

Browse files
committed
Merge pull request #13 from JohnThomson/feature/datagrid
DataGrid is working now except for sorting.
2 parents 4daf4aa + 2f3582e commit da4fb18

File tree

11 files changed

+182
-13
lines changed

11 files changed

+182
-13
lines changed

src/BloomLibrary_AngularApp/app/index.html

+8
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
<!-- for Bootstrap 2 only -->
1818

1919
<link rel="stylesheet" href="modules/browse/browse.css">
20+
<link rel="stylesheet" href="modules/datagrid/datagrid.css">
2021
<link rel="stylesheet" href="modules/detail/detail.css">
2122
<link rel="stylesheet" href="modules/browse/retrofitBootstrap3ForAngularJSPagination.css">
2223

2324
<link rel="stylesheet" href="components/fancybox/source/jquery.fancybox.css">
25+
<link rel="stylesheet" type="text/css" href="components/ng-grid/ng-grid.css" />
2426

2527
<script src="components/jquery/jquery.js"></script>
2628
<script src="components/jquery-ui/ui/jquery-ui.js"></script>
@@ -78,6 +80,7 @@
7880
<script src="components/angular-ui-router/release/angular-ui-router.js"></script>
7981

8082
<script src="components/fancybox/source/jquery.fancybox.js"></script>
83+
<script type="text/javascript" src="components/ng-grid/ng-grid-2.0.7.debug.js"></script>
8184

8285
<!-- app module -->
8386
<script src="modules/app/app.js"></script>
@@ -94,6 +97,11 @@
9497
<script src="modules/login/login-module.js"></script>
9598
<script src="modules/login/login-controller.js"></script>
9699

100+
<!-- datagrid module -->
101+
<script src="modules/datagrid/datagrid-module.js"></script>
102+
<script src="modules/datagrid/datagrid-controller.js"></script>
103+
104+
97105
<!-- signup module -->
98106
<script src="modules/signup/app.js"></script>
99107

src/BloomLibrary_AngularApp/app/modules/app/app.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
var BloomLibraryApp = angular.module('BloomLibraryApp',
4-
['BloomLibraryApp.browse', 'BloomLibraryApp.detail', "BloomLibraryApp.login", "BloomLibraryApp.signup", "BloomLibraryApp.services",
4+
['BloomLibraryApp.browse', 'BloomLibraryApp.detail', "BloomLibraryApp.login", "BloomLibraryApp.signup", "BloomLibraryApp.services", "BloomLibraryApp.datagrid",
55
"ui.bootstrap", 'ui.router', 'palaso.ui.listview', 'restangular' ])
66

77
.config(['$urlRouterProvider', '$stateProvider',

src/BloomLibrary_AngularApp/app/modules/browse/browse.tpl.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ <h3 class="firstRowAboutBook">{{book.volumeInfo.title}}
3232
<div class="unfloat"></div>
3333
</div>
3434
</div>
35-
36-
35+
<!-- temporary affordance for trying out the new datagrid. Not the final design -->
36+
<form action="#datagrid"><input type="submit" value="Grid view"></form>
3737
</div>
3838
</div>

src/BloomLibrary_AngularApp/app/modules/common/services.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ angular.module('BloomLibraryApp.services', ['restangular'])
1313
restangularConfigurer.setBaseUrl('https://api.parse.com/1');// 1/indicates rev 1 of parse.com API
1414
restangularConfigurer.setDefaultHeaders(headers);
1515
};
16-
16+
1717
var factory = {
1818

1919
userName: function () { return userNameX; },
@@ -57,10 +57,10 @@ angular.module('BloomLibraryApp.services', ['restangular'])
5757
}
5858

5959
};
60-
60+
6161
return factory;
6262
}])
63-
63+
6464
.service('bookService', ['Restangular', 'authService', '$q', '$rootScope', function(restangular, authService, $q, $rootScope) {
6565
// Initialize Parse.com javascript query module for our project.
6666
// Note: we would prefer to do this query using the REST API, but it does not currently support substring matching.
@@ -113,7 +113,7 @@ angular.module('BloomLibraryApp.services', ['restangular'])
113113
// We will return the result as an angularjs promise. Typically the caller will
114114
// do something like getFilteredBookRange(...).then(function(books) {...do somethign with books}
115115
// By that time books will be an array of json-encoded book objects from parse.com.
116-
this.getFilteredBookRange = function (first, count, searchString) {
116+
this.getFilteredBookRange = function (first, count, searchString, sortBy, ascending) {
117117
var defer = $q.defer(); // used to implement angularjs-style promise
118118
// This is a parse.com query, using the parse-1.2.13.min.js script included by index.html
119119
var query = new Parse.Query('books');
@@ -122,6 +122,14 @@ angular.module('BloomLibraryApp.services', ['restangular'])
122122
query.limit(count);
123123
if (searchString)
124124
query.contains('volumeInfo.title', searchString);
125+
// Review: have not yet verified that sorting works at all. At best it probably works only for top-level complete fields.
126+
// It does not work for e.g. volumeInfo.title.
127+
if (sortBy) {
128+
if (ascending)
129+
query.ascending(sortBy);
130+
else
131+
query.descending(sortBy);
132+
}
125133
// query.find returns a parse.com promise, but it is not quite the same api as
126134
// as an angularjs promise. Instead, translate its find and error funtions using the
127135
// angularjs promise.
@@ -152,16 +160,16 @@ angular.module('BloomLibraryApp.services', ['restangular'])
152160
}])
153161
.service('userService', ['Restangular', 'authService', function(restangular, authService) {
154162
var checkforerror = function(callback) {
155-
156-
163+
164+
157165
};
158166

159167
this.register = function(user, callback) {
160168
if (!user.mandatoryfield) {
161169
return restangular.withConfig(authService.config()).all('users').post(user).then(callback,callback);
162170
}
163171
};
164-
172+
165173
this.readByUserName = function(username, callback) {
166174
return restangular.withConfig(authService.config()).all('users').getList({"where": '{"username": "' + username + '"}'}).then(callback,callback);
167175
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
'use strict';
2+
3+
// Controller for the data grid view (url #/datagrid)
4+
// Todo: Trello card says Columns of interest: Title, Date, Copyright Holder, License, Modified Date, Workflow Status: {Draft, Edited, Private Published, Web Published}
5+
// Most of these are not currently available (or at least not in the sample data).
6+
// The setting scope.visibleData needs to be modified to make the actual fields we want,
7+
// and the columnDefs spec should be changed to match, and eventually we need to implement a sortBy for each column.
8+
angular.module('BloomLibraryApp.datagrid')
9+
.controller('DataGridCtrl', ['$scope', '$dialog', '$timeout', 'bookService', '$state', '$stateParams', '$location',
10+
function ($scope, $dialog, $timeout, bookService, $state, $stateParams, $location) {
11+
12+
$scope.filterOptions = {
13+
filterText: "", // gets updated by user action in ngGrid
14+
useExternalFilter: true
15+
};
16+
$scope.totalServerItems = 0;
17+
$scope.pagingOptions = {
18+
pageSizes: [20, 50, 100],
19+
pageSize: 20, // Gets updated by user action in ngGrid
20+
currentPage: 1 // Gets updated by user action in ngGrid
21+
};
22+
$scope.sortInfo = {
23+
fields: [], directions: [], columns: []
24+
};
25+
$scope.getBookRange = function (count, currentPage, searchText) {
26+
var first = (currentPage - 1) * count;
27+
var sortField = $scope.sortInfo.fields[0];
28+
var sortBy = null;
29+
// Todo: setting sortBy to a complex field like this does not work...no sorting happens.
30+
// It appears we will need to put a redundant top-level data field in the record for
31+
// anything we want to sort by. This is especially annoying in that it may not actually
32+
// be useful to sort by all the fields...but ng-grid allows the user to do so.
33+
// Possibly we could disallow some fields with a message and switch to some other sort.
34+
// Another reason a redundant field is probably necessary is that parse.com's built-in sorting
35+
// is case-sensitive, and their only suggestion for overcoming this is a redundant
36+
// all-lower-case field. Similarly any other sort-key field must somehow be in a form
37+
// where a plain binary sort will give the right results.
38+
if (sortField == 'title')
39+
sortBy = 'volumeInfo.title';
40+
bookService.getFilteredBookRange(first, count, searchText, sortBy).then(function(result) {
41+
$scope.visibleBooks = result;
42+
$scope.visibleData = $scope.visibleBooks.map(function(item) {
43+
return {
44+
title: item.volumeInfo.title,
45+
published: item.volumeInfo.publishedDate,
46+
publisher: item.volumeInfo.publisher,
47+
pages: item.volumeInfo.pageCount,
48+
authors: (item.volumeInfo.authors ? item.volumeInfo.authors.join(", ") : "")
49+
};
50+
});
51+
})
52+
};
53+
$scope.getBookCount = function (searchText) {
54+
bookService.getFilteredBooksCount(searchText).then(function (count) {
55+
$scope.bookCount = count;
56+
});
57+
};
58+
$scope.getBookCount($scope.filterOptions.filterText); // initialize count
59+
$scope.getBookRange($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText); // init
60+
$scope.$watch('pagingOptions', function (newVal, oldVal) {
61+
if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
62+
$scope.getBookRange($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
63+
}
64+
}, true);
65+
$scope.$watch('filterOptions', function (newVal, oldVal) {
66+
if (newVal !== oldVal) {
67+
$scope.getBookCount($scope.filterOptions.filterText);
68+
$scope.getBookRange($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
69+
}
70+
}, true);
71+
$scope.$watch('sortInfo', function (newVal, oldVal) {
72+
if (newVal !== oldVal) {
73+
$scope.getBookRange($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
74+
}
75+
}, true);
76+
$scope.gridOptions = { data: 'visibleData',
77+
enableColumnResize: true,
78+
//showColumnMenu:true,
79+
//showFilter:true,
80+
enablePaging: true,
81+
showFooter: true,
82+
totalServerItems: 'bookCount',
83+
pagingOptions: $scope.pagingOptions,
84+
useExternalSorting: true,
85+
showColumnMenu: true,
86+
filterOptions: $scope.filterOptions,
87+
sortInfo: $scope.sortInfo,
88+
columnDefs: [{field:'title', displayName:'Title', width:'***'},
89+
{field:'published', displayName:'Date', width: 80},
90+
{field:'publisher', displayName:'Copyright', width: '**'},
91+
{field:'pages', displayName:'Pages', width: 50},
92+
{field: 'authors', displayName: 'Authors', width:'***'}
93+
]
94+
};
95+
// $scope.searchText = $stateParams["search"];
96+
// $scope.searchTextRaw = $scope.searchText;
97+
98+
//
99+
// // browse.tpl.html listview div configures this to be called as pageItemsFunction when user chooses a page.
100+
// // Todo: should get Filtered book range.
101+
102+
//
103+
// $scope.foo = function(paramOne, paramTwo) {
104+
// return paramOne + paramTwo;
105+
// }
106+
//
107+
//
108+
// $scope.updatePageControl = function () {
109+
// $scope.currentPage = 1;
110+
// $scope.setPage = function (pageNo) {
111+
// $scope.currentPage = pageNo;
112+
// };
113+
//
114+
// }
115+
//
116+
// $scope.SearchNow = function () {
117+
// // Todo: this needs to run a query on the real database and update bookCount
118+
// // and do something to make the listview invoke getBookRange (even if the bookCount
119+
// // does not change).
120+
// $scope.searchText = $scope.searchTextRaw;
121+
// $state.go('.', {search: $scope.searchText});
122+
// }
123+
}]);
124+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'use strict';
2+
3+
// Model declaration for the data grid view (url #/datagrid)
4+
angular.module('BloomLibraryApp.datagrid', ['ui.router', 'restangular', 'ngGrid'])//, 'BloomLibraryApp.detail'])
5+
.config(['$stateProvider', function config($stateProvider) {
6+
7+
$stateProvider.state('datagrid', {
8+
url: "/datagrid",
9+
templateUrl: 'modules/datagrid/datagrid.tpl.html',
10+
controller: 'DataGridCtrl'
11+
});
12+
}]);
13+
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/*Will be compiled down to a single stylesheet with your sass files*/
2+
.gridStyle {
3+
border: 1px solid rgb(212,212,212);
4+
width: 100%;
5+
height: 400px
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div>
2+
<h1>Books</h1>
3+
<div class="container">
4+
<input type="text" ng-model="filterOptions.filterText" class="search-query" placeholder="Filter">
5+
<div class="gridStyle" ng-grid="gridOptions">
6+
</div>
7+
</div>
8+
</div>

src/BloomLibrary_AngularApp/app/modules/detail/detail.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
margin-top: -6px;
2525
line-height: 1;
2626
}
27-
.col2
27+
.detailCol2
2828
{
2929
margin-top: 1px;
3030
margin-left: 143px;

src/BloomLibrary_AngularApp/app/modules/detail/detail.tpl.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
</div>
77
<div class="modal-body">
88
<img ng-src="{{book.volumeInfo.imageLinks.thumbnail}}" />
9-
<div class="col2">
9+
<div class="detailCol2">
1010
<div class="title">{{book.volumeInfo.title}}</div>
1111
<div class="author">{{book.volumeInfo.authors }}</div>
1212
<div class="summary">{{book.volumeInfo.description}}</div>

src/BloomLibrary_AngularApp/bower.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"angular-bootstrap": "~0.5.0",
1313
"angular-ui-router": "~0.2.0",
1414
"bootstrap-modal": "~2.1.0",
15-
"fancybox": "~2.1.5"
15+
"fancybox": "~2.1.5",
16+
"ng-grid": "~2.0.7"
1617
},
1718
"devDependencies": {
1819
"angular-mocks": "~1.0.5",

0 commit comments

Comments
 (0)