Skip to content

Commit

Permalink
Merge 66cb896 into 9f39bd8
Browse files Browse the repository at this point in the history
  • Loading branch information
edgarmueller committed Nov 12, 2015
2 parents 9f39bd8 + 66cb896 commit 1a69bba
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 85 deletions.
155 changes: 77 additions & 78 deletions components/renderers/controls/array/array-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,80 +2,105 @@

class ArrayRenderer implements JSONForms.IRenderer {

private maxSize = 99;
priority = 2;

constructor(private pathResolver: JSONForms.IPathResolver, private scope: ng.IScope) {

}

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);

if (dataProvider instanceof JSONForms.DefaultInternalDataProvider) {
defaultGridOptions.totalItems = dataProvider.getTotalItems();
} else {
let externalPaginationEnabled = ArrayRenderer.isExternalPagingAvailable(dataProvider, existingOptions);
let externalFilteringEnabled = ArrayRenderer.isExternalFilterAvailable(dataProvider, existingOptions);

paginationEnabled = dataProvider.fetchPage !== undefined;

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) {
if (externalPaginationEnabled) {
gridApi.pagination.on.paginationChanged(this.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(this.scope, () => {
var columns = gridApi.grid.columns;
var terms = columns.reduce((acc, column) => {
var value: any = column.filters[0].term;
acc[column.field] = ArrayRenderer.convertColumnValue(column.colDef, value);
return acc;
}, {});
dataProvider.filter(terms).then(newData => {
existingOptions.data = newData;
})
});
}
gridApi.edit.on.afterCellEdit(this.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();
});

};

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 +127,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 +149,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 +174,7 @@ class ArrayRenderer implements JSONForms.IRenderer {
</div>`;
}

return {
return {
cellTemplate: cellTemplate,
field: field,
displayName: col.label,
Expand Down Expand Up @@ -178,41 +202,16 @@ 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) {
Expand Down
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>
}
}
20 changes: 17 additions & 3 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 @@ -202,7 +208,7 @@ angular.module('makeithappen').controller('PlaceholderController', ['$scope', '$
// Resources --
//

var Posts = $resource('http://localhost:3000/posts/:id');
var Posts = $resource('http://localhost:3000/posts/:id?');
var Users = $resource('http://localhost:3000/users/:id');
var Comments = $resource('http://localhost:3000/comments/:id');

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 1a69bba

Please sign in to comment.