Skip to content

Commit 1a69bba

Browse files
committed
Merge 66cb896 into 9f39bd8
2 parents 9f39bd8 + 66cb896 commit 1a69bba

File tree

3 files changed

+151
-85
lines changed

3 files changed

+151
-85
lines changed

components/renderers/controls/array/array-renderer.ts

Lines changed: 77 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,80 +2,105 @@
22

33
class ArrayRenderer implements JSONForms.IRenderer {
44

5+
private maxSize = 99;
6+
priority = 2;
7+
58
constructor(private pathResolver: JSONForms.IPathResolver, private scope: ng.IScope) {
69

710
}
811

9-
private defaultGridOptions(services: JSONForms.Services, schema: SchemaElement): uiGrid.IGridOptions {
12+
private static isExternalFilterAvailable(dataProvider: JSONForms.IDataProvider,
13+
options: uiGrid.IGridOptions): boolean {
14+
return dataProvider.filter !== undefined &&
15+
options.hasOwnProperty('useExternalFiltering');
16+
}
17+
18+
private static isExternalPagingAvailable(dataProvider: JSONForms.IDataProvider,
19+
options: uiGrid.IGridOptions) {
20+
return dataProvider.fetchPage !== undefined &&
21+
options.hasOwnProperty('useExternalPagination');
22+
}
23+
24+
private defaultGridOptions(existingOptions: uiGrid.IGridOptions,
25+
services: JSONForms.Services, schema: SchemaElement): uiGrid.IGridOptions {
1026

11-
var paginationEnabled = false;
12-
var defaultGridOptions:uiGrid.IGridOptions = {};
13-
defaultGridOptions.enableColumnResizing = true;
14-
defaultGridOptions.enableHorizontalScrollbar = 0;
15-
defaultGridOptions.enableVerticalScrollbar = 0;
1627
var dataProvider = services.get<JSONForms.IDataProvider>(JSONForms.ServiceId.DataProvider);
1728
var validationService = services.get<JSONForms.IValidationService>(JSONForms.ServiceId.Validation);
1829

19-
if (dataProvider instanceof JSONForms.DefaultInternalDataProvider) {
20-
defaultGridOptions.totalItems = dataProvider.getTotalItems();
21-
} else {
30+
let externalPaginationEnabled = ArrayRenderer.isExternalPagingAvailable(dataProvider, existingOptions);
31+
let externalFilteringEnabled = ArrayRenderer.isExternalFilterAvailable(dataProvider, existingOptions);
2232

23-
paginationEnabled = dataProvider.fetchPage !== undefined;
24-
25-
if (paginationEnabled) {
26-
// disable internal and enable external pagination
27-
defaultGridOptions.enablePagination = false;
28-
defaultGridOptions.useExternalPagination = true;
29-
defaultGridOptions.paginationPageSizes = [5, 10, 20];
30-
defaultGridOptions.paginationPageSize = 5;
31-
defaultGridOptions.paginationCurrentPage = 1;
32-
defaultGridOptions.enablePaginationControls = true;
33-
}
33+
var defaultGridOptions:uiGrid.IGridOptions = {};
34+
defaultGridOptions.totalItems = dataProvider.getTotalItems();
35+
defaultGridOptions.enableColumnResizing = true;
36+
defaultGridOptions.enableHorizontalScrollbar = 0;
37+
defaultGridOptions.enableVerticalScrollbar = 0;
38+
defaultGridOptions.paginationPageSizes = [5, 10, 20];
39+
defaultGridOptions.paginationPageSize = 5;
40+
defaultGridOptions.paginationCurrentPage = 1;
41+
defaultGridOptions.enablePaginationControls = true;
3442

35-
// TODO: implement filtering and pass grid options accordingly
36-
//if (filteringEnabled) {
37-
// defaultGridOptions.enableFiltering = false;
38-
// defaultGridOptions.useExternalPagination = true;
39-
//}
43+
if (externalPaginationEnabled) {
44+
defaultGridOptions.useExternalPagination = true;
4045
}
4146

4247
defaultGridOptions.onRegisterApi = (gridApi) => {
43-
if (paginationEnabled) {
48+
if (externalPaginationEnabled) {
4449
gridApi.pagination.on.paginationChanged(this.scope, (newPage, pageSize) => {
4550
defaultGridOptions.paginationCurrentPage = newPage;
4651
defaultGridOptions.paginationPageSize = pageSize;
4752
dataProvider.setPageSize(pageSize);
48-
dataProvider.fetchPage(newPage, pageSize).then(newData => {
49-
defaultGridOptions.data = newData;
53+
dataProvider.fetchPage(newPage).then(newData => {
54+
existingOptions.data = newData;
5055
});
5156
});
5257
}
53-
gridApi.edit.on.afterCellEdit(this.scope, (rowEntity, colDef: uiGrid.IColumnDef, newValue, oldValue) => {
54-
var value = newValue;
55-
56-
// TODO: newValue is a string?
57-
if (colDef.type) {
58-
if (colDef.type == "number" || colDef.type == "integer") {
59-
value = Number(newValue);
60-
} else if (colDef.type == "boolean") {
61-
value = Boolean(newValue);
62-
}
63-
}
64-
65-
rowEntity[colDef.field] = value;
58+
if (externalFilteringEnabled) {
59+
gridApi.core.on.filterChanged(this.scope, () => {
60+
var columns = gridApi.grid.columns;
61+
var terms = columns.reduce((acc, column) => {
62+
var value: any = column.filters[0].term;
63+
acc[column.field] = ArrayRenderer.convertColumnValue(column.colDef, value);
64+
return acc;
65+
}, {});
66+
dataProvider.filter(terms).then(newData => {
67+
existingOptions.data = newData;
68+
})
69+
});
70+
}
71+
gridApi.edit.on.afterCellEdit(this.scope, (rowEntity, colDef:uiGrid.IColumnDef, newValue, oldValue) => {
72+
rowEntity[colDef.field] = ArrayRenderer.convertColumnValue(colDef, newValue);
6673
validationService.validate(rowEntity, schema['items']);
6774
// TODO: use constant
6875
gridApi.core.notifyDataChange("column");
6976
this.scope.$apply();
7077
});
71-
7278
};
7379

74-
return defaultGridOptions;
80+
return this.mergeOptions(existingOptions, defaultGridOptions);
7581
}
7682

77-
private maxSize = 99;
78-
priority = 2;
83+
private static convertColumnValue(colDef: uiGrid.IColumnDef, value: string): any {
84+
if (colDef.type) {
85+
if (colDef.type == "number" || colDef.type == "integer") {
86+
return Number(value);
87+
} else if (colDef.type == "boolean") {
88+
return Boolean(value);
89+
}
90+
}
91+
92+
return value;
93+
}
94+
95+
private mergeOptions(optionsA: any, optionsB: any): any {
96+
return Object.keys(optionsB).reduce((mergedOpts, optionName) => {
97+
if (mergedOpts.hasOwnProperty(optionName)) {
98+
return mergedOpts
99+
}
100+
mergedOpts[optionName] = optionsB[optionName];
101+
return mergedOpts;
102+
}, optionsA);
103+
}
79104

80105
isApplicable(element: IUISchemaElement, subSchema: SchemaElement, schemaPath: string):boolean {
81106
return element.type == 'Control' && subSchema !== undefined && subSchema.type == 'array';
@@ -102,7 +127,6 @@ class ArrayRenderer implements JSONForms.IRenderer {
102127
};
103128
}
104129

105-
106130
private generateColumnDefs(schema: SchemaElement, schemaPath: string): any {
107131
var columnsDefs = [];
108132
var subSchema = this.pathResolver.resolveSchema(schema, schemaPath);
@@ -125,10 +149,10 @@ class ArrayRenderer implements JSONForms.IRenderer {
125149
return columnsDefs;
126150
}
127151

128-
private createColumnDefs(element: IArrayControlObject, schema: SchemaElement, services: JSONForms.Services): uiGrid.IColumnDef[] {
152+
private createColumnDefs(columns: IColumnControlObject[], schema: SchemaElement, services: JSONForms.Services): uiGrid.IColumnDef[] {
129153
var validationService:JSONForms.IValidationService = services.get<JSONForms.IValidationService>(JSONForms.ServiceId.Validation);
130154

131-
return element.columns.map((col) => {
155+
return columns.map((col) => {
132156
var href = col['href'];
133157
if (href) {
134158
var hrefScope = href.scope;
@@ -150,7 +174,7 @@ class ArrayRenderer implements JSONForms.IRenderer {
150174
</div>`;
151175
}
152176

153-
return {
177+
return {
154178
cellTemplate: cellTemplate,
155179
field: field,
156180
displayName: col.label,
@@ -178,41 +202,16 @@ class ArrayRenderer implements JSONForms.IRenderer {
178202

179203
private createGridOptions(element: IArrayControlObject, services: JSONForms.Services, schema: SchemaElement, schemaPath: string) {
180204

181-
var columnsDefs: uiGrid.IColumnDef[];
182205
var subSchema = this.pathResolver.resolveSchema(schema, schemaPath);
183206

184-
if (element.columns) {
185-
columnsDefs = this.createColumnDefs(element, subSchema, services);
186-
} else {
187-
columnsDefs = this.generateColumnDefs(subSchema, schemaPath);
188-
}
189-
190-
var defaultGridOptions: uiGrid.IGridOptions = this.defaultGridOptions(services, schema);
191-
var gridOptions: uiGrid.IGridOptions = element.options || {};
192-
for (var option in defaultGridOptions) {
193-
if (defaultGridOptions.hasOwnProperty(option)) {
194-
gridOptions[option] = defaultGridOptions[option];
195-
}
196-
}
207+
var columnsDefs: uiGrid.IColumnDef[] = element.columns ?
208+
this.createColumnDefs(element.columns, subSchema, services) :
209+
this.generateColumnDefs(subSchema, schemaPath);
197210

211+
var gridOptions: uiGrid.IGridOptions = this.defaultGridOptions(element.options || {}, services, schema);
198212
gridOptions.columnDefs = columnsDefs;
199213
return gridOptions;
200214
}
201-
202-
findSearchTerms(grid) {
203-
var searchTerms = [];
204-
for (var i = 0; i < grid.columns.length; i++) {
205-
var searchTerm = grid.columns[i].filters[0].term;
206-
if (searchTerm !== undefined && searchTerm !== null) {
207-
searchTerms.push({
208-
column: grid.columns[i].getName,
209-
term: searchTerm
210-
});
211-
}
212-
}
213-
214-
return searchTerms;
215-
}
216215
}
217216

218217
angular.module('jsonforms.renderers.controls.array').run(['RenderService', 'PathResolver', '$rootScope', function(RenderService, PathResolver, $rootScope) {

components/utils/dataproviders.d.ts

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,65 @@
22

33
declare module JSONForms{
44
export interface IDataProvider extends IService {
5+
6+
/**
7+
* Initially fetches the data instance
8+
*
9+
* @return a promise returning the initially fetched data
10+
*/
511
fetchData(): ng.IPromise<any>
6-
fetchPage(page:number, size:number): ng.IPromise<any>
7-
setPageSize(size:number)
12+
13+
14+
/**
15+
* Returns the instance.
16+
*
17+
* @return {any} the instance
18+
*/
819
getData(): any
9-
getPageSize(): number
10-
getPage(): number
20+
21+
/**
22+
* Fetches the given page of data.
23+
*
24+
* @param page the page to be fetched
25+
* @return a promise returning the fetched data
26+
*/
27+
fetchPage?(page:number): ng.IPromise<any>
28+
29+
/**
30+
* Returns the currently used page size by the data provider.
31+
*
32+
* @return {number} the current page size
33+
*/
34+
getPageSize?(): number
35+
36+
/**
37+
* Set the page size to be used by the data provider.
38+
*
39+
* @param size the page size
40+
*/
41+
setPageSize?(size:number)
42+
43+
/**
44+
* Returns the current page the data provider currently has in scope.
45+
*
46+
* @return {number} the current page
47+
*/
48+
getPage?(): number
49+
50+
/**
51+
* Returns the overall number of items available.
52+
* Since not all data provider are able to determine an overall number of items,
53+
* this method is optional.
54+
*
55+
* @return {number} the overall number of items
56+
*/
1157
getTotalItems?(): number
58+
59+
/**
60+
* Fetches the data filtered accordingly to the given terms.
61+
*
62+
* @param terms search terms
63+
*/
64+
filter?(terms: any): ng.IPromise<any>
1265
}
1366
}

examples/js/PlaceholderController.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,13 @@ angular.module('makeithappen').controller('PlaceholderController', ['$scope', '$
6464
"url": "/placeholder-users"
6565
}
6666
}
67-
]
67+
],
68+
"options": {
69+
enableFiltering: true,
70+
// will cause IDataProvider#filter to be called
71+
useExternalFiltering: true,
72+
pageSizes: [5,10]
73+
}
6874
};
6975

7076
//
@@ -202,7 +208,7 @@ angular.module('makeithappen').controller('PlaceholderController', ['$scope', '$
202208
// Resources --
203209
//
204210

205-
var Posts = $resource('http://localhost:3000/posts/:id');
211+
var Posts = $resource('http://localhost:3000/posts/:id?');
206212
var Users = $resource('http://localhost:3000/users/:id');
207213
var Comments = $resource('http://localhost:3000/comments/:id');
208214

@@ -235,7 +241,7 @@ angular.module('makeithappen').controller('PlaceholderController', ['$scope', '$
235241
var start = (page - 1) * this.pageSize;
236242
var end = start + this.pageSize;
237243
var that = this;
238-
return Comments.query({_start: start, _end: end}, function (response) {
244+
return toQuery.query({_start: start, _end: end}, function (response) {
239245
that.data = response;
240246
}).$promise;
241247
},
@@ -254,6 +260,14 @@ angular.module('makeithappen').controller('PlaceholderController', ['$scope', '$
254260
console.log("error occurred: " + JSON.stringify(error));
255261
}).$promise;
256262
}
263+
},
264+
filter: function(terms) {
265+
var that = this;
266+
return toQuery.query(terms, function(response) {
267+
that.data = response;
268+
}, function(error) {
269+
console.log("error occurred: " + JSON.stringify(error));
270+
}).$promise;
257271
}
258272
};
259273
};

0 commit comments

Comments
 (0)