Skip to content

Commit

Permalink
feat(ngTableFilterConfig): nested options never undefined
Browse files Browse the repository at this point in the history
This is part of supporting typescript strictNullChecks compiler option.

BREAKING CHANGES

`NgTableFilterConfigProvider.setConfig`: any config value supplied as undefined will now be ignored

Instead of `undefined` you will need to supply a suitable value as described below:

* `aliasUrls` - an empty object to reset configuration back to using filter templates supplied by the ng-table library
  • Loading branch information
ccrowhurstram committed Dec 21, 2016
1 parent 3f54fdb commit 842b45d
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 49 deletions.
3 changes: 2 additions & 1 deletion src/browser/index.ts
Expand Up @@ -37,4 +37,5 @@ const ngTableBrowserModule = angular.module('ngTable-browser', [])
.controller('ngTableSorterRowController', NgTableSorterRowController);

export * from './public-interfaces';
export { NgTableController, NgTableFilterConfigProvider, NgTableFilterConfig, ngTableBrowserModule };
export { NgTableController, ngTableBrowserModule };
export * from './ngTableFilterConfig';
29 changes: 14 additions & 15 deletions src/browser/ngTableDynamic.directive.ts
Expand Up @@ -15,6 +15,10 @@ interface ScopeExtensions {
$columns: ColumnDef[]
}

function toArray<T>(arr: ArrayLike<T>) {
return Array.prototype.slice.call(arr) as T[];
}

ngTableDynamic.$inject = [];

/**
Expand All @@ -31,40 +35,35 @@ ngTableDynamic.$inject = [];
* </table>
* ```
*/
export function ngTableDynamic () : IDirective{
export function ngTableDynamic(): IDirective {

return {
restrict: 'A',
priority: 1001,
scope: true,
controller: 'ngTableController',
compile: function(tElement: IAugmentedJQuery) {
let row: IAugmentedJQuery;
compile: function (tElement: IAugmentedJQuery) {

// IE 8 fix :not(.ng-table-group) selector
ng1.forEach(tElement.find('tr'), (tr: JQuery) => {
tr = ng1.element(tr);
if (!tr.hasClass('ng-table-group') && !row) {
row = tr;
}
});
if (!row) {
const tRows = toArray(tElement[0].getElementsByTagName('tr'));
const tRow = tRows.filter(tr => !ng1.element(tr).hasClass('ng-table-group'))[0];

if (!tRow) {
return undefined;
}

ng1.forEach(row.find('td'), (item: JQuery) => {
const el = ng1.element(item);
toArray(tRow.getElementsByTagName('td')).forEach(tCell => {
const el = ng1.element(tCell);
const getAttrValue = (attr: string) => {
return el.attr('x-data-' + attr) || el.attr('data-' + attr) || el.attr(attr);
};

// this used in responsive table
const titleExpr = getAttrValue('title');
if (!titleExpr){
if (!titleExpr) {
el.attr('data-title-text', '{{$columns[$index].titleAlt(this) || $columns[$index].title(this)}}');
}
const showExpr = el.attr('ng-if');
if (!showExpr){
if (!showExpr) {
el.attr('ng-if', '$columns[$index].show(this)');
}
});
Expand Down
38 changes: 27 additions & 11 deletions src/browser/ngTableFilterConfig.ts
Expand Up @@ -8,7 +8,30 @@

import * as ng1 from 'angular';
import { IServiceProvider, auto } from 'angular';
import { FilterConfigValues, FilterTemplateDef } from './public-interfaces';
import { assignPartialDeep } from '../shared';
import { FilterTemplateDef } from './public-interfaces';

/**
* Configuration values that determine the behaviour of the `ngTableFilterConfig` service
*/
export class FilterConfigValues {
/**
* The default base url to use when deriving the url for a filter template given just an alias name
*/
defaultBaseUrl = 'ng-table/filters/';
/**
* The extension to use when deriving the url of a filter template when given just an alias name
*/
defaultExt = '.html';
/**
* A map of alias names and their corrosponding urls. A lookup against this map will be used
* to find the url matching an alias name.
* If no match is found then a url will be derived using the following pattern `${defaultBaseUrl}${aliasName}.${defaultExt}`
*/
aliasUrls: { [name: string]: string } = {};
}

export type FilterConfigValuesPartial = Partial<FilterConfigValues>

/**
* The angular provider used to configure the behaviour of the `NgTableFilterConfig` service.
Expand All @@ -17,11 +40,6 @@ export class NgTableFilterConfigProvider implements IServiceProvider {
static $inject = ['$injector'];
$get: () => NgTableFilterConfig;
private config: FilterConfigValues;
private defaultConfig: FilterConfigValues = {
defaultBaseUrl: 'ng-table/filters/',
defaultExt: '.html',
aliasUrls: {}
};
constructor($injector: auto.IInjectorService) {
this.$get = () => {
return $injector.instantiate<NgTableFilterConfig>(NgTableFilterConfig, { config: ng1.copy(this.config) });
Expand All @@ -34,16 +52,14 @@ export class NgTableFilterConfigProvider implements IServiceProvider {
* Reset back to factory defaults the config values that `NgTableFilterConfig` service will use
*/
resetConfigs() {
this.config = this.defaultConfig;
this.config = new FilterConfigValues();
}

/**
* Set the config values used by `NgTableFilterConfig` service
*/
setConfig(customConfig: FilterConfigValues) {
const mergeConfig = ng1.extend({}, this.config, customConfig);
mergeConfig.aliasUrls = ng1.extend({}, this.config.aliasUrls, customConfig.aliasUrls);
this.config = mergeConfig;
setConfig(customConfig: FilterConfigValuesPartial) {
this.config = assignPartialDeep(ng1.copy(this.config), customConfig);
}
}

Expand Down
21 changes: 0 additions & 21 deletions src/browser/public-interfaces.ts
Expand Up @@ -157,27 +157,6 @@ export interface DynamicTableColDef {
titleAlt?: DynamicTableColField<string>;
}

/**
* Configuration values that determine the behaviour of the `ngTableFilterConfig` service
*/
export interface FilterConfigValues {
/**
* The default base url to use when deriving the url for a filter template given just an alias name
* Defaults to 'ng-table/filters/'
*/
defaultBaseUrl?: string;
/**
* The extension to use when deriving the url of a filter template when given just an alias name
*/
defaultExt?: string;
/**
* A map of alias names and their corrosponding urls. A lookup against this map will be used
* to find the url matching an alias name.
* If no match is found then a url will be derived using the following pattern `${defaultBaseUrl}${aliasName}.${defaultExt}`
*/
aliasUrls?: { [name: string]: string };
}

/**
* A key value-pair map where the key is the name of a field in a data row and the value is the definition
* for the template used to render a filter cell in the header of a html table.
Expand Down
45 changes: 44 additions & 1 deletion test/specs/filters.spec.ts
@@ -1,5 +1,6 @@
import { NgTableFilterConfig, NgTableFilterConfigProvider, ngTableBrowserModule } from '../../src/browser';
import * as ng1 from 'angular';
import * as _ from 'lodash';
import { NgTableFilterConfig, NgTableFilterConfigProvider, FilterConfigValues, ngTableBrowserModule } from '../../src/browser';

describe('ngTableFilterConfig', () => {
let ngTableFilterConfig: NgTableFilterConfig,
Expand All @@ -19,8 +20,24 @@ describe('ngTableFilterConfig', () => {
}));


it('should return defaults', () => {
ngTableFilterConfig = ngTableFilterConfigProvider.$get();

expect(ngTableFilterConfig.config).toEqualPlainObject({
defaultBaseUrl: 'ng-table/filters/',
defaultExt: '.html',
aliasUrls: {}
});
})


describe('setConfig', () => {

let allSettings: FilterConfigValues
beforeEach(() => {
allSettings = new FilterConfigValues();
});

it('should set aliasUrls supplied', () => {

ngTableFilterConfigProvider.setConfig({
Expand Down Expand Up @@ -49,6 +66,32 @@ describe('ngTableFilterConfig', () => {
expect(ngTableFilterConfig.config.aliasUrls['text']).toBe('custom/url/text.html');
expect(ngTableFilterConfig.config.aliasUrls['number']).toBe('custom/url/custom-number.html');
});

it('undefined values in new settings should be ignored', () => {
const newSettings = _.mapValues(allSettings, _.constant(undefined));
// when
ngTableFilterConfigProvider.setConfig(newSettings);
// then
ngTableFilterConfig = ngTableFilterConfigProvider.$get();
expect(ngTableFilterConfig.config).toEqualPlainObject(allSettings);
});

it('undefined nested values in new settings should be ignored', () => {
ngTableFilterConfigProvider.setConfig({
aliasUrls: {
'text': 'custom/url/text.html'
}
});

ngTableFilterConfigProvider.setConfig({
aliasUrls: {
'text': undefined
}
});

ngTableFilterConfig = ngTableFilterConfigProvider.$get();
expect(ngTableFilterConfig.config.aliasUrls['text']).toBe('custom/url/text.html');
});
});

describe('getTemplateUrl', () => {
Expand Down

0 comments on commit 842b45d

Please sign in to comment.