Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit f2fbbfc

Browse files
Ghislain BeaulacGhislain Beaulac
authored andcommitted
fix(editors): not allow grid paste of invalid values, issue #171
- the Editors all have their own "validate()" method that verifies if the value is valid or not and we should also verify the values when pasting into the grid
1 parent 23cf70a commit f2fbbfc

File tree

10 files changed

+53
-39
lines changed

10 files changed

+53
-39
lines changed

src/app/examples/custom-inputEditor.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ export class CustomInputEditor implements Editor {
8787
}
8888

8989
applyValue(item: any, state: any) {
90-
item[this.args.column.field] = state;
90+
const validation = this.validate(state);
91+
item[this.args.column.field] = (validation && validation.valid) ? state : '';
9192
}
9293

9394
isValueChanged() {
@@ -109,9 +110,9 @@ export class CustomInputEditor implements Editor {
109110
}
110111
}
111112

112-
validate(): EditorValidatorOutput {
113+
validate(inputValue?: any): EditorValidatorOutput {
113114
if (this.validator) {
114-
const value = this.$input && this.$input.val && this.$input.val();
115+
const value = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();
115116
return this.validator(value, this.args);
116117
}
117118

src/app/modules/angular-slickgrid/editors/autoCompleteEditor.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ export class AutoCompleteEditor implements Editor {
185185

186186
// when it's a complex object, then pull the object name only, e.g.: "user.firstName" => "user"
187187
const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';
188-
item[fieldNameFromComplexObject || fieldName] = newValue;
188+
const validation = this.validate(newValue);
189+
item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? newValue : '';
189190
}
190191

191192
isValueChanged() {
@@ -196,9 +197,9 @@ export class AutoCompleteEditor implements Editor {
196197
return (!(this.$input.val() === '' && this._defaultTextValue === null)) && (this.$input.val() !== this._defaultTextValue);
197198
}
198199

199-
validate(): EditorValidatorOutput {
200+
validate(inputValue?: any): EditorValidatorOutput {
200201
const isRequired = this.columnEditor.required;
201-
const elmValue = this.$input && this.$input.val && this.$input.val();
202+
const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();
202203
const errorMsg = this.columnEditor.errorMessage;
203204

204205
if (this.validator) {

src/app/modules/angular-slickgrid/editors/checkboxEditor.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,17 @@ export class CheckboxEditor implements Editor {
8989
const fieldName = this.columnDef && this.columnDef.field;
9090
// when it's a complex object, then pull the object name only, e.g.: "user.firstName" => "user"
9191
const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';
92-
item[fieldNameFromComplexObject || fieldName] = state;
92+
const validation = this.validate(state);
93+
item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';
9394
}
9495

9596
isValueChanged() {
9697
return (this.serializeValue() !== this.defaultValue);
9798
}
9899

99-
validate(): EditorValidatorOutput {
100+
validate(inputValue?: any): EditorValidatorOutput {
100101
const isRequired = this.columnEditor.required;
101-
const isChecked = this.$input && this.$input.prop && this.$input.prop('checked');
102+
const isChecked = (inputValue !== undefined) ? inputValue : this.$input && this.$input.prop && this.$input.prop('checked');
102103
const errorMsg = this.columnEditor.errorMessage;
103104

104105
if (this.validator) {

src/app/modules/angular-slickgrid/editors/dateEditor.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ export class DateEditor implements Editor {
3535
return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor || {};
3636
}
3737

38+
/** Get Flatpickr options passed to the editor by the user */
39+
get editorOptions(): any {
40+
return this.columnEditor.editorOptions || {};
41+
}
42+
3843
/** Get the Validator function, can be passed in Editor property or Column Definition */
3944
get validator(): EditorValidator {
4045
return this.columnEditor.validator || this.columnDef.validator;
@@ -68,7 +73,7 @@ export class DateEditor implements Editor {
6873
};
6974

7075
// merge options with optional user's custom options
71-
const pickerMergedOptions = { ...pickerOptions, ...this.columnEditor.editorOptions };
76+
const pickerMergedOptions = { ...pickerOptions, ...this.editorOptions };
7277
const inputCssClasses = `.editor-text.editor-${columnId}.flatpickr`;
7378

7479
this.$input = $(`<input type="text" data-defaultDate="${this.defaultDate}" class="${inputCssClasses.replace(/\./g, ' ')}" placeholder="${placeholder}" title="${title}" />`);
@@ -178,21 +183,22 @@ export class DateEditor implements Editor {
178183

179184
// when it's a complex object, then pull the object name only, e.g.: "user.firstName" => "user"
180185
const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';
181-
item[fieldNameFromComplexObject || fieldName] = state ? moment(state, outputFormat).toDate() : '';
186+
const newValue = state ? moment(state, outputFormat).toDate() : '';
187+
const validation = this.validate(newValue);
188+
item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? newValue : '';
182189
}
183190

184191
isValueChanged() {
185192
return (!(this.$input.val() === '' && this.defaultDate == null)) && (this.$input.val() !== this.defaultDate);
186193
}
187194

188-
validate(): EditorValidatorOutput {
195+
validate(inputValue?: any): EditorValidatorOutput {
189196
const isRequired = this.columnEditor.required;
190-
const elmValue = this.$input && this.$input.val && this.$input.val();
197+
const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();
191198
const errorMsg = this.columnEditor.errorMessage;
192199

193200
if (this.validator) {
194-
const value = this.$input && this.$input.val && this.$input.val();
195-
return this.validator(value, this.args);
201+
return this.validator(elmValue, this.args);
196202
}
197203

198204
// by default the editor is almost always valid (except when it's required but not provided)

src/app/modules/angular-slickgrid/editors/floatEditor.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ export class FloatEditor implements Editor {
140140
const fieldName = this.columnDef && this.columnDef.field;
141141
// when it's a complex object, then pull the object name only, e.g.: "user.firstName" => "user"
142142
const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';
143-
item[fieldNameFromComplexObject || fieldName] = state;
143+
const validation = this.validate(state);
144+
item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';
144145
}
145146

146147
isValueChanged() {
@@ -163,8 +164,8 @@ export class FloatEditor implements Editor {
163164
}
164165
}
165166

166-
validate(): EditorValidatorOutput {
167-
const elmValue = this.$input.val();
167+
validate(inputValue?: any): EditorValidatorOutput {
168+
const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();
168169
const floatNumber = !isNaN(elmValue as number) ? parseFloat(elmValue) : null;
169170
const decPlaces = this.getDecimalPlaces();
170171
const isRequired = this.columnEditor.required;

src/app/modules/angular-slickgrid/editors/integerEditor.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ export class IntegerEditor implements Editor {
9999
const fieldName = this.columnDef && this.columnDef.field;
100100
// when it's a complex object, then pull the object name only, e.g.: "user.firstName" => "user"
101101
const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';
102-
item[fieldNameFromComplexObject || fieldName] = state;
102+
const validation = this.validate(state);
103+
item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';
103104
}
104105

105106
isValueChanged() {
@@ -124,8 +125,8 @@ export class IntegerEditor implements Editor {
124125
}
125126
}
126127

127-
validate(): EditorValidatorOutput {
128-
const elmValue = this.$input.val();
128+
validate(inputValue?: any): EditorValidatorOutput {
129+
const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();
129130
const intNumber = !isNaN(elmValue as number) ? parseInt(elmValue, 10) : null;
130131
const errorMsg = this.columnEditor.errorMessage;
131132
const isRequired = this.columnEditor.required;

src/app/modules/angular-slickgrid/editors/longTextEditor.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ export class LongTextEditor implements Editor {
168168
const fieldName = this.columnDef && this.columnDef.field;
169169
// when it's a complex object, then pull the object name only, e.g.: "user.firstName" => "user"
170170
const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';
171-
item[fieldNameFromComplexObject || fieldName] = state;
171+
const validation = this.validate(state);
172+
item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';
172173
}
173174

174175

@@ -189,14 +190,13 @@ export class LongTextEditor implements Editor {
189190
}
190191
}
191192

192-
validate(): EditorValidatorOutput {
193+
validate(inputValue?: any): EditorValidatorOutput {
193194
const isRequired = this.columnEditor.required;
194-
const elmValue = this.$textarea && this.$textarea.val && this.$textarea.val();
195+
const elmValue = (inputValue !== undefined) ? inputValue : this.$textarea && this.$textarea.val && this.$textarea.val();
195196
const errorMsg = this.columnEditor.errorMessage;
196197

197198
if (this.validator) {
198-
const value = this.$textarea && this.$textarea.val && this.$textarea.val();
199-
return this.validator(value, this.args);
199+
return this.validator(elmValue, this.args);
200200
}
201201

202202
// by default the editor is almost always valid (except when it's required but not provided)

src/app/modules/angular-slickgrid/editors/selectEditor.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -274,22 +274,23 @@ export class SelectEditor implements Editor {
274274
applyValue(item: any, state: any): void {
275275
const fieldName = this.columnDef && this.columnDef.field;
276276
const fieldType = this.columnDef && this.columnDef.type;
277-
let value = state;
277+
let newValue = state;
278278

279279
// when the provided user defined the column field type as a possible number then try parsing the state value as that
280280
if (fieldType === FieldType.number || fieldType === FieldType.integer || fieldType === FieldType.boolean) {
281-
value = parseFloat(state);
281+
newValue = parseFloat(state);
282282
}
283283

284284
// when set as a multiple selection, we can assume that the 3rd party lib multiple-select will return a CSV string
285285
// we need to re-split that into an array to be the same as the original column
286286
if (this.isMultipleSelect && typeof state === 'string' && state.indexOf(',') >= 0) {
287-
value = state.split(',');
287+
newValue = state.split(',');
288288
}
289289

290290
// when it's a complex object, then pull the object name only, e.g.: "user.firstName" => "user"
291291
const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';
292-
item[fieldNameFromComplexObject || fieldName] = value;
292+
const validation = this.validate(newValue);
293+
item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? newValue : '';
293294
}
294295

295296
destroy() {
@@ -365,13 +366,13 @@ export class SelectEditor implements Editor {
365366
return this.$editorElm.val() !== this.defaultValue;
366367
}
367368

368-
validate(): EditorValidatorOutput {
369+
validate(inputValue?: any): EditorValidatorOutput {
369370
const isRequired = this.columnEditor.required;
370-
const elmValue = this.$editorElm && this.$editorElm.val && this.$editorElm.val();
371+
const elmValue = (inputValue !== undefined) ? inputValue : this.$editorElm && this.$editorElm.val && this.$editorElm.val();
371372
const errorMsg = this.columnEditor.errorMessage;
372373

373374
if (this.validator) {
374-
const value = this.isMultipleSelect ? this.currentValues : this.currentValue;
375+
const value = (inputValue !== undefined) ? inputValue : (this.isMultipleSelect ? this.currentValues : this.currentValue);
375376
return this.validator(value, this.args);
376377
}
377378

src/app/modules/angular-slickgrid/editors/sliderEditor.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ export class SliderEditor implements Editor {
119119
const fieldName = this.columnDef && this.columnDef.field;
120120
// when it's a complex object, then pull the object name only, e.g.: "user.firstName" => "user"
121121
const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';
122-
item[fieldNameFromComplexObject || fieldName] = state;
122+
const validation = this.validate(state);
123+
item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';
123124
}
124125

125126
isValueChanged() {
@@ -131,8 +132,8 @@ export class SliderEditor implements Editor {
131132
return (!(elmValue === '' && this.defaultValue === null)) && (elmValue !== this.defaultValue);
132133
}
133134

134-
validate(): EditorValidatorOutput {
135-
const elmValue = this.$input.val();
135+
validate(inputValue?: any): EditorValidatorOutput {
136+
const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();
136137
const isRequired = this.columnEditor.required;
137138
const minValue = this.columnEditor.minValue;
138139
const maxValue = this.columnEditor.maxValue;

src/app/modules/angular-slickgrid/editors/textEditor.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ export class TextEditor implements Editor {
9999
const fieldName = this.columnDef && this.columnDef.field;
100100
// when it's a complex object, then pull the object name only, e.g.: "user.firstName" => "user"
101101
const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';
102-
item[fieldNameFromComplexObject || fieldName] = state;
102+
const validation = this.validate(state);
103+
item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';
103104
}
104105

105106
isValueChanged() {
@@ -121,9 +122,9 @@ export class TextEditor implements Editor {
121122
}
122123
}
123124

124-
validate(): EditorValidatorOutput {
125+
validate(inputValue?: any): EditorValidatorOutput {
125126
const isRequired = this.columnEditor.required;
126-
const elmValue = this.$input && this.$input.val && this.$input.val();
127+
const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();
127128
const errorMsg = this.columnEditor.errorMessage;
128129

129130
if (this.validator) {

0 commit comments

Comments
 (0)