Skip to content

Commit

Permalink
feat(editors): convert jQuery to native element on slider editor
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding committed May 24, 2021
1 parent 7eba9ab commit 871f86b
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 135 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
insert_final_newline = true
insert_final_newline = false
trim_trailing_whitespace = true

[*]
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="https://github.com/ghiscoding/Angular-Slickgrid">
<a class="navbar-brand ms-2" href="https://github.com/ghiscoding/Angular-Slickgrid">
<i class="fa fa-github"></i>
<span>{{title}}</span>
</a>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Editors } from '../index';
import { SliderEditor } from '../sliderEditor';
import { AutocompleteOption, Column, EditorArgs, EditorArguments, GridOption, KeyCode } from '../../models';
import { AutocompleteOption, Column, ColumnEditor, EditorArgs, EditorArguments, GridOption, KeyCode } from '../../models';

const KEY_CHAR_0 = 48;
const containerId = 'demo-container';
Expand Down Expand Up @@ -47,7 +47,7 @@ describe('SliderEditor', () => {
grid: gridStub,
column: mockColumn,
item: mockItemData,
event: null,
event: null as any,
cancelChanges: jest.fn(),
commitChanges: jest.fn(),
container: divContainer,
Expand All @@ -61,7 +61,7 @@ describe('SliderEditor', () => {
describe('with invalid Editor instance', () => {
it('should throw an error when trying to call init without any arguments', (done) => {
try {
editor = new SliderEditor(null);
editor = new SliderEditor(null as any);
} catch (e) {
expect(e.toString()).toContain(`[Angular-SlickGrid] Something is wrong with this grid, an Editor must always have valid arguments.`);
done();
Expand Down Expand Up @@ -90,10 +90,10 @@ describe('SliderEditor', () => {

it('should have a title (tooltip) when defined in its column definition', () => {
const testValue = 'test title';
mockColumn.internalColumnEditor.title = testValue;
mockColumn.internalColumnEditor!.title = testValue;

editor = new SliderEditor(editorArguments);
const editorElm = divContainer.querySelector<HTMLInputElement>('.slider-editor input.editor-price');
const editorElm = divContainer.querySelector('.slider-editor input.editor-price') as HTMLInputElement;

expect(editorElm.title).toBe(testValue);
});
Expand All @@ -109,13 +109,13 @@ describe('SliderEditor', () => {
});

it('should create the input editor with defined value and a different step size when "valueStep" is provided', () => {
mockColumn.internalColumnEditor.valueStep = 5;
mockColumn.internalColumnEditor!.valueStep = 5;
mockItemData = { id: 1, price: 15, isActive: true };

editor = new SliderEditor(editorArguments);
editor.loadValue(mockItemData);
const editorNumberElm = divContainer.querySelector<HTMLInputElement>('.input-group-text');
const editorInputElm = divContainer.querySelector<HTMLInputElement>('.slider-editor input.editor-price');
const editorNumberElm = divContainer.querySelector('.input-group-text') as HTMLInputElement;
const editorInputElm = divContainer.querySelector('.slider-editor input.editor-price') as HTMLInputElement;

expect(editorInputElm.step).toBe('5');
expect(editorNumberElm.textContent).toBe('15');
Expand All @@ -130,8 +130,8 @@ describe('SliderEditor', () => {

editor = new SliderEditor(editorArguments);

const editorInputElm = divContainer.querySelector<HTMLInputElement>('.slider-editor input.editor-price');
const editorNumberElm = divContainer.querySelector<HTMLInputElement>('.input-group-text');
const editorInputElm = divContainer.querySelector('.slider-editor input.editor-price') as HTMLInputElement;
const editorNumberElm = divContainer.querySelector('.input-group-text') as HTMLInputElement;

expect(editorInputElm.min).toBe('4');
expect(editorInputElm.max).toBe('69');
Expand All @@ -145,8 +145,8 @@ describe('SliderEditor', () => {
editor = new SliderEditor(editorArguments);
editor.loadValue(mockItemData);

const editorInputElm = divContainer.querySelector<HTMLInputElement>('.slider-editor input.editor-price');
const editorNumberElm = divContainer.querySelector<HTMLInputElement>('.input-group-text');
const editorInputElm = divContainer.querySelector('.slider-editor input.editor-price') as HTMLInputElement;
const editorNumberElm = divContainer.querySelector('.input-group-text') as HTMLInputElement;

expect(editor.getValue()).toEqual('4');
expect(editorInputElm.min).toBe('0');
Expand All @@ -155,7 +155,7 @@ describe('SliderEditor', () => {
});

it('should create the input editor with default search terms range but without showing side numbers when "hideSliderNumber" is set in params', () => {
mockColumn.internalColumnEditor.params = { hideSliderNumber: true };
mockColumn.internalColumnEditor!.params = { hideSliderNumber: true };
mockItemData = { id: 1, price: null, isActive: true };

editor = new SliderEditor(editorArguments);
Expand Down Expand Up @@ -184,21 +184,23 @@ describe('SliderEditor', () => {
it('should define an item datacontext containing a string as cell value and expect this value to be loaded in the editor when calling "loadValue"', () => {
editor = new SliderEditor(editorArguments);
editor.loadValue(mockItemData);
const editorInputElm = editor.editorInputDomElement;
const editorElm = editor.editorDomElement;

expect(editor.getValue()).toBe('213');
expect(editorElm[0].defaultValue).toBe('0');
expect(editorElm).toBeTruthy();
expect(editorInputElm.defaultValue).toBe('0');
});

it('should update slider number every time a change event happens on the input slider', () => {
mockColumn.internalColumnEditor.params = { hideSliderNumber: false };
mockColumn.internalColumnEditor!.params = { hideSliderNumber: false };
mockItemData = { id: 1, price: 32, isActive: true };
editor = new SliderEditor(editorArguments);
editor.loadValue(mockItemData);
editor.setValue(17);

const editorElm = divContainer.querySelector('.slider-container.slider-editor');
const editorNumberElm = divContainer.querySelector<HTMLInputElement>('.input-group-text');
const editorElm = divContainer.querySelector('.slider-container.slider-editor') as HTMLDivElement;
const editorNumberElm = divContainer.querySelector('.input-group-text') as HTMLInputElement;
const mockEvent = new Event('change');
Object.defineProperty(mockEvent, 'target', { writable: true, configurable: true, value: { value: '13' } });
editorElm.dispatchEvent(mockEvent);
Expand All @@ -209,14 +211,14 @@ describe('SliderEditor', () => {

describe('isValueChanged method', () => {
it('should return True when previously dispatched change event is a different slider input number', () => {
mockColumn.internalColumnEditor.params = { sliderStartValue: 5 };
mockColumn.internalColumnEditor!.params = { sliderStartValue: 5 };
mockItemData = { id: 1, price: 32, isActive: true };
editor = new SliderEditor(editorArguments);
editor.loadValue(mockItemData);
editor.setValue(45);

const editorElm = divContainer.querySelector<HTMLInputElement>('.slider-editor input.editor-price');
editorElm.dispatchEvent(new CustomEvent('change'));
const editorElm = divContainer.querySelector('.slider-editor input.editor-price') as HTMLInputElement;
editorElm.dispatchEvent(new Event('change'));

expect(editor.isValueChanged()).toBe(true);
});
Expand All @@ -226,8 +228,8 @@ describe('SliderEditor', () => {
editor = new SliderEditor(editorArguments);
editor.loadValue(mockItemData);

const editorElm = divContainer.querySelector<HTMLInputElement>('.slider-editor input.editor-price');
editorElm.dispatchEvent(new CustomEvent('change'));
const editorElm = divContainer.querySelector('.slider-editor input.editor-price') as HTMLInputElement;
editorElm.dispatchEvent(new Event('change'));

expect(editor.isValueChanged()).toBe(false);
});
Expand All @@ -237,28 +239,28 @@ describe('SliderEditor', () => {
editor = new SliderEditor(editorArguments);
editor.loadValue(mockItemData);

const editorElm = divContainer.querySelector<HTMLInputElement>('.slider-editor input.editor-price');
editorElm.dispatchEvent(new CustomEvent('change'));
const editorElm = divContainer.querySelector('.slider-editor input.editor-price') as HTMLInputElement;
editorElm.dispatchEvent(new Event('change'));

expect(editor.isValueChanged()).toBe(false);
});

it('should return False when previously dispatched change event is the same input number as "sliderStartValue" provided by the user', () => {
mockColumn.internalColumnEditor.params = { sliderStartValue: 5 };
mockColumn.internalColumnEditor!.params = { sliderStartValue: 5 };
mockItemData = { id: 1, price: 5, isActive: true };
editor = new SliderEditor(editorArguments);
editor.loadValue(mockItemData);

const editorElm = divContainer.querySelector<HTMLInputElement>('.slider-editor input.editor-price');
editorElm.dispatchEvent(new CustomEvent('change'));
const editorElm = divContainer.querySelector('.slider-editor input.editor-price') as HTMLInputElement;
editorElm.dispatchEvent(new Event('change'));

expect(editor.isValueChanged()).toBe(false);
});
});

describe('applyValue method', () => {
it('should apply the value to the price property when it passes validation', () => {
mockColumn.internalColumnEditor.validator = null;
mockColumn.internalColumnEditor!.validator = null as any;
mockItemData = { id: 1, price: 456, isActive: true };

editor = new SliderEditor(editorArguments);
Expand All @@ -268,7 +270,7 @@ describe('SliderEditor', () => {
});

it('should apply the value to the price property with a field having dot notation (complex object) that passes validation', () => {
mockColumn.internalColumnEditor.validator = null;
mockColumn.internalColumnEditor!.validator = null as any;
mockColumn.field = 'part.price';
mockItemData = { id: 1, part: { price: 456 }, isActive: true };

Expand All @@ -279,7 +281,7 @@ describe('SliderEditor', () => {
});

it('should return item data with an empty string in its value when it fails the custom validation', () => {
mockColumn.internalColumnEditor.validator = (value: any, args: EditorArgs) => {
mockColumn.internalColumnEditor!.validator = (value: any) => {
if (+value < 10) {
return { valid: false, msg: 'Value must be over 10.' };
}
Expand Down Expand Up @@ -336,7 +338,7 @@ describe('SliderEditor', () => {
});

it('should return serialized value as the custom "sliderStartValue" number when item value is null', () => {
mockColumn.internalColumnEditor.params = { sliderStartValue: 5 };
mockColumn.internalColumnEditor!.params = { sliderStartValue: 5 };
mockItemData = { id: 1, price: null, isActive: true };

editor = new SliderEditor(editorArguments);
Expand Down Expand Up @@ -412,8 +414,7 @@ describe('SliderEditor', () => {
const spySave = jest.spyOn(editor, 'save');
const editorElm = editor.editorDomElement;

editorElm.trigger('mouseup');
editorElm[0].dispatchEvent(new (window.window as any).Event('mouseup'));
editorElm.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true }));

setTimeout(() => {
expect(spyCommit).toHaveBeenCalled();
Expand All @@ -425,16 +426,16 @@ describe('SliderEditor', () => {

describe('validate method', () => {
it('should return False when field is required and field is empty', () => {
mockColumn.internalColumnEditor.required = true;
(mockColumn.internalColumnEditor as ColumnEditor).required = true;
editor = new SliderEditor(editorArguments);
const validation = editor.validate('');

expect(validation).toEqual({ valid: false, msg: 'Field is required' });
});

it('should return False when field is not between minValue & maxValue defined', () => {
mockColumn.internalColumnEditor.minValue = 10;
mockColumn.internalColumnEditor.maxValue = 99;
(mockColumn.internalColumnEditor as ColumnEditor).minValue = 10;
(mockColumn.internalColumnEditor as ColumnEditor).maxValue = 99;
editor = new SliderEditor(editorArguments);
const validation = editor.validate(100);

Expand Down

0 comments on commit 871f86b

Please sign in to comment.