Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(editor): add missing Slider changeEditorOption() for Composite Editor #1733

Merged
merged 1 commit into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions examples/vite-demo-vanilla-bundle/src/examples/example12.ts
Original file line number Diff line number Diff line change
Expand Up @@ -628,10 +628,11 @@ export default class Example12 {
}

// you can also change some editor options
// not all Editors supports this functionality, so far only these Editors are supported: AutoComplete, Date Single/Multiple Select
// not all Editors supports this functionality, so far only these Editors are supported are: Date, Single/Multiple Select, Slider
/*
if (columnDef.id === 'completed') {
this.compositeEditorInstance.changeFormEditorOption('percentComplete', 'filter', true); // multiple-select.js, show filter in dropdown
this.compositeEditorInstance.changeFormEditorOption('complexity', 'filter', true); // multiple-select dropdown editor
this.compositeEditorInstance.changeFormEditorOption('percentComplete', 'hideSliderNumber', formValues['completed']); // slider editor
this.compositeEditorInstance.changeFormEditorOption('finish', 'range', { min: 'today' }); // calendar picker, change minDate to today
}
*/
Expand Down
68 changes: 63 additions & 5 deletions packages/common/src/editors/__tests__/sliderEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,65 @@ describe('SliderEditor', () => {
expect(cellMouseEnterSpy).toHaveBeenCalledWith({ column: mockColumn, grid: gridStub }, expect.anything());
});

describe('isValueChanged method', () => {
describe('changeEditorOption() method', () => {
it('should be able to change enableSliderTrackColoring option', () => {
editor = new SliderEditor(editorArguments);
editor.changeEditorOption('enableSliderTrackColoring', true);

expect(editor.editorOptions.enableSliderTrackColoring).toBe(true);
});

it('should be able to change hideSliderNumber option', () => {
editor = new SliderEditor(editorArguments);
editor.changeEditorOption('hideSliderNumber', true);

expect(editor.editorOptions.hideSliderNumber).toBe(true);
});

it('should be able to change maxValue option', () => {
editor = new SliderEditor(editorArguments);
editor.changeEditorOption('maxValue', 33);

expect(editor.sliderOptions?.maxValue).toBe(33);
});

it('should be able to change minValue option', () => {
editor = new SliderEditor(editorArguments);
editor.changeEditorOption('minValue', 4);

expect(editor.sliderOptions?.minValue).toBe(4);
});

it('should be able to change step option', () => {
editor = new SliderEditor(editorArguments);
editor.changeEditorOption('step', 5);

expect(editor.sliderOptions?.step).toBe(5);
});

it('should be able to change sliderStartValue option', () => {
editor = new SliderEditor(editorArguments);
editor.changeEditorOption('sliderStartValue', 33);

expect(editor.editorOptions.sliderStartValue).toBe(33);
});

it('should be able to change sliderTrackBackground option', () => {
editor = new SliderEditor(editorArguments);
editor.changeEditorOption('sliderTrackBackground', '#fff');

expect(editor.sliderOptions?.sliderTrackBackground).toBe('#fff');
});

it('should be able to change sliderTrackFilledColor option', () => {
editor = new SliderEditor(editorArguments);
editor.changeEditorOption('sliderTrackFilledColor', '#fff');

expect(editor.editorOptions.sliderTrackFilledColor).toBe('#fff');
});
});

describe('isValueChanged() method', () => {
it('should return True when previously dispatched change event is a different slider input number', () => {
mockColumn.editor!.editorOptions = { sliderStartValue: 5 };
mockItemData = { id: 1, price: 32, isActive: true };
Expand Down Expand Up @@ -305,7 +363,7 @@ describe('SliderEditor', () => {
});
});

describe('applyValue method', () => {
describe('applyValue() method', () => {
it('should apply the value to the price property when it passes validation', () => {
mockColumn.editor!.validator = null as any;
mockItemData = { id: 1, price: 456, isActive: true };
Expand Down Expand Up @@ -343,7 +401,7 @@ describe('SliderEditor', () => {
});
});

describe('serializeValue method', () => {
describe('serializeValue() method', () => {
it('should return serialized value as a number', () => {
mockItemData = { id: 1, price: 33, isActive: true };

Expand Down Expand Up @@ -407,7 +465,7 @@ describe('SliderEditor', () => {
});
});

describe('save method', () => {
describe('save() method', () => {
afterEach(() => {
vi.clearAllMocks();
});
Expand Down Expand Up @@ -472,7 +530,7 @@ describe('SliderEditor', () => {
});
});

describe('validate method', () => {
describe('validate() method', () => {
it('should return False when field is required and field is empty', () => {
mockColumn.editor!.required = true;
editor = new SliderEditor(editorArguments);
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/editors/autocompleterEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export class AutocompleterEditor<T extends AutocompleteItem = any> implements Ed
}

// get locales provided by user in forRoot or else use default English locales via the Constants
this._locales = this.gridOptions && this.gridOptions.locales || Constants.locales;
this._locales = this.gridOptions?.locales || Constants.locales;

this.init();
}
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 @@ -175,7 +175,7 @@ export class CheckboxEditor implements Editor {
}

applyValue(item: any, state: any): void {
const fieldName = this.columnDef && this.columnDef.field;
const fieldName = this.columnDef?.field;
if (fieldName !== undefined) {
const isComplexObject = fieldName?.indexOf('.') > 0; // is the field a complex object, "address.streetNumber"

Expand Down Expand Up @@ -203,7 +203,7 @@ export class CheckboxEditor implements Editor {
}

loadValue(item: any): void {
const fieldName = this.columnDef && this.columnDef.field;
const fieldName = this.columnDef?.field;

if (item && fieldName !== undefined && this._input) {
// is the field a complex object, "address.streetNumber"
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/editors/dateEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ export class DateEditor implements Editor {
* @param {string} optionName
* @param {newValue} newValue
*/
changeEditorOption<T extends keyof VanillaCalendarOption, K extends Partial<VanillaCalendarOption[T]>>(optionName: T, newValue: K): void {
changeEditorOption<T extends keyof Required<VanillaCalendarOption>, K extends Required<VanillaCalendarOption>[T]>(optionName: T, newValue: K): void {
if (!this.columnEditor.editorOptions) {
this.columnEditor.editorOptions = {};
}
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/editors/floatEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class FloatEditor extends InputEditor {
}

loadValue(item: any): void {
const fieldName = this.columnDef && this.columnDef.field;
const fieldName = this.columnDef?.field;

if (fieldName !== undefined) {

Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/editors/inputEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ export class InputEditor implements Editor {
}

applyValue(item: any, state: any): void {
const fieldName = this.columnDef && this.columnDef.field;
const fieldName = this.columnDef?.field;
if (fieldName !== undefined) {
const isComplexObject = fieldName?.indexOf('.') > 0; // is the field a complex object, "address.streetNumber"

Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/editors/selectEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ export class SelectEditor implements Editor {
* @param {string} optionName - MultipleSelect option name
* @param {newValue} newValue - MultipleSelect new option value
*/
changeEditorOption(optionName: keyof MultipleSelectOption, newValue: any): void {
changeEditorOption<T extends keyof Required<MultipleSelectOption>, K extends Required<MultipleSelectOption>[T]>(optionName: T, newValue: K): void {
if (this.columnEditor) {
if (!this.columnEditor.editorOptions) {
this.columnEditor.editorOptions = {};
Expand Down
45 changes: 40 additions & 5 deletions packages/common/src/editors/sliderEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,35 @@ export class SliderEditor implements Editor {
}
}

/**
* Dynamically change an Editor option, this is especially useful with Composite Editor
* since this is the only way to change option after the Editor is created (for example dynamically change "minDate" or another Editor)
* @param {string} optionName - Slider editor option name
* @param {newValue} newValue - Slider editor new option value
*/
changeEditorOption<T extends keyof Required<(CurrentSliderOption & SliderOption)>, K extends Required<(CurrentSliderOption & SliderOption)>[T]>(optionName: T, newValue: K): void {
if (this.columnEditor) {
this.columnEditor.editorOptions ??= {};
this.columnEditor.editorOptions[optionName] = newValue;
(this._sliderOptions as any)[optionName] = newValue;

switch (optionName) {
case 'hideSliderNumber':
this.renderSliderNumber(this._editorElm, 0);
break;
case 'sliderStartValue':
this._inputElm.value = `${newValue}`;
this._inputElm.defaultValue = `${newValue}`;
break;
case 'maxValue':
case 'minValue':
case 'step':
this._inputElm[optionName.replace('Value', '') as 'min' | 'max' | 'step'] = `${newValue}`;
break;
}
}
}

isValueChanged(): boolean {
const elmValue = this._inputElm?.value ?? '';
return (!(elmValue === '' && this._originalValue === undefined)) && (+elmValue !== this._originalValue);
Expand Down Expand Up @@ -335,19 +364,25 @@ export class SliderEditor implements Editor {
sliderInputContainerElm.appendChild(this._inputElm);
divContainerElm.appendChild(sliderInputContainerElm);

this.renderSliderNumber(divContainerElm, defaultValue);

// merge options with optional user's custom options
this._sliderOptions = { minValue, maxValue, step };

return divContainerElm;
}

protected renderSliderNumber(divContainerElm: HTMLDivElement, defaultValue: number | string): void {
if (!this.editorOptions.hideSliderNumber) {
divContainerElm.classList.add('input-group');

const divGroupAddonElm = createDomElement('div', { className: 'input-group-addon input-group-append slider-value' });
this._sliderNumberElm = createDomElement('span', { className: `input-group-text`, textContent: `${defaultValue}` });
divGroupAddonElm.appendChild(this._sliderNumberElm);
divContainerElm.appendChild(divGroupAddonElm);
} else {
divContainerElm.querySelector('.slider-value')?.remove();
}

// merge options with optional user's custom options
this._sliderOptions = { minValue, maxValue, step };

return divContainerElm;
}

/** when it's a Composite Editor, we'll check if the Editor is editable (by checking onBeforeEditCell) and if not Editable we'll disable the Editor */
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/filters/sliderFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export class SliderFilter implements Filter {
this._shouldTriggerQuery = shouldTriggerQuery;
this.searchTerms = [];
const lowestValue = +(this.filterOptions?.sliderStartValue ?? Constants.SLIDER_DEFAULT_MIN_VALUE) as number;
const highestValue = +(this.filterOptions?.sliderEndValue ?? Constants.SLIDER_DEFAULT_MAX_VALUE) as number;
const highestValue = +((this.filterOptions as SliderRangeOption)?.sliderEndValue ?? Constants.SLIDER_DEFAULT_MAX_VALUE) as number;

if (this.sliderType === 'double') {
if (this._sliderLeftInputElm) {
Expand Down
12 changes: 6 additions & 6 deletions packages/common/src/interfaces/sliderOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ export interface SliderOption {
/** Defaults to true, hide the slider number shown on the right side */
hideSliderNumber?: boolean;

/** Slider max end value */
sliderEndValue?: number;

/** Slider min start value */
sliderStartValue?: number;

/** Defaults to "#3C97DD", what will be the color to use to represent slider range */
sliderTrackFilledColor?: string;

/** Defaults to 0, minimum value gap before reaching the maximum end value */
stopGapBetweenSliderHandles?: number;
}

export interface SliderRangeOption extends Omit<SliderOption, 'hideSliderNumber'> {
/** Defaults to false, hide the slider numbers shown on the left/right side */
hideSliderNumbers?: boolean;

/** Slider max end value */
sliderEndValue?: number;

/** Defaults to 0, minimum value gap before reaching the maximum end value */
stopGapBetweenSliderHandles?: number;
}

export interface CurrentSliderOption {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export class SlickCompositeEditorComponent implements ExternalResource {
if (editor?.changeEditorOption) {
editor.changeEditorOption(optionName, newOptionValue);
} else {
throw new Error(`Editor with column id "${columnId}" not found OR the Editor does not support "changeEditorOption" (current only available with AutoComplete, Date, MultipleSelect & SingleSelect Editors).`);
throw new Error(`Editor with column id "${columnId}" not found OR the Editor does not support "changeEditorOption" (current only available with Date, MultipleSelect, SingleSelect & Slider Editors).`);
}
}

Expand Down
Loading