Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.
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
19 changes: 7 additions & 12 deletions src/app/examples/custom-angularComponentEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Subscription } from 'rxjs';
import {
AngularUtilService,
Column,
ColumnEditor,
Editor,
EditorValidator,
EditorValidatorOutput,
Expand Down Expand Up @@ -53,7 +54,7 @@ export class CustomAngularComponentEditor implements Editor {
}

/** Get Column Editor object */
get columnEditor(): any {
get columnEditor(): ColumnEditor {
return this.columnDef && this.columnDef.internalColumnEditor || {};
}

Expand Down Expand Up @@ -94,13 +95,10 @@ export class CustomAngularComponentEditor implements Editor {
}

save() {
const validation = this.validate();
if (validation && validation.valid) {
if (this.hasAutoCommitEdit) {
this.args.grid.getEditorLock().commitCurrentEdit();
} else {
this.args.commitChanges();
}
if (this.hasAutoCommitEdit) {
this.args.grid.getEditorLock().commitCurrentEdit();
} else {
this.args.commitChanges();
}
}

Expand Down Expand Up @@ -166,10 +164,7 @@ export class CustomAngularComponentEditor implements Editor {
validate(): EditorValidatorOutput {
if (this.validator) {
const value = this.componentRef.instance.selectedId;
const validationResults = this.validator(value, this.args);
if (!validationResults.valid) {
return validationResults;
}
return this.validator(value, this.args);
}

// by default the editor is always valid
Expand Down
22 changes: 12 additions & 10 deletions src/app/examples/custom-inputEditor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Column, Editor, EditorValidator, EditorValidatorOutput, KeyCode } from './../modules/angular-slickgrid';
import { Column, ColumnEditor, Editor, EditorValidator, EditorValidatorOutput, KeyCode } from './../modules/angular-slickgrid';

// using external non-typed js libraries
declare var $: any;
Expand All @@ -8,6 +8,7 @@ declare var $: any;
* KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.
*/
export class CustomInputEditor implements Editor {
private _lastInputEvent: KeyboardEvent;
$input: any;
defaultValue: any;

Expand All @@ -21,7 +22,7 @@ export class CustomInputEditor implements Editor {
}

/** Get Column Editor object */
get columnEditor(): any {
get columnEditor(): ColumnEditor {
return this.columnDef && this.columnDef.internalColumnEditor || {};
}

Expand All @@ -39,9 +40,10 @@ export class CustomInputEditor implements Editor {

this.$input = $(`<input type="text" class="editor-text" placeholder="${placeholder}" />`)
.appendTo(this.args.container)
.on('keydown.nav', (e) => {
if (e.keyCode === KeyCode.LEFT || e.keyCode === KeyCode.RIGHT) {
e.stopImmediatePropagation();
.on('keydown.nav', (event: KeyboardEvent) => {
this._lastInputEvent = event;
if (event.keyCode === KeyCode.LEFT || event.keyCode === KeyCode.RIGHT) {
event.stopImmediatePropagation();
}
});

Expand Down Expand Up @@ -88,6 +90,10 @@ export class CustomInputEditor implements Editor {
}

isValueChanged() {
const lastEvent = this._lastInputEvent && this._lastInputEvent.keyCode;
if (this.columnEditor && this.columnEditor.alwaysSaveOnEnterKey && lastEvent === KeyCode.ENTER) {
return true;
}
return (!(this.$input.val() === '' && this.defaultValue === null)) && (this.$input.val() !== this.defaultValue);
}

Expand All @@ -102,11 +108,7 @@ export class CustomInputEditor implements Editor {
validate(): EditorValidatorOutput {
if (this.validator) {
const value = this.$input && this.$input.val && this.$input.val();
const validationResults = this.validator(value, this.args);

if (!validationResults.valid) {
return validationResults;
}
return this.validator(value, this.args);
}

return {
Expand Down
5 changes: 4 additions & 1 deletion src/app/examples/grid-editor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export class GridEditorComponent implements OnInit {
type: FieldType.string,
editor: {
model: Editors.longText,
required: true,
validator: myCustomTitleValidator, // use a custom validator
},
onCellChange: (e: Event, args: OnEventArgs) => {
Expand Down Expand Up @@ -187,6 +188,7 @@ export class GridEditorComponent implements OnInit {
editor: {
// default is 0 decimals, if no decimals is passed it will accept 0 or more decimals
// however if you pass the "decimalPlaces", it will validate with that maximum
alwaysSaveOnEnterKey: true, // defaults to False, when set to true and user presses ENTER it will always call a Save even if value is empty
model: Editors.float,
minValue: 0,
maxValue: 365,
Expand Down Expand Up @@ -383,6 +385,7 @@ export class GridEditorComponent implements OnInit {
separatorBetweenTextLabels: ' '
},
model: Editors.multipleSelect,
required: true
},
filter: {
collectionAsync: this.http.get<{ value: string; label: string; }[]>(URL_SAMPLE_COLLECTION_DATA),
Expand Down Expand Up @@ -511,7 +514,7 @@ export class GridEditorComponent implements OnInit {
tempDataset.push({
id: i,
title: 'Task ' + i,
duration: Math.round(Math.random() * 100) + '',
duration: (i % 33 === 0) ? null : Math.round(Math.random() * 100) + '',
percentComplete: randomPercent,
percentCompleteNumber: randomPercent,
start: new Date(randomYear, randomMonth, randomDay),
Expand Down
4 changes: 4 additions & 0 deletions src/app/modules/angular-slickgrid/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ export class Constants {
static TEXT_SORT_DESCENDING = 'Sort Descending';
static TEXT_TOGGLE_FILTER_ROW = 'Toggle Filter Row';
static TEXT_TOGGLE_PRE_HEADER_ROW = 'Toggle Pre-Header Row';
static VALIDATION_REQUIRED_FIELD = 'Field is required';
static VALIDATION_EDITOR_VALID_NUMBER = 'Please enter a valid number';
static VALIDATION_EDITOR_VALID_INTEGER = 'Please enter a valid integer number';
static VALIDATION_EDITOR_INTEGER_BETWEEN = 'Please enter a valid integer number between {{minValue}} and {{maxValue}}';
static VALIDATION_EDITOR_INTEGER_MAX = 'Please enter a valid integer number that is lower than {{maxValue}}';
static VALIDATION_EDITOR_INTEGER_MIN = 'Please enter a valid integer number that is greater than {{minValue}}';
static VALIDATION_EDITOR_NUMBER_BETWEEN = 'Please enter a valid number between {{minValue}} and {{maxValue}}';
static VALIDATION_EDITOR_NUMBER_MAX = 'Please enter a valid number that is lower than {{maxValue}}';
static VALIDATION_EDITOR_NUMBER_MIN = 'Please enter a valid number that is greater than {{minValue}}';
Expand Down
48 changes: 37 additions & 11 deletions src/app/modules/angular-slickgrid/editors/autoCompleteEditor.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {
Column,
ColumnEditor,
Editor,
EditorValidator,
EditorValidatorOutput,
KeyCode,
CollectionCustomStructure,
FieldType
} from './../models/index';
import { Constants } from './../constants';

// using external non-typed js libraries
declare var $: any;
Expand All @@ -18,6 +20,7 @@ declare var $: any;
export class AutoCompleteEditor implements Editor {
private _currentValue: any;
private _defaultTextValue: string;
private _lastInputEvent: KeyboardEvent;
$input: any;

/** The property name for labels in the collection */
Expand All @@ -41,7 +44,7 @@ export class AutoCompleteEditor implements Editor {
}

/** Get Column Editor object */
get columnEditor(): any {
get columnEditor(): ColumnEditor {
return this.columnDef && this.columnDef.internalColumnEditor || {};
}

Expand All @@ -50,6 +53,10 @@ export class AutoCompleteEditor implements Editor {
return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor.customStructure;
}

get hasAutoCommitEdit() {
return this.args.grid.getOptions().autoCommitEdit;
}

/** Get the Validator function, can be passed in Editor property or Column Definition */
get validator(): EditorValidator {
return this.columnEditor.validator || this.columnDef.validator;
Expand All @@ -63,9 +70,10 @@ export class AutoCompleteEditor implements Editor {

this.$input = $(`<input type="text" class="autocomplete editor-text editor-${columnId}" placeholder="${placeholder}" />`)
.appendTo(this.args.container)
.on('keydown.nav', (e) => {
if (e.keyCode === KeyCode.LEFT || e.keyCode === KeyCode.RIGHT) {
e.stopImmediatePropagation();
.on('keydown.nav', (event: KeyboardEvent) => {
this._lastInputEvent = event;
if (event.keyCode === KeyCode.LEFT || event.keyCode === KeyCode.RIGHT) {
event.stopImmediatePropagation();
}
});

Expand Down Expand Up @@ -124,6 +132,14 @@ export class AutoCompleteEditor implements Editor {
this.$input.select();
}

save() {
if (this.hasAutoCommitEdit) {
this.args.grid.getEditorLock().commitCurrentEdit();
} else {
this.args.commitChanges();
}
}

serializeValue() {
// if user provided a custom structure, we need to reswap the properties
// we do this because autocomplete needed label/value pair which might not be what the user provided
Expand All @@ -141,20 +157,30 @@ export class AutoCompleteEditor implements Editor {
}

isValueChanged() {
const lastEvent = this._lastInputEvent && this._lastInputEvent.keyCode;
if (this.columnEditor && this.columnEditor.alwaysSaveOnEnterKey && lastEvent === KeyCode.ENTER) {
return true;
}
return (!(this.$input.val() === '' && this._defaultTextValue === null)) && (this.$input.val() !== this._defaultTextValue);
}

validate(): EditorValidatorOutput {
const isRequired = this.columnEditor.required;
const elmValue = this.$input && this.$input.val && this.$input.val();
const errorMsg = this.columnEditor.errorMessage;

if (this.validator) {
const value = this.$input && this.$input.val && this.$input.val();
const validationResults = this.validator(value, this.args);
if (!validationResults.valid) {
return validationResults;
}
return this.validator(elmValue, this.args);
}

// by default the editor is almost always valid (except when it's required but not provided)
if (isRequired && elmValue === '') {
return {
valid: false,
msg: errorMsg || Constants.VALIDATION_REQUIRED_FIELD
};
}

// by default the editor is always valid
// if user want it to be a required checkbox, he would have to provide his own validator
return {
valid: true,
msg: null
Expand Down
25 changes: 16 additions & 9 deletions src/app/modules/angular-slickgrid/editors/checkboxEditor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Column, Editor, EditorValidator, EditorValidatorOutput } from './../models/index';
import { Constants } from './../constants';
import { Column, ColumnEditor, Editor, EditorValidator, EditorValidatorOutput } from './../models/index';

// using external non-typed js libraries
declare var $: any;
Expand All @@ -21,7 +22,7 @@ export class CheckboxEditor implements Editor {
}

/** Get Column Editor object */
get columnEditor(): any {
get columnEditor(): ColumnEditor {
return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor || {};
}

Expand Down Expand Up @@ -84,16 +85,22 @@ export class CheckboxEditor implements Editor {
}

validate(): EditorValidatorOutput {
const isRequired = this.columnEditor.required;
const isChecked = this.$input && this.$input.prop && this.$input.prop('checked');
const errorMsg = this.columnEditor.errorMessage;

if (this.validator) {
const value = this.$input && this.$input.val && this.$input.val();
const validationResults = this.validator(value, this.args);
if (!validationResults.valid) {
return validationResults;
}
return this.validator(isChecked, this.args);
}

// by default the editor is almost always valid (except when it's required but not provided)
if (isRequired && !isChecked) {
return {
valid: false,
msg: errorMsg || Constants.VALIDATION_REQUIRED_FIELD
};
}

// by default the editor is always valid
// if user want it to be a required checkbox, he would have to provide his own validator
return {
valid: true,
msg: null
Expand Down
37 changes: 21 additions & 16 deletions src/app/modules/angular-slickgrid/editors/dateEditor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { mapFlatpickrDateFormatWithFieldType, mapMomentDateFormatWithFieldType } from './../services/utilities';
import { Column, Editor, EditorValidator, EditorValidatorOutput, FieldType, GridOption } from './../models/index';
import { TranslateService } from '@ngx-translate/core';
import { Constants } from './../constants';
import { mapFlatpickrDateFormatWithFieldType, mapMomentDateFormatWithFieldType } from './../services/utilities';
import { Column, ColumnEditor, Editor, EditorValidator, EditorValidatorOutput, FieldType, GridOption } from './../models/index';
import * as moment_ from 'moment-mini';
const moment = moment_; // patch to fix rollup "moment has no default export" issue, document here https://github.com/rollup/rollup/issues/670

Expand Down Expand Up @@ -29,7 +30,7 @@ export class DateEditor implements Editor {
}

/** Get Column Editor object */
get columnEditor(): any {
get columnEditor(): ColumnEditor {
return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor || {};
}

Expand Down Expand Up @@ -115,13 +116,10 @@ export class DateEditor implements Editor {

save() {
// autocommit will not focus the next editor
const validation = this.validate();
if (validation && validation.valid) {
if (this.args.grid.getOptions().autoCommitEdit) {
this.args.grid.getEditorLock().commitCurrentEdit();
} else {
this.args.commitChanges();
}
if (this.args.grid.getOptions().autoCommitEdit) {
this.args.grid.getEditorLock().commitCurrentEdit();
} else {
this.args.commitChanges();
}
}

Expand Down Expand Up @@ -161,16 +159,23 @@ export class DateEditor implements Editor {
}

validate(): EditorValidatorOutput {
const isRequired = this.columnEditor.required;
const elmValue = this.$input && this.$input.val && this.$input.val();
const errorMsg = this.columnEditor.errorMessage;

if (this.validator) {
const value = this.$input && this.$input.val && this.$input.val();
const validationResults = this.validator(value, this.args);
if (!validationResults.valid) {
return validationResults;
}
return this.validator(value, this.args);
}

// by default the editor is almost always valid (except when it's required but not provided)
if (isRequired && elmValue === '') {
return {
valid: false,
msg: errorMsg || Constants.VALIDATION_REQUIRED_FIELD
};
}

// by default the editor is always valid
// if user want it to be a required checkbox, he would have to provide his own validator
return {
valid: true,
msg: null
Expand Down
Loading