Skip to content

Commit

Permalink
feat(editors): add Column Editor collectionOverride option (#228)
Browse files Browse the repository at this point in the history
* feat(editors): add Column Editor collectionOverride option
  • Loading branch information
ghiscoding authored Jan 6, 2021
1 parent 526881f commit 91421fc
Show file tree
Hide file tree
Showing 22 changed files with 435 additions and 361 deletions.
2 changes: 1 addition & 1 deletion examples/webpack-demo-vanilla-bundle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@
"url-loader": "^4.1.1",
"webpack": "^5.11.1",
"webpack-cli": "^4.3.1",
"webpack-dev-server": "^3.11.1"
"webpack-dev-server": "next"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export class Example4 {
// We can also add HTML text to be rendered (any bad script will be sanitized) but we have to opt-in, else it will be sanitized
enableRenderHtml: true,
// collection: [{ value: '1', label: '1' }, { value: '2', label: '2' }, { value: '3', label: '3' }, { value: '4', label: '4' }, { value: '5', label: '5' }],
collection: Array.from(Array(101).keys()).map(k => ({ value: k, label: k, symbol: '<i class="mdi mdi-percent-outline" style="color:cadetblue"></i>' })),
collection: Array.from(Array(101).keys()).map(k => ({ value: k, label: k, symbol: '<i class="mdi mdi-percent-outline color-info"></i>' })),
customStructure: {
value: 'value',
label: 'label',
Expand All @@ -111,6 +111,10 @@ export class Example4 {
value: 0,
operator: OperatorType.notEqual
},
// collectionOverride: (updatedCollection, args) => {
// console.log(args);
// return updatedCollection.filter((col) => args.dataContext.id % 2 ? col.value < 50 : col.value >= 50);
// },
editorOptions: {
filter: true // adds a filter on top of the multi-select dropdown
},
Expand Down
2 changes: 2 additions & 0 deletions examples/webpack-demo-vanilla-bundle/src/examples/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ export class Icons {
'.mdi.mdi-pencil-outline',
'.mdi.mdi-pencil-box-multiple',
'.mdi.mdi-pencil-box-multiple-outline',
'.mdi.mdi-percent',
'.mdi.mdi-percent-outline',
'.mdi.mdi-pin-off-outline',
'.mdi.mdi-pin-outline',
'.mdi.mdi-playlist-plus',
Expand Down
23 changes: 6 additions & 17 deletions examples/webpack-demo-vanilla-bundle/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,10 @@ const baseUrl = '';
const outDirLocal = path.resolve(__dirname, 'dist');
const outDirProd = path.resolve(__dirname, '../../docs');
const srcDir = path.resolve(__dirname, 'src');
const platform = {
hmr: false,
open: true,
port: 8888,
host: 'localhost',
output: 'dist'
};

module.exports = ({ production } = {}, { hmr, port, host } = {}) => ({
mode: production ? 'production' : 'development',
entry: {
app: [`${srcDir}/main.ts`],
},
entry: `${srcDir}/main.ts`,
stats: {
warnings: false
},
Expand Down Expand Up @@ -69,14 +60,12 @@ module.exports = ({ production } = {}, { hmr, port, host } = {}) => ({
],
},
devServer: {
contentBase: production ? outDirProd : outDirLocal,
// serve index.html for all 404 (required for push-state)
static: production ? outDirProd : outDirLocal,
port: 8888,
hot: false,
host: 'localhost',
open: true,
historyApiFallback: true,
hot: hmr || platform.hmr,
port: port || platform.port,
host: host || platform.host,
open: platform.open,
disableHostCheck: true,
},
devtool: production ? false : 'eval-cheap-module-source-map',
plugins: [
Expand Down
17 changes: 17 additions & 0 deletions packages/common/src/editors/__tests__/autoCompleteEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,23 @@ describe('AutoCompleteEditor', () => {
expect(autoCompleteSpy).toHaveBeenCalledWith('option', 'delay', 500);
});

describe('collectionOverride callback option', () => {
it('should create the editor and expect a different collection outputed when using the override', () => {
mockColumn.internalColumnEditor = {
collection: [{ value: 'other', label: 'Other' }, { value: 'male', label: 'Male' }, { value: 'female', label: 'Female' }],
collectionOverride: (inputCollection) => inputCollection.filter(item => item.value !== 'other')
};

editor = new AutoCompleteEditor(editorArguments);
editor.destroy();
editor.init();
const editorCount = divContainer.querySelectorAll('input.editor-text.editor-gender').length;

expect(editorCount).toBe(1);
expect(editor.elementCollection).toEqual([{ value: 'male', label: 'Male', labelPrefix: '', labelSuffix: '' }, { value: 'female', label: 'Female', labelPrefix: '', labelSuffix: '' }]);
});
});

describe('applyValue method', () => {
it('should apply the value to the gender property when it passes validation', () => {
(mockColumn.internalColumnEditor as ColumnEditor).validator = null as any;
Expand Down
18 changes: 18 additions & 0 deletions packages/common/src/editors/__tests__/selectEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,24 @@ describe('SelectEditor', () => {
});
});

describe('collectionOverride callback option', () => {
it('should create the multi-select editor and expect a different collection outputed when using the override', () => {
mockColumn.internalColumnEditor = {
collection: ['other', 'male', 'female'],
collectionOverride: (inputCollection) => inputCollection.filter(item => item !== 'other')
};

editor = new SelectEditor(editorArguments, true);
const editorBtnElm = divContainer.querySelector('.ms-parent.ms-filter.editor-gender button.ms-choice') as HTMLButtonElement;
const editorListElm = divContainer.querySelectorAll<HTMLInputElement>(`[name=editor-gender].ms-drop ul>li input[type=checkbox]`);
editorBtnElm.click();

expect(editorListElm.length).toBe(2);
expect(editorListElm[0].value).toBe('male');
expect(editorListElm[1].value).toBe('female');
});
});

describe('collectionInsideObjectProperty setting', () => {
it('should create the multi-select editor with a value/label pair collection that is inside an object when "collectionInsideObjectProperty" is defined with a dot notation', () => {
mockColumn.internalColumnEditor = {
Expand Down
11 changes: 8 additions & 3 deletions packages/common/src/editors/autoCompleteEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export class AutoCompleteEditor implements Editor {

/** Getter of the Collection */
get editorCollection(): any[] {
return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor.collection || [];
return this.columnDef?.internalColumnEditor?.collection ?? [];
}

/** Getter for the Editor DOM Element */
Expand All @@ -93,8 +93,8 @@ export class AutoCompleteEditor implements Editor {
}

/** Get Column Definition object */
get columnDef(): Column | undefined {
return this.args && this.args.column;
get columnDef(): Column {
return this.args.column;
}

/** Get Column Editor object */
Expand Down Expand Up @@ -476,6 +476,11 @@ export class AutoCompleteEditor implements Editor {
// assign the collection to a temp variable before filtering/sorting the collection
let finalCollection = collection;

// user could also override the collection
if (this.columnEditor?.collectionOverride) {
finalCollection = this.columnEditor.collectionOverride(finalCollection, { column: this.columnDef, dataContext: this.args.item, grid: this.grid });
}

// user might provide his own custom structure
// jQuery UI autocomplete requires a label/value pair, so we must remap them when user provide different ones
if (Array.isArray(finalCollection)) {
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/editors/checkboxEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export class CheckboxEditor implements Editor {
}

/** Get Column Definition object */
get columnDef(): Column | undefined {
return this.args && this.args.column;
get columnDef(): Column {
return this.args.column;
}

/** Get Column Editor object */
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/editors/dateEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ export class DateEditor implements Editor {
}

/** Get Column Definition object */
get columnDef(): Column | undefined {
return this.args && this.args.column;
get columnDef(): Column {
return this.args.column;
}

/** Get Column Editor object */
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/editors/dualInputEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ export class DualInputEditor implements Editor {
}

/** Get Column Definition object */
get columnDef(): Column | undefined {
return this.args && this.args.column;
get columnDef(): Column {
return this.args.column;
}

/** Get Column Editor object */
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/editors/floatEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export class FloatEditor implements Editor {
}

/** Get Column Definition object */
get columnDef(): Column | undefined {
return this.args && this.args.column;
get columnDef(): Column {
return this.args.column;
}

/** Get Column Editor object */
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/editors/integerEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export class IntegerEditor implements Editor {
}

/** Get Column Definition object */
get columnDef(): Column | undefined {
return this.args && this.args.column;
get columnDef(): Column {
return this.args.column;
}

/** Get Column Editor object */
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/editors/longTextEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ export class LongTextEditor implements Editor {
}

/** Get Column Definition object */
get columnDef(): Column | undefined {
return this.args && this.args.column;
get columnDef(): Column {
return this.args.column;
}

/** Get Column Editor object */
Expand Down
11 changes: 8 additions & 3 deletions packages/common/src/editors/selectEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ export class SelectEditor implements Editor {
}

/** Get Column Definition object */
get columnDef(): Column | undefined {
return this.args && this.args.column;
get columnDef(): Column {
return this.args.column;
}

/** Get Column Editor object */
Expand All @@ -186,7 +186,7 @@ export class SelectEditor implements Editor {
* The current selected values (multiple select) from the collection
*/
get currentValues(): any[] | null {
const elmValue = this.$editorElm.val();
const elmValue = this.$editorElm?.val();

// collection of strings, just return the filtered string that are equals
if (this.collection.every(x => typeof x === 'string')) {
Expand Down Expand Up @@ -626,6 +626,11 @@ export class SelectEditor implements Editor {
newCollection = this.filterCollection(newCollection);
newCollection = this.sortCollection(newCollection);

// user could also override the collection
if (this.columnEditor?.collectionOverride) {
newCollection = this.columnEditor.collectionOverride(newCollection, { column: this.columnDef, dataContext: this.args.item, grid: this.grid });
}

// step 1, create HTML string template
const editorTemplate = this.buildTemplateHtmlString(newCollection);

Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/editors/sliderEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export class SliderEditor implements Editor {
}

/** Get Column Definition object */
get columnDef(): Column | undefined {
return this.args && this.args.column;
get columnDef(): Column {
return this.args.column;
}

/** Get Column Editor object */
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/editors/textEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export class TextEditor implements Editor {
}

/** Get Column Definition object */
get columnDef(): Column | undefined {
return this.args && this.args.column;
get columnDef(): Column {
return this.args.column;
}

/** Get Column Editor object */
Expand Down
12 changes: 12 additions & 0 deletions packages/common/src/interfaces/collectionOverrideArgs.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Column, SlickGrid } from './index';

export interface CollectionOverrideArgs {
/** Column Definition */
column: Column;

/** item data context object */
dataContext: any;

/** Slick Grid object */
grid: SlickGrid;
}
2 changes: 1 addition & 1 deletion packages/common/src/interfaces/column.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export interface Column<T = any> {
defaultSortAsc?: boolean;

/** Any inline editor function that implements Editor for the cell value or ColumnEditor */
editor?: ColumnEditor | any;
editor?: ColumnEditor;

/** Default to false, which leads to exclude the column title from the Column Picker. */
excludeFromColumnPicker?: boolean;
Expand Down
7 changes: 7 additions & 0 deletions packages/common/src/interfaces/columnEditor.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
CollectionCustomStructure,
CollectionFilterBy,
CollectionOption,
CollectionOverrideArgs,
CollectionSortBy,
EditorValidator,
MultipleSelectOption,
Expand Down Expand Up @@ -39,6 +40,12 @@ export interface ColumnEditor {
/** Options to change the behavior of the "collection" */
collectionOptions?: CollectionOption;

/**
* A collection override allows you to manipulate the collection provided to the Column Editor.
* NOTE: if you provide a "customStructure" it will still be applied on the collection, in other words make sure that the collection returned by the override does have the properties defined in the "customStructure".
*/
collectionOverride?: (collectionInput: any[], args: CollectionOverrideArgs) => any[];

/** We could sort the collection by 1 or more properties, or by translated value(s) when enableTranslateLabel is True */
collectionSortBy?: CollectionSortBy | CollectionSortBy[];

Expand Down
1 change: 1 addition & 0 deletions packages/common/src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export * from './checkboxSelectorOption.interface';
export * from './collectionCustomStructure.interface';
export * from './collectionFilterBy.interface';
export * from './collectionOption.interface';
export * from './collectionOverrideArgs.interface';
export * from './collectionSortBy.interface';
export * from './column.interface';
export * from './columnEditor.interface';
Expand Down
10 changes: 10 additions & 0 deletions packages/common/src/styles/material-svg-icons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,16 @@ $icon-height: $icon-width;
"M4 6H2V20C2 21.11 2.9 22 4 22H18V20H4V6M18.7 7.35L17.7 8.35L15.65 6.3L16.65 5.3C16.86 5.08 17.21 5.08 17.42 5.3L18.7 6.58C18.92 6.79 18.92 7.14 18.7 7.35M9 12.94L15.06 6.88L17.12 8.94L11.06 15H9V12.94M20 4L20 4L20 16L8 16L8 4H20M20 2H8C6.9 2 6 2.9 6 4V16C6 17.1 6.9 18 8 18H20C21.1 18 22 17.1 22 16V4C22 2.9 21.1 2 20 2Z",
encodecolor($icon-color), $icon-height, $icon-width, inline-block);

@include loadsvg(
".mdi.mdi-percent",
"M18.5,3.5L3.5,18.5L5.5,20.5L20.5,5.5M7,4A3,3 0 0,0 4,7A3,3 0 0,0 7,10A3,3 0 0,0 10,7A3,3 0 0,0 7,4M17,14A3,3 0 0,0 14,17A3,3 0 0,0 17,20A3,3 0 0,0 20,17A3,3 0 0,0 17,14Z",
encodecolor($icon-color), $icon-height, $icon-width, inline-block);

@include loadsvg(
".mdi.mdi-percent-outline",
"M18.5 3.5L20.5 5.5L5.5 20.5L3.5 18.5L18.5 3.5M7 4C8.66 4 10 5.34 10 7C10 8.66 8.66 10 7 10C5.34 10 4 8.66 4 7C4 5.34 5.34 4 7 4M17 14C18.66 14 20 15.34 20 17C20 18.66 18.66 20 17 20C15.34 20 14 18.66 14 17C14 15.34 15.34 14 17 14M7 6C6.45 6 6 6.45 6 7C6 7.55 6.45 8 7 8C7.55 8 8 7.55 8 7C8 6.45 7.55 6 7 6M17 16C16.45 16 16 16.45 16 17C16 17.55 16.45 18 17 18C17.55 18 18 17.55 18 17C18 16.45 17.55 16 17 16Z",
encodecolor($icon-color), $icon-height, $icon-width, inline-block);

@include loadsvg(
".mdi.mdi-pin-off-outline",
"M8,6.2V4H7V2H17V4H16V12L18,14V16H17.8L14,12.2V4H10V8.2L8,6.2M20,20.7L18.7,22L12.8,16.1V22H11.2V16H6V14L8,12V11.3L2,5.3L3.3,4L20,20.7M8.8,14H10.6L9.7,13.1L8.8,14Z",
Expand Down
Loading

0 comments on commit 91421fc

Please sign in to comment.