Skip to content

Commit

Permalink
Merge 238b32a into 9f39bd8
Browse files Browse the repository at this point in the history
  • Loading branch information
edgarmueller committed Nov 16, 2015
2 parents 9f39bd8 + 238b32a commit b10b842
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 93 deletions.
168 changes: 85 additions & 83 deletions components/renderers/controls/array/array-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,80 +2,108 @@

class ArrayRenderer implements JSONForms.IRenderer {

constructor(private pathResolver: JSONForms.IPathResolver, private scope: ng.IScope) {
private maxSize = 99;
priority = 2;

constructor(private pathResolver: JSONForms.IPathResolver) {

}

private defaultGridOptions(services: JSONForms.Services, schema: SchemaElement): uiGrid.IGridOptions {
private static isExternalFilterAvailable(dataProvider: JSONForms.IDataProvider,
options: uiGrid.IGridOptions): boolean {
return dataProvider.filter !== undefined &&
options.hasOwnProperty('useExternalFiltering');
}

private static isExternalPagingAvailable(dataProvider: JSONForms.IDataProvider,
options: uiGrid.IGridOptions) {
return dataProvider.fetchPage !== undefined &&
options.hasOwnProperty('useExternalPagination');
}

private defaultGridOptions(existingOptions: uiGrid.IGridOptions,
services: JSONForms.Services, schema: SchemaElement): uiGrid.IGridOptions {

var paginationEnabled = false;
var defaultGridOptions:uiGrid.IGridOptions = {};
defaultGridOptions.enableColumnResizing = true;
defaultGridOptions.enableHorizontalScrollbar = 0;
defaultGridOptions.enableVerticalScrollbar = 0;
var dataProvider = services.get<JSONForms.IDataProvider>(JSONForms.ServiceId.DataProvider);
var validationService = services.get<JSONForms.IValidationService>(JSONForms.ServiceId.Validation);
var scope = services.get<JSONForms.IScopeProvider>(JSONForms.ServiceId.ScopeProvider).getScope();

if (dataProvider instanceof JSONForms.DefaultInternalDataProvider) {
defaultGridOptions.totalItems = dataProvider.getTotalItems();
} else {

paginationEnabled = dataProvider.fetchPage !== undefined;
let externalPaginationEnabled = ArrayRenderer.isExternalPagingAvailable(dataProvider, existingOptions);
let externalFilteringEnabled = ArrayRenderer.isExternalFilterAvailable(dataProvider, existingOptions);

if (paginationEnabled) {
// disable internal and enable external pagination
defaultGridOptions.enablePagination = false;
defaultGridOptions.useExternalPagination = true;
defaultGridOptions.paginationPageSizes = [5, 10, 20];
defaultGridOptions.paginationPageSize = 5;
defaultGridOptions.paginationCurrentPage = 1;
defaultGridOptions.enablePaginationControls = true;
}
var defaultGridOptions:uiGrid.IGridOptions = {};
defaultGridOptions.totalItems = dataProvider.getTotalItems();
defaultGridOptions.enableColumnResizing = true;
defaultGridOptions.enableHorizontalScrollbar = 0;
defaultGridOptions.enableVerticalScrollbar = 0;
defaultGridOptions.paginationPageSizes = [5, 10, 20];
defaultGridOptions.paginationPageSize = 5;
defaultGridOptions.paginationCurrentPage = 1;
defaultGridOptions.enablePaginationControls = true;

// TODO: implement filtering and pass grid options accordingly
//if (filteringEnabled) {
// defaultGridOptions.enableFiltering = false;
// defaultGridOptions.useExternalPagination = true;
//}
if (externalPaginationEnabled) {
defaultGridOptions.useExternalPagination = true;
}

defaultGridOptions.onRegisterApi = (gridApi) => {
if (paginationEnabled) {
gridApi.pagination.on.paginationChanged(this.scope, (newPage, pageSize) => {
if (externalPaginationEnabled) {
gridApi.pagination.on.paginationChanged(scope, (newPage, pageSize) => {
defaultGridOptions.paginationCurrentPage = newPage;
defaultGridOptions.paginationPageSize = pageSize;
dataProvider.setPageSize(pageSize);
dataProvider.fetchPage(newPage, pageSize).then(newData => {
defaultGridOptions.data = newData;
dataProvider.fetchPage(newPage).then(newData => {
existingOptions.data = newData;
});
});
}
gridApi.edit.on.afterCellEdit(this.scope, (rowEntity, colDef: uiGrid.IColumnDef, newValue, oldValue) => {
var value = newValue;

// TODO: newValue is a string?
if (colDef.type) {
if (colDef.type == "number" || colDef.type == "integer") {
value = Number(newValue);
} else if (colDef.type == "boolean") {
value = Boolean(newValue);
}
}

rowEntity[colDef.field] = value;
if (externalFilteringEnabled) {
gridApi.core.on.filterChanged(scope, () => {
var columns = gridApi.grid.columns;
var terms = columns.reduce((acc, column) => {
var value: any = column.filters[0].term;
if (value !== undefined && value.length > 0) {
acc[column.field] = ArrayRenderer.convertColumnValue(column.colDef, value);
}
return acc;
}, {});
dataProvider.filter(terms).then(newData => {
existingOptions.data = newData;
})
});
}
gridApi.edit.on.afterCellEdit(scope, (rowEntity, colDef:uiGrid.IColumnDef, newValue, oldValue) => {
rowEntity[colDef.field] = ArrayRenderer.convertColumnValue(colDef, newValue);
validationService.validate(rowEntity, schema['items']);
// TODO: use constant
gridApi.core.notifyDataChange("column");
this.scope.$apply();
scope.$apply();
});

};

return defaultGridOptions;
return this.mergeOptions(existingOptions, defaultGridOptions);
}

private maxSize = 99;
priority = 2;
private static convertColumnValue(colDef: uiGrid.IColumnDef, value: string): any {
if (colDef.type) {
if (colDef.type == "number" || colDef.type == "integer") {
return Number(value);
} else if (colDef.type == "boolean") {
return Boolean(value);
}
}

return value;
}

private mergeOptions(optionsA: any, optionsB: any): any {
return Object.keys(optionsB).reduce((mergedOpts, optionName) => {
if (mergedOpts.hasOwnProperty(optionName)) {
return mergedOpts
}
mergedOpts[optionName] = optionsB[optionName];
return mergedOpts;
}, optionsA);
}

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


private generateColumnDefs(schema: SchemaElement, schemaPath: string): any {
var columnsDefs = [];
var subSchema = this.pathResolver.resolveSchema(schema, schemaPath);
Expand All @@ -125,10 +152,10 @@ class ArrayRenderer implements JSONForms.IRenderer {
return columnsDefs;
}

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

return element.columns.map((col) => {
return columns.map((col) => {
var href = col['href'];
if (href) {
var hrefScope = href.scope;
Expand All @@ -150,7 +177,7 @@ class ArrayRenderer implements JSONForms.IRenderer {
</div>`;
}

return {
return {
cellTemplate: cellTemplate,
field: field,
displayName: col.label,
Expand Down Expand Up @@ -178,43 +205,18 @@ class ArrayRenderer implements JSONForms.IRenderer {

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

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

if (element.columns) {
columnsDefs = this.createColumnDefs(element, subSchema, services);
} else {
columnsDefs = this.generateColumnDefs(subSchema, schemaPath);
}

var defaultGridOptions: uiGrid.IGridOptions = this.defaultGridOptions(services, schema);
var gridOptions: uiGrid.IGridOptions = element.options || {};
for (var option in defaultGridOptions) {
if (defaultGridOptions.hasOwnProperty(option)) {
gridOptions[option] = defaultGridOptions[option];
}
}
var columnsDefs: uiGrid.IColumnDef[] = element.columns ?
this.createColumnDefs(element.columns, subSchema, services) :
this.generateColumnDefs(subSchema, schemaPath);

var gridOptions: uiGrid.IGridOptions = this.defaultGridOptions(element.options || {}, services, schema);
gridOptions.columnDefs = columnsDefs;
return gridOptions;
}

findSearchTerms(grid) {
var searchTerms = [];
for (var i = 0; i < grid.columns.length; i++) {
var searchTerm = grid.columns[i].filters[0].term;
if (searchTerm !== undefined && searchTerm !== null) {
searchTerms.push({
column: grid.columns[i].getName,
term: searchTerm
});
}
}

return searchTerms;
}
}

angular.module('jsonforms.renderers.controls.array').run(['RenderService', 'PathResolver', '$rootScope', function(RenderService, PathResolver, $rootScope) {
RenderService.register(new ArrayRenderer(PathResolver, $rootScope));
angular.module('jsonforms.renderers.controls.array').run(['RenderService', 'PathResolver', function(RenderService, PathResolver) {
RenderService.register(new ArrayRenderer(PathResolver));
}]);
61 changes: 57 additions & 4 deletions components/utils/dataproviders.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,65 @@

declare module JSONForms{
export interface IDataProvider extends IService {

/**
* Initially fetches the data instance
*
* @return a promise returning the initially fetched data
*/
fetchData(): ng.IPromise<any>
fetchPage(page:number, size:number): ng.IPromise<any>
setPageSize(size:number)


/**
* Returns the instance.
*
* @return {any} the instance
*/
getData(): any
getPageSize(): number
getPage(): number

/**
* Fetches the given page of data.
*
* @param page the page to be fetched
* @return a promise returning the fetched data
*/
fetchPage?(page:number): ng.IPromise<any>

/**
* Returns the currently used page size by the data provider.
*
* @return {number} the current page size
*/
getPageSize?(): number

/**
* Set the page size to be used by the data provider.
*
* @param size the page size
*/
setPageSize?(size:number)

/**
* Returns the current page the data provider currently has in scope.
*
* @return {number} the current page
*/
getPage?(): number

/**
* Returns the overall number of items available.
* Since not all data provider are able to determine an overall number of items,
* this method is optional.
*
* @return {number} the overall number of items
*/
getTotalItems?(): number

/**
* Fetches the data filtered accordingly to the given terms.
*
* @param terms search terms
*/
filter?(terms: any): ng.IPromise<any>
}
}
11 changes: 7 additions & 4 deletions components/utils/dataproviders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ module JSONForms {
this._pageSize = newPageSize
};

fetchPage = (page: number, size: number) => {
fetchPage = (page: number) => {
this._page = page;
this._pageSize = size;
var p = this.$q.defer();
if (this._data instanceof Array) {
p.resolve(
Expand All @@ -52,9 +51,13 @@ module JSONForms {
return p.promise;
};

totalItems() {
getTotalItems():number {
return this._data.length;
}

filter(terms:any):angular.IPromise<any> {
return undefined;
}
}

export class DefaultInternalDataProvider implements IDataProvider {
Expand Down Expand Up @@ -87,7 +90,7 @@ module JSONForms {
return undefined;
}

fetchPage(page:number, size:number):angular.IPromise<any> {
fetchPage(page:number):angular.IPromise<any> {
return undefined;
}

Expand Down
18 changes: 16 additions & 2 deletions examples/js/PlaceholderController.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,13 @@ angular.module('makeithappen').controller('PlaceholderController', ['$scope', '$
"url": "/placeholder-users"
}
}
]
],
"options": {
enableFiltering: true,
// will cause IDataProvider#filter to be called
useExternalFiltering: true,
pageSizes: [5,10]
}
};

//
Expand Down Expand Up @@ -235,7 +241,7 @@ angular.module('makeithappen').controller('PlaceholderController', ['$scope', '$
var start = (page - 1) * this.pageSize;
var end = start + this.pageSize;
var that = this;
return Comments.query({_start: start, _end: end}, function (response) {
return toQuery.query({_start: start, _end: end}, function (response) {
that.data = response;
}).$promise;
},
Expand All @@ -254,6 +260,14 @@ angular.module('makeithappen').controller('PlaceholderController', ['$scope', '$
console.log("error occurred: " + JSON.stringify(error));
}).$promise;
}
},
filter: function(terms) {
var that = this;
return toQuery.query(terms, function(response) {
that.data = response;
}, function(error) {
console.log("error occurred: " + JSON.stringify(error));
}).$promise;
}
};
};
Expand Down

0 comments on commit b10b842

Please sign in to comment.