@slickgrid-universal/composite-editor-component 5.14.0 → 9.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/compositeEditor.factory.d.ts.map +1 -0
  2. package/dist/{esm/compositeEditor.factory.js → compositeEditor.factory.js} +5 -5
  3. package/dist/compositeEditor.factory.js.map +1 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/{types/slick-composite-editor.component.d.ts → slick-composite-editor.component.d.ts} +1 -1
  7. package/dist/slick-composite-editor.component.d.ts.map +1 -0
  8. package/dist/{esm/slick-composite-editor.component.js → slick-composite-editor.component.js} +6 -6
  9. package/dist/slick-composite-editor.component.js.map +1 -0
  10. package/package.json +10 -12
  11. package/src/compositeEditor.factory.ts +5 -5
  12. package/src/slick-composite-editor.component.ts +6 -6
  13. package/dist/cjs/compositeEditor.factory.js +0 -230
  14. package/dist/cjs/compositeEditor.factory.js.map +0 -1
  15. package/dist/cjs/index.js +0 -19
  16. package/dist/cjs/index.js.map +0 -1
  17. package/dist/cjs/slick-composite-editor.component.js +0 -928
  18. package/dist/cjs/slick-composite-editor.component.js.map +0 -1
  19. package/dist/esm/compositeEditor.factory.js.map +0 -1
  20. package/dist/esm/index.js.map +0 -1
  21. package/dist/esm/slick-composite-editor.component.js.map +0 -1
  22. package/dist/tsconfig.tsbuildinfo +0 -1
  23. package/dist/types/compositeEditor.factory.d.ts.map +0 -1
  24. package/dist/types/index.d.ts.map +0 -1
  25. package/dist/types/slick-composite-editor.component.d.ts.map +0 -1
  26. /package/dist/{types/compositeEditor.factory.d.ts → compositeEditor.factory.d.ts} +0 -0
  27. /package/dist/{types/index.d.ts → index.d.ts} +0 -0
  28. /package/dist/{esm/index.js → index.js} +0 -0
@@ -1,928 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SlickCompositeEditorComponent = void 0;
4
- const binding_1 = require("@slickgrid-universal/binding");
5
- const utils_1 = require("@slickgrid-universal/utils");
6
- const common_1 = require("@slickgrid-universal/common");
7
- const compositeEditor_factory_js_1 = require("./compositeEditor.factory.js");
8
- const DEFAULT_ON_ERROR = (error) => console.log(error.message);
9
- class SlickCompositeEditorComponent {
10
- get eventHandler() {
11
- return this._eventHandler;
12
- }
13
- get dataView() {
14
- return this.grid?.getData();
15
- }
16
- get dataViewLength() {
17
- return this.dataView.getLength();
18
- }
19
- get formValues() {
20
- return this._formValues;
21
- }
22
- get editors() {
23
- return this._editors;
24
- }
25
- set editors(editors) {
26
- this._editors = editors;
27
- }
28
- get gridOptions() {
29
- return this.grid?.getOptions();
30
- }
31
- constructor() {
32
- this._columnDefinitions = [];
33
- this._lastActiveRowNumber = -1;
34
- this._formValues = null;
35
- this.gridService = null;
36
- this._eventHandler = new common_1.SlickEventHandler();
37
- this._bindEventService = new binding_1.BindingEventService();
38
- }
39
- /**
40
- * initialize the Composite Editor by passing the SlickGrid object and the container service
41
- *
42
- * Note: we aren't using DI in the constructor simply to be as framework agnostic as possible,
43
- * we are simply using this init() function with a very basic container service to do the job
44
- */
45
- init(grid, containerService) {
46
- this.grid = grid;
47
- this.gridService = containerService.get('GridService');
48
- this.translaterService = containerService.get('TranslaterService');
49
- if (!this.gridService) {
50
- throw new Error('[Slickgrid-Universal] it seems that the GridService is not being loaded properly, make sure the Container Service is properly implemented.');
51
- }
52
- if (this.gridOptions.enableTranslate && (!this.translaterService || !this.translaterService.translate)) {
53
- throw new Error('[Slickgrid-Universal] requires a Translate Service to be installed and configured when the grid option "enableTranslate" is enabled.');
54
- }
55
- // get locales provided by user in forRoot or else use default English locales via the Constants
56
- this._locales = this.gridOptions?.locales ?? common_1.Constants.locales;
57
- }
58
- /** Dispose of the Component & unsubscribe all events */
59
- dispose() {
60
- this._eventHandler.unsubscribeAll();
61
- this._bindEventService.unbindAll();
62
- this._formValues = null;
63
- this.disposeComponent();
64
- }
65
- /** Dispose of the Component without unsubscribing any events */
66
- disposeComponent() {
67
- // protected _editorContainers!: Array<HTMLElement | null>;
68
- this._modalBodyTopValidationElm?.remove();
69
- this._modalSaveButtonElm?.remove();
70
- if (typeof this._modalElm?.remove === 'function') {
71
- this._modalElm.remove();
72
- // remove the body backdrop click listener, every other listeners will be dropped automatically since we destroy the component
73
- document.body.classList.remove('slick-modal-open');
74
- }
75
- this._editorContainers = [];
76
- }
77
- /**
78
- * Dynamically change value of an input from the Composite Editor form.
79
- *
80
- * NOTE: user might get an error thrown when trying to apply a value on a Composite Editor that was not found in the form,
81
- * but in some cases the user might still want the value to be applied to the formValues so that it will be sent to the save in final item data context
82
- * and when that happens, you can just skip that error so it won't throw.
83
- * @param {String | Column} columnIdOrDef - column id or column definition
84
- * @param {*} newValue - the new value
85
- * @param {Boolean} skipMissingEditorError - defaults to False, skipping the error when the Composite Editor was not found will allow to still apply the value into the formValues object
86
- * @param {Boolean} triggerOnCompositeEditorChange - defaults to True, will this change trigger a onCompositeEditorChange event?
87
- */
88
- changeFormInputValue(columnIdOrDef, newValue, skipMissingEditorError = false, triggerOnCompositeEditorChange = true) {
89
- const columnDef = this.getColumnByObjectOrId(columnIdOrDef);
90
- const columnId = typeof columnIdOrDef === 'string' ? columnIdOrDef : (columnDef?.id ?? '');
91
- const editor = this._editors?.[columnId];
92
- let outputValue = newValue;
93
- if (!editor && !skipMissingEditorError) {
94
- throw new Error(`Composite Editor with column id "${columnId}" not found.`);
95
- }
96
- if (typeof editor?.setValue === 'function' && Array.isArray(this._editorContainers)) {
97
- editor.setValue(newValue, true, triggerOnCompositeEditorChange);
98
- const editorContainerElm = this._editorContainers.find((editorElm) => editorElm.dataset.editorid === columnId);
99
- const excludeDisabledFieldFormValues = this.gridOptions?.compositeEditorOptions?.excludeDisabledFieldFormValues ?? false;
100
- if (!editor.disabled || (editor.disabled && !excludeDisabledFieldFormValues)) {
101
- editorContainerElm?.classList?.add('modified');
102
- }
103
- else {
104
- outputValue = '';
105
- editorContainerElm?.classList?.remove('modified');
106
- }
107
- // when the field is disabled, we will only allow a blank value anything else will be disregarded
108
- if (editor.disabled && (outputValue !== '' || outputValue !== null || outputValue !== undefined || outputValue !== 0)) {
109
- outputValue = '';
110
- }
111
- }
112
- // is the field a complex object, like "address.streetNumber"
113
- // we'll set assign the value as a complex object following the `field` dot notation
114
- const fieldName = columnDef?.field ?? '';
115
- if (columnDef && fieldName?.includes('.')) {
116
- // when it's a complex object, user could override the object path (where the editable object is located)
117
- // else we use the path provided in the Field Column Definition
118
- const objectPath = columnDef.editor?.complexObjectPath ?? fieldName ?? '';
119
- (0, utils_1.setDeepValue)(this._formValues ?? {}, objectPath, newValue);
120
- }
121
- else {
122
- this._formValues = { ...this._formValues, [columnId]: outputValue };
123
- }
124
- }
125
- /**
126
- * Dynamically update the `formValues` object directly without triggering the onCompositeEditorChange event.
127
- * The fact that this doesn't trigger an event, might not always be good though, in these cases you are probably better with using the changeFormInputValue() method
128
- * @param {String | Column} columnIdOrDef - column id or column definition
129
- * @param {*} newValue - the new value
130
- */
131
- changeFormValue(columnIdOrDef, newValue) {
132
- const columnDef = this.getColumnByObjectOrId(columnIdOrDef);
133
- const columnId = typeof columnIdOrDef === 'string' ? columnIdOrDef : (columnDef?.id ?? '');
134
- // is the field a complex object, like "address.streetNumber"
135
- // we'll set assign the value as a complex object following the `field` dot notation
136
- const fieldName = columnDef?.field ?? columnIdOrDef;
137
- if (fieldName?.includes('.')) {
138
- // when it's a complex object, user could override the object path (where the editable object is located)
139
- // else we use the path provided in the Field Column Definition
140
- const objectPath = columnDef?.editor?.complexObjectPath ?? fieldName ?? '';
141
- (0, utils_1.setDeepValue)(this._formValues, objectPath, newValue);
142
- }
143
- else {
144
- this._formValues = { ...this._formValues, [columnId]: newValue };
145
- }
146
- this._formValues = (0, utils_1.deepMerge)({}, this._itemDataContext, this._formValues);
147
- }
148
- /**
149
- * Dynamically change an Editor option of the Composite Editor form
150
- * For example, a use case could be to dynamically change the "minDate" of another Date Editor in the Composite Editor form.
151
- * @param {String} columnId - column id
152
- * @param {*} newValue - the new value
153
- */
154
- changeFormEditorOption(columnId, optionName, newOptionValue) {
155
- const editor = this._editors?.[columnId];
156
- // change an Editor option (not all Editors have that method, so make sure it exists before trying to call it)
157
- if (editor?.changeEditorOption) {
158
- editor.changeEditorOption(optionName, newOptionValue);
159
- }
160
- else {
161
- 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).`);
162
- }
163
- }
164
- /**
165
- * Disable (or enable) an input of the Composite Editor form
166
- * @param {String} columnId - column definition id
167
- * @param isDisabled - defaults to True, are we disabling the associated form input
168
- */
169
- disableFormInput(columnId, isDisabled = true) {
170
- const editor = this._editors?.[columnId];
171
- if (editor?.disable && Array.isArray(this._editorContainers)) {
172
- editor.disable(isDisabled);
173
- }
174
- }
175
- /** Entry point to initialize and open the Composite Editor modal window */
176
- openDetails(options) {
177
- const onError = options.onError ?? DEFAULT_ON_ERROR;
178
- const defaultOptions = {
179
- backdrop: 'static',
180
- showCloseButtonOutside: true,
181
- shouldClearRowSelectionAfterMassAction: true,
182
- viewColumnLayout: 'auto',
183
- modalType: 'edit',
184
- };
185
- try {
186
- if (!this.grid || (this.grid.getEditorLock().isActive() && !this.grid.getEditorLock().commitCurrentEdit())) {
187
- return null;
188
- }
189
- this._formValues = null; // make sure there's no leftover from previous change
190
- this._options = {
191
- ...defaultOptions,
192
- ...this.gridOptions.compositeEditorOptions,
193
- ...options,
194
- labels: { ...this.gridOptions.compositeEditorOptions?.labels, ...options?.labels },
195
- }; // merge default options with user options
196
- this._options.backdrop = options.backdrop !== undefined ? options.backdrop : 'static';
197
- const viewColumnLayout = this._options.viewColumnLayout || 1;
198
- const activeCell = this.grid.getActiveCell();
199
- const activeColIndex = activeCell?.cell ?? 0;
200
- const activeRow = activeCell?.row ?? 0;
201
- const gridUid = this.grid.getUID() || '';
202
- let headerTitle = options.headerTitle || '';
203
- // execute callback before creating the modal window (that is in short the first event in the lifecycle)
204
- if (typeof this._options.onBeforeOpen === 'function') {
205
- this._options.onBeforeOpen();
206
- }
207
- if (this.hasRowSelectionEnabled() && this._options.modalType === 'auto-mass' && this.grid.getSelectedRows) {
208
- const selectedRowsIndexes = this.grid.getSelectedRows() || [];
209
- if (selectedRowsIndexes.length > 0) {
210
- this._options.modalType = 'mass-selection';
211
- if (options?.headerTitleMassSelection) {
212
- headerTitle = options?.headerTitleMassSelection;
213
- }
214
- }
215
- else {
216
- this._options.modalType = 'mass-update';
217
- if (options?.headerTitleMassUpdate) {
218
- headerTitle = options?.headerTitleMassUpdate;
219
- }
220
- }
221
- }
222
- const modalType = this._options.modalType || 'edit';
223
- if (!this.gridOptions.editable) {
224
- onError({
225
- type: 'error',
226
- code: 'EDITABLE_GRID_REQUIRED',
227
- message: 'Your grid must be editable in order to use the Composite Editor Modal.',
228
- });
229
- return null;
230
- }
231
- else if (!this.gridOptions.enableCellNavigation) {
232
- onError({
233
- type: 'error',
234
- code: 'ENABLE_CELL_NAVIGATION_REQUIRED',
235
- message: 'Composite Editor requires the flag "enableCellNavigation" to be set to True in your Grid Options.',
236
- });
237
- return null;
238
- }
239
- else if (!this.gridOptions.enableAddRow && (modalType === 'clone' || modalType === 'create')) {
240
- onError({
241
- type: 'error',
242
- code: 'ENABLE_ADD_ROW_REQUIRED',
243
- message: 'Composite Editor requires the flag "enableAddRow" to be set to True in your Grid Options when cloning/creating a new item.',
244
- });
245
- return null;
246
- }
247
- else if (!activeCell && (modalType === 'clone' || modalType === 'edit')) {
248
- onError({ type: 'warning', code: 'NO_RECORD_FOUND', message: 'No records selected for edit or clone operation.' });
249
- return null;
250
- }
251
- else {
252
- const isWithMassChange = modalType === 'mass-update' || modalType === 'mass-selection';
253
- const dataContext = !isWithMassChange ? this.grid.getDataItem(activeRow) : {};
254
- this._originalDataContext = (0, utils_1.extend)(true, {}, dataContext);
255
- this._columnDefinitions = this.grid.getColumns();
256
- const selectedRowsIndexes = this.hasRowSelectionEnabled() ? this.grid.getSelectedRows() : [];
257
- const fullDatasetLength = this.dataView?.getItemCount() ?? 0;
258
- this._lastActiveRowNumber = activeRow;
259
- const dataContextIds = this.dataView.getAllSelectedIds();
260
- // focus on a first cell with an Editor (unless current cell already has an Editor then do nothing)
261
- // also when it's a "Create" modal, we'll scroll to the end of the grid
262
- const rowIndex = modalType === 'create' ? this.dataViewLength : activeRow;
263
- const hasFoundEditor = this.focusOnFirstColumnCellWithEditor(this._columnDefinitions, dataContext, activeColIndex, rowIndex, isWithMassChange);
264
- if (!hasFoundEditor) {
265
- return null;
266
- }
267
- if (modalType === 'edit' && !dataContext) {
268
- onError({ type: 'warning', code: 'ROW_NOT_EDITABLE', message: 'Current row is not editable.' });
269
- return null;
270
- }
271
- else if (modalType === 'mass-selection') {
272
- if (selectedRowsIndexes.length < 1) {
273
- onError({
274
- type: 'warning',
275
- code: 'ROW_SELECTION_REQUIRED',
276
- message: 'You must select some rows before trying to apply new value(s).',
277
- });
278
- return null;
279
- }
280
- }
281
- let modalColumns = [];
282
- if (isWithMassChange) {
283
- // when using Mass Update, we only care about the columns that have the "massUpdate: true", we disregard anything else
284
- modalColumns = this._columnDefinitions.filter((col) => col.editorClass && col.editor?.massUpdate === true);
285
- }
286
- else {
287
- modalColumns = this._columnDefinitions.filter((col) => col.editorClass);
288
- }
289
- // user could optionally show the form inputs in a specific order instead of using default column definitions order
290
- if (modalColumns.some((col) => col.editor?.compositeEditorFormOrder !== undefined)) {
291
- modalColumns.sort((col1, col2) => {
292
- const val1 = col1?.editor?.compositeEditorFormOrder ?? Infinity;
293
- const val2 = col2?.editor?.compositeEditorFormOrder ?? Infinity;
294
- return (0, common_1.numericSortComparer)(val1, val2, common_1.SortDirectionNumber.asc);
295
- });
296
- }
297
- // open the editor modal and we can also provide a header title with optional parsing pulled from the dataContext, via template {{ }}
298
- // for example {{title}} => display the item title, or even complex object works {{product.name}} => display item product name
299
- const parsedHeaderTitle = headerTitle.replace(/\{\{(.*?)\}\}/g, (_match, group) => (0, common_1.getDescendantProperty)(dataContext, group));
300
- const layoutColCount = viewColumnLayout === 'auto' ? this.autoCalculateLayoutColumnCount(modalColumns.length) : viewColumnLayout;
301
- this._modalElm = (0, common_1.createDomElement)('div', { className: `slick-editor-modal ${gridUid}` });
302
- const modalContentElm = (0, common_1.createDomElement)('div', { className: 'slick-editor-modal-content' });
303
- // add dark mode CSS class when enabled
304
- if (this.gridOptions?.darkMode) {
305
- modalContentElm.classList.add('slick-dark-mode');
306
- }
307
- if ((!isNaN(viewColumnLayout) && +viewColumnLayout > 1) || (viewColumnLayout === 'auto' && layoutColCount > 1)) {
308
- const splitClassName = layoutColCount === 2 ? 'split-view' : 'triple-split-view';
309
- modalContentElm.classList.add(splitClassName);
310
- }
311
- const modalHeaderTitleElm = (0, common_1.createDomElement)('div', { className: 'slick-editor-modal-title' });
312
- this.grid.applyHtmlCode(modalHeaderTitleElm, parsedHeaderTitle);
313
- const modalCloseButtonElm = (0, common_1.createDomElement)('button', {
314
- type: 'button',
315
- ariaLabel: 'Close',
316
- textContent: '×',
317
- className: 'close',
318
- dataset: { action: 'close' },
319
- });
320
- if (this._options.showCloseButtonOutside) {
321
- modalHeaderTitleElm?.classList?.add('outside');
322
- modalCloseButtonElm?.classList?.add('outside');
323
- }
324
- const modalHeaderElm = (0, common_1.createDomElement)('div', { ariaLabel: 'Close', className: 'slick-editor-modal-header' });
325
- modalHeaderElm.appendChild(modalHeaderTitleElm);
326
- modalHeaderElm.appendChild(modalCloseButtonElm);
327
- const modalBodyElm = (0, common_1.createDomElement)('div', { className: 'slick-editor-modal-body' });
328
- this._modalBodyTopValidationElm = (0, common_1.createDomElement)('div', { className: 'validation-summary', style: { display: 'none' } }, modalBodyElm);
329
- const modalFooterElm = (0, common_1.createDomElement)('div', { className: 'slick-editor-modal-footer' });
330
- const modalCancelButtonElm = (0, common_1.createDomElement)('button', {
331
- type: 'button',
332
- ariaLabel: this.getLabelText('cancelButton', 'TEXT_CANCEL', 'Cancel'),
333
- className: 'btn btn-cancel btn-default btn-sm',
334
- textContent: this.getLabelText('cancelButton', 'TEXT_CANCEL', 'Cancel'),
335
- dataset: { action: 'cancel' },
336
- });
337
- let leftFooterText = '';
338
- let saveButtonText = '';
339
- switch (modalType) {
340
- case 'clone':
341
- saveButtonText = this.getLabelText('cloneButton', 'TEXT_CLONE', 'Clone');
342
- break;
343
- case 'mass-update':
344
- const footerUnparsedText = this.getLabelText('massUpdateStatus', 'TEXT_ALL_X_RECORDS_SELECTED', 'All {{x}} records selected');
345
- leftFooterText = this.parseText(footerUnparsedText, { x: fullDatasetLength });
346
- saveButtonText = this.getLabelText('massUpdateButton', 'TEXT_APPLY_MASS_UPDATE', 'Mass Update');
347
- break;
348
- case 'mass-selection':
349
- const selectionUnparsedText = this.getLabelText('massSelectionStatus', 'TEXT_X_OF_Y_MASS_SELECTED', '{{x}} of {{y}} selected');
350
- leftFooterText = this.parseText(selectionUnparsedText, { x: dataContextIds.length, y: fullDatasetLength });
351
- saveButtonText = this.getLabelText('massSelectionButton', 'TEXT_APPLY_TO_SELECTION', 'Update Selection');
352
- break;
353
- default:
354
- saveButtonText = this.getLabelText('saveButton', 'TEXT_SAVE', 'Save');
355
- }
356
- const selectionCounterElm = (0, common_1.createDomElement)('div', { className: 'footer-status-text', textContent: leftFooterText });
357
- this._modalSaveButtonElm = (0, common_1.createDomElement)('button', {
358
- type: 'button',
359
- className: 'btn btn-save btn-primary btn-sm',
360
- ariaLabel: saveButtonText,
361
- textContent: saveButtonText,
362
- dataset: {
363
- action: modalType === 'create' || modalType === 'edit' ? 'save' : modalType,
364
- ariaLabel: saveButtonText,
365
- },
366
- });
367
- const footerContainerElm = (0, common_1.createDomElement)('div', { className: 'footer-buttons' });
368
- if (modalType === 'mass-update' || modalType === 'mass-selection') {
369
- modalFooterElm.appendChild(selectionCounterElm);
370
- }
371
- footerContainerElm.appendChild(modalCancelButtonElm);
372
- footerContainerElm.appendChild(this._modalSaveButtonElm);
373
- modalFooterElm.appendChild(footerContainerElm);
374
- modalContentElm.appendChild(modalHeaderElm);
375
- modalContentElm.appendChild(modalBodyElm);
376
- modalContentElm.appendChild(modalFooterElm);
377
- this._modalElm.appendChild(modalContentElm);
378
- for (const columnDef of modalColumns) {
379
- if (columnDef.editorClass) {
380
- const itemContainer = (0, common_1.createDomElement)('div', { className: `item-details-container editor-${columnDef.id}` });
381
- if (layoutColCount === 1) {
382
- itemContainer.classList.add('slick-col-medium-12');
383
- }
384
- else {
385
- itemContainer.classList.add('slick-col-medium-6', `slick-col-xlarge-${12 / layoutColCount}`);
386
- }
387
- const templateItemLabelElm = (0, common_1.createDomElement)('div', { className: `item-details-label editor-${columnDef.id}` });
388
- this.grid.applyHtmlCode(templateItemLabelElm, this.getColumnLabel(columnDef) || 'n/a');
389
- const templateItemEditorElm = (0, common_1.createDomElement)('div', {
390
- className: 'item-details-editor-container slick-cell',
391
- dataset: { editorid: `${columnDef.id}` },
392
- });
393
- const templateItemValidationElm = (0, common_1.createDomElement)('div', {
394
- className: `item-details-validation editor-${columnDef.id}`,
395
- });
396
- // optionally add a reset button beside each editor
397
- if (this._options?.showResetButtonOnEachEditor) {
398
- const editorResetButtonElm = this.createEditorResetButtonElement(`${columnDef.id}`);
399
- this._bindEventService.bind(editorResetButtonElm, 'click', this.handleResetInputValue.bind(this));
400
- templateItemLabelElm.appendChild(editorResetButtonElm);
401
- }
402
- itemContainer.appendChild(templateItemLabelElm);
403
- itemContainer.appendChild(templateItemEditorElm);
404
- itemContainer.appendChild(templateItemValidationElm);
405
- modalBodyElm.appendChild(itemContainer);
406
- }
407
- }
408
- // optionally add a form reset button
409
- if (this._options?.showFormResetButton) {
410
- const resetButtonContainerElm = this.createFormResetButtonElement();
411
- this._bindEventService.bind(resetButtonContainerElm, 'click', this.handleResetFormClicked.bind(this));
412
- modalBodyElm.appendChild(resetButtonContainerElm);
413
- }
414
- document.body.appendChild(this._modalElm);
415
- document.body.classList.add('slick-modal-open'); // add backdrop to body
416
- this._bindEventService.bind(document.body, 'click', this.handleBodyClicked.bind(this));
417
- // execute lifecycle callback after the modal window is created and rendered in the DOM
418
- if (typeof this._options.onRendered === 'function') {
419
- this._options.onRendered(this._modalElm);
420
- }
421
- this._editors = {};
422
- this._editorContainers = modalColumns.map((col) => modalBodyElm.querySelector(`[data-editorid='${col.id}']`)) || [];
423
- this._compositeOptions = {
424
- destroy: this.disposeComponent.bind(this),
425
- modalType,
426
- validationMsgPrefix: '* ',
427
- formValues: {},
428
- editors: this._editors,
429
- };
430
- const compositeEditor = new compositeEditor_factory_js_1.SlickCompositeEditor(modalColumns, this._editorContainers, this._compositeOptions);
431
- this.grid.editActiveCell(compositeEditor);
432
- // --
433
- // Add a few Event Handlers
434
- // keyboard, blur & button event handlers
435
- this._bindEventService.bind(modalCloseButtonElm, 'click', this.cancelEditing.bind(this));
436
- this._bindEventService.bind(modalCancelButtonElm, 'click', this.cancelEditing.bind(this));
437
- this._bindEventService.bind(this._modalSaveButtonElm, 'click', this.handleSaveClicked.bind(this));
438
- this._bindEventService.bind(this._modalElm, 'keydown', this.handleKeyDown.bind(this));
439
- this._bindEventService.bind(this._modalElm, 'focusout', this.validateCurrentEditor.bind(this));
440
- this._bindEventService.bind(this._modalElm, 'blur', this.validateCurrentEditor.bind(this));
441
- // when any of the input of the composite editor form changes, we'll add/remove a "modified" CSS className for styling purposes
442
- this._eventHandler.subscribe(this.grid.onCompositeEditorChange, this.handleOnCompositeEditorChange.bind(this));
443
- // when adding a new row to the grid, we need to invalidate that row and re-render the grid
444
- this._eventHandler.subscribe(this.grid.onAddNewRow, (_e, args) => {
445
- this._originalDataContext = this.insertNewItemInDataView(args.item); // this becomes the new data context
446
- });
447
- }
448
- return this;
449
- }
450
- catch (error) {
451
- this.dispose();
452
- const errorMsg = typeof error === 'string' ? error : (error?.message ?? error?.body?.message ?? '');
453
- const errorCode = typeof error === 'string' ? error : (error?.status ?? error?.body?.status ?? errorMsg);
454
- onError({ type: 'error', code: errorCode, message: errorMsg });
455
- return null;
456
- }
457
- }
458
- /** Cancel the Editing which will also close the modal window */
459
- async cancelEditing() {
460
- let confirmed = true;
461
- if (this.formValues && Object.keys(this.formValues).length > 0 && typeof this._options.onClose === 'function') {
462
- confirmed = await this._options.onClose();
463
- }
464
- if (confirmed) {
465
- this.grid.getEditController()?.cancelCurrentEdit();
466
- // cancel current edit is not enough when editing/cloning,
467
- // we also need to reset with the original item data context to undo/reset the entire row
468
- if (this._options?.modalType === 'edit' || this._options?.modalType === 'clone') {
469
- this.resetCurrentRowDataContext();
470
- }
471
- this.grid.setActiveRow(this._lastActiveRowNumber);
472
- this.dispose();
473
- }
474
- }
475
- /** Show a Validation Summary text (as a <div>) when a validation fails or simply hide it when there's no error */
476
- showValidationSummaryText(isShowing, errorMsg = '') {
477
- if (isShowing && errorMsg !== '') {
478
- this._modalBodyTopValidationElm.textContent = errorMsg;
479
- this._modalBodyTopValidationElm.style.display = 'block';
480
- this._modalBodyTopValidationElm.scrollIntoView?.();
481
- this._modalSaveButtonElm.disabled = false;
482
- this._modalSaveButtonElm.classList.remove('saving');
483
- }
484
- else {
485
- this._modalBodyTopValidationElm.style.display = 'none';
486
- this._modalBodyTopValidationElm.textContent = errorMsg;
487
- }
488
- }
489
- // --
490
- // protected methods
491
- // ----------------
492
- /** Apply Mass Update Changes (form values) to the entire dataset */
493
- applySaveMassUpdateChanges(formValues, _selection, applyToDataview = true) {
494
- // not applying to dataView means that we're doing a preview of dataset and we should use a deep copy of it instead of applying changes directly to it
495
- const data = applyToDataview ? this.dataView.getItems() : (0, utils_1.extend)(true, [], this.dataView.getItems());
496
- // from the "lastCompositeEditor" object that we kept as reference, it contains all the changes inside the "formValues" property
497
- // we can loop through these changes and apply them on the selected row indexes
498
- Object.keys(formValues).forEach((itemProp) => {
499
- if (itemProp in formValues) {
500
- data.forEach((dataContext) => {
501
- // prettier-ignore
502
- if (itemProp in formValues && (this._options?.validateMassUpdateChange === undefined || this._options.validateMassUpdateChange(itemProp, dataContext, formValues) !== false)) {
503
- dataContext[itemProp] = formValues[itemProp];
504
- }
505
- });
506
- }
507
- });
508
- // change the entire dataset with our updated dataset
509
- if (applyToDataview) {
510
- this.dataView.setItems(data, this.gridOptions.datasetIdPropertyName);
511
- this.grid.invalidate();
512
- }
513
- return data;
514
- }
515
- /** Apply Mass Changes to the Selected rows in the grid (form values) */
516
- applySaveMassSelectionChanges(formValues, selection, applyToDataview = true) {
517
- const selectedItemIds = selection?.dataContextIds ?? [];
518
- const selectedTmpItems = selectedItemIds.map((itemId) => this.dataView.getItemById(itemId));
519
- // not applying to dataView means that we're doing a preview of dataset and we should use a deep copy of it instead of applying changes directly to it
520
- const selectedItems = applyToDataview ? selectedTmpItems : (0, utils_1.extend)(true, [], selectedTmpItems);
521
- // from the "lastCompositeEditor" object that we kept as reference, it contains all the changes inside the "formValues" property
522
- // we can loop through these changes and apply them on the selected row indexes
523
- Object.keys(formValues).forEach((itemProp) => {
524
- if (itemProp in formValues) {
525
- selectedItems.forEach((dataContext) => {
526
- // prettier-ignore
527
- if (itemProp in formValues && (this._options?.validateMassUpdateChange === undefined || this._options.validateMassUpdateChange(itemProp, dataContext, formValues) !== false)) {
528
- dataContext[itemProp] = formValues[itemProp];
529
- }
530
- });
531
- }
532
- });
533
- // update all items in the grid with the grid service
534
- if (applyToDataview) {
535
- this.gridService?.updateItems(selectedItems);
536
- }
537
- return selectedItems;
538
- }
539
- /**
540
- * Auto-Calculate how many columns to display in the view layout (1, 2, or 3).
541
- * We'll display a 1 column layout for 8 or less Editors, 2 columns layout for less than 15 Editors or 3 columns when more than 15 Editors
542
- * @param {number} editorCount - how many Editors do we have in total
543
- * @returns {number} count - calculated column count (1, 2 or 3)
544
- */
545
- autoCalculateLayoutColumnCount(editorCount) {
546
- if (editorCount >= 15) {
547
- return 3;
548
- }
549
- else if (editorCount >= 8) {
550
- return 2;
551
- }
552
- return 1;
553
- }
554
- /**
555
- * Create a reset button for each editor and attach a button click handler
556
- * @param {String} columnId - column id
557
- * @returns {Object} - html button
558
- */
559
- createEditorResetButtonElement(columnId) {
560
- const resetButtonElm = (0, common_1.createDomElement)('button', {
561
- type: 'button',
562
- name: columnId,
563
- ariaLabel: 'Reset',
564
- title: this._options?.labels?.resetFormButton ?? 'Reset Form Input',
565
- className: 'btn btn-xs btn-editor-reset',
566
- });
567
- if (this._options?.resetEditorButtonCssClass) {
568
- const resetBtnClasses = (0, utils_1.classNameToList)(this._options?.resetEditorButtonCssClass);
569
- for (const cssClass of resetBtnClasses) {
570
- resetButtonElm.classList.add(cssClass);
571
- }
572
- }
573
- return resetButtonElm;
574
- }
575
- /**
576
- * Create a form reset button and attach a button click handler
577
- * @param {String} columnId - column id
578
- * @returns {Object} - html button
579
- */
580
- createFormResetButtonElement() {
581
- const resetButtonContainerElm = (0, common_1.createDomElement)('div', { className: 'reset-container' });
582
- const resetButtonElm = (0, common_1.createDomElement)('button', { type: 'button', className: 'btn btn-sm reset-form' }, resetButtonContainerElm);
583
- (0, common_1.createDomElement)('span', { className: this._options?.resetFormButtonIconCssClass ?? '' }, resetButtonElm);
584
- resetButtonElm.appendChild(document.createTextNode(' Reset Form'));
585
- return resetButtonContainerElm;
586
- }
587
- /**
588
- * Execute the onError callback when defined
589
- * or use the default onError callback which is to simply display the error in the console
590
- */
591
- executeOnError(error) {
592
- const onError = this._options?.onError ?? DEFAULT_ON_ERROR;
593
- onError(error);
594
- }
595
- /**
596
- * A simple and generic method to execute the "OnSave" callback if it's defined by the user OR else simply execute built-in apply changes callback.
597
- * This method deals with multiple callbacks as shown below
598
- * @param {Function} applyChangesCallback - first callback to apply the changes into the grid (this could be a user custom callback)
599
- * @param {Function} executePostCallback - second callback to execute right after the "onSave"
600
- * @param {Function} beforeClosingCallback - third and last callback to execute after Saving but just before closing the modal window
601
- * @param {Object} itemDataContext - item data context when modal type is (create/clone/edit)
602
- */
603
- async executeOnSave(applyChangesCallback, executePostCallback, beforeClosingCallback, itemDataContext) {
604
- try {
605
- this.showValidationSummaryText(false, '');
606
- const validationResults = this.validateCompositeEditors();
607
- if (validationResults.valid) {
608
- this._modalSaveButtonElm.classList.add('saving');
609
- this._modalSaveButtonElm.disabled = true;
610
- if (typeof this._options?.onSave === 'function') {
611
- const isMassChange = this._options.modalType === 'mass-update' || this._options.modalType === 'mass-selection';
612
- // apply the changes in the grid early when that option is enabled (that is before the await of `onSave`)
613
- let updatedDataset;
614
- if (isMassChange && this._options?.shouldPreviewMassChangeDataset) {
615
- updatedDataset = applyChangesCallback(this.formValues, this.getCurrentRowSelections(), false);
616
- }
617
- // call the custon onSave callback when defined and note that the item data context will only be filled for create/clone/edit
618
- const dataContextOrUpdatedDatasetPreview = isMassChange ? updatedDataset : itemDataContext;
619
- const successful = await this._options?.onSave(this.formValues, this.getCurrentRowSelections(), dataContextOrUpdatedDatasetPreview);
620
- if (successful) {
621
- // apply the changes in the grid (if it's not yet applied)
622
- applyChangesCallback(this.formValues, this.getCurrentRowSelections());
623
- // once we're done doing the mass update, we can cancel the current editor since we don't want to add any new row
624
- // that will also destroy/close the modal window
625
- executePostCallback();
626
- }
627
- }
628
- else {
629
- applyChangesCallback(this.formValues, this.getCurrentRowSelections());
630
- executePostCallback();
631
- }
632
- // run any function before closing the modal
633
- if (typeof beforeClosingCallback === 'function') {
634
- beforeClosingCallback();
635
- }
636
- // close the modal only when successful
637
- this.dispose();
638
- }
639
- }
640
- catch (error) {
641
- const errorMsg = typeof error === 'string' ? error : (error?.message ?? error?.body?.message ?? '');
642
- this.showValidationSummaryText(true, errorMsg);
643
- }
644
- }
645
- // For the Composite Editor to work, the current active cell must have an Editor (because it calls editActiveCell() and that only works with a cell with an Editor)
646
- // so if current active cell doesn't have an Editor, we'll find the first column with an Editor and focus on it (from left to right starting at index 0)
647
- focusOnFirstColumnCellWithEditor(columns, dataContext, columnIndex, rowIndex, isWithMassChange) {
648
- // make sure we're not trying to activate a cell outside of the grid, that can happen when using MassUpdate without `enableAddRow` flag enabled
649
- const activeCellIndex = isWithMassChange && !this.gridOptions.enableAddRow && rowIndex >= this.dataViewLength ? this.dataViewLength - 1 : rowIndex;
650
- let columnIndexWithEditor = columnIndex;
651
- const cellEditor = columns[columnIndex].editorClass;
652
- let activeEditorCellNode = this.grid.getCellNode(activeCellIndex, columnIndex);
653
- if (!cellEditor || !activeEditorCellNode || !this.getActiveCellEditor(activeCellIndex, columnIndex)) {
654
- columnIndexWithEditor = this.findNextAvailableEditorColumnIndex(columns, dataContext, rowIndex, isWithMassChange);
655
- if (columnIndexWithEditor === -1) {
656
- this.executeOnError({
657
- type: 'error',
658
- code: 'NO_EDITOR_FOUND',
659
- message: 'We could not find any Editor in your Column Definition',
660
- });
661
- return false;
662
- }
663
- else {
664
- this.grid.setActiveCell(activeCellIndex, columnIndexWithEditor, false);
665
- if (isWithMassChange) {
666
- // when it's a mass change, we'll activate the last row without scrolling to it
667
- // that is possible via the 3rd argument "suppressScrollIntoView" set to "true"
668
- this.grid.setActiveRow(this.dataViewLength, columnIndexWithEditor, true);
669
- }
670
- }
671
- }
672
- // check again if the cell node is now being created, if it is then we're good
673
- activeEditorCellNode = this.grid.getCellNode(activeCellIndex, columnIndexWithEditor);
674
- return !!activeEditorCellNode;
675
- }
676
- findNextAvailableEditorColumnIndex(columns, dataContext, rowIndex, isWithMassUpdate) {
677
- let columnIndexWithEditor = -1;
678
- for (let colIndex = 0; colIndex < columns.length; colIndex++) {
679
- const col = columns[colIndex];
680
- if (col.editorClass && (!isWithMassUpdate || (isWithMassUpdate && col.editor?.massUpdate))) {
681
- // we can check that the cell is really editable by checking the onBeforeEditCell event not returning false (returning undefined, null also mean it is editable)
682
- const isCellEditable = this.grid.onBeforeEditCell
683
- .notify({
684
- row: rowIndex,
685
- cell: colIndex,
686
- item: dataContext,
687
- column: col,
688
- grid: this.grid,
689
- target: 'composite',
690
- compositeEditorOptions: this._compositeOptions,
691
- })
692
- .getReturnValue();
693
- this.grid.setActiveCell(rowIndex, colIndex, false);
694
- if (isCellEditable !== false) {
695
- columnIndexWithEditor = colIndex;
696
- break;
697
- }
698
- }
699
- }
700
- return columnIndexWithEditor;
701
- }
702
- /**
703
- * Get a column definition by providing a column id OR a column definition.
704
- * If the input is a string, we'll assume it's a columnId and we'll simply search for the column in the column definitions list
705
- */
706
- getColumnByObjectOrId(columnIdOrDef) {
707
- let column;
708
- if (typeof columnIdOrDef === 'object') {
709
- column = columnIdOrDef;
710
- }
711
- else if (typeof columnIdOrDef === 'string') {
712
- column = this._columnDefinitions.find((col) => col.id === columnIdOrDef);
713
- }
714
- return column;
715
- }
716
- getActiveCellEditor(row, cell) {
717
- this.grid.setActiveCell(row, cell, false);
718
- return this.grid.getCellEditor();
719
- }
720
- /**
721
- * Get the column label, the label might have an optional "columnGroup" (or "columnGroupKey" which need to be translated)
722
- * @param {object} columnDef - column definition
723
- * @returns {string} label - column label
724
- */
725
- getColumnLabel(columnDef) {
726
- const columnGroupSeparator = this.gridOptions.columnGroupSeparator || ' - ';
727
- let columnName = columnDef.nameCompositeEditor || columnDef.name || '';
728
- let columnGroup = columnDef.columnGroup || '';
729
- if (this.gridOptions.enableTranslate && this.translaterService) {
730
- const translationKey = columnDef.nameCompositeEditorKey || columnDef.nameKey;
731
- if (translationKey) {
732
- columnName = this.translaterService.translate(translationKey);
733
- }
734
- if (columnDef.columnGroupKey && this.translaterService?.translate) {
735
- columnGroup = this.translaterService.translate(columnDef.columnGroupKey);
736
- }
737
- }
738
- const columnLabel = columnGroup ? `${columnGroup}${columnGroupSeparator}${columnName}` : columnName;
739
- return (0, utils_1.getHtmlStringOutput)(columnLabel, 'innerHTML');
740
- }
741
- /** Get the correct label text depending, if we use a Translater Service then translate the text when possible else use default text */
742
- getLabelText(labelProperty, localeText, defaultText) {
743
- const textLabels = { ...this.gridOptions.compositeEditorOptions?.labels, ...this._options?.labels };
744
- if (this.gridOptions?.enableTranslate &&
745
- this.translaterService?.translate &&
746
- textLabels.hasOwnProperty(`${labelProperty}Key`)) {
747
- const translationKey = textLabels[`${labelProperty}Key`];
748
- return this.translaterService.translate(translationKey || '');
749
- }
750
- return textLabels?.[labelProperty] ?? this._locales?.[localeText] ?? defaultText;
751
- }
752
- /** Retrieve the current selection of row indexes & data context Ids */
753
- getCurrentRowSelections() {
754
- const dataContextIds = this.dataView.getAllSelectedIds();
755
- const gridRowIndexes = this.dataView.mapIdsToRows(dataContextIds);
756
- return { gridRowIndexes, dataContextIds };
757
- }
758
- handleBodyClicked(event) {
759
- if (event.target?.classList?.contains('slick-editor-modal')) {
760
- if (this._options?.backdrop !== 'static') {
761
- this.dispose();
762
- }
763
- }
764
- }
765
- handleKeyDown(event) {
766
- if (event.code === 'Escape') {
767
- this.cancelEditing();
768
- event.stopPropagation();
769
- event.preventDefault();
770
- }
771
- else if (event.code === 'Tab') {
772
- this.validateCurrentEditor();
773
- }
774
- }
775
- handleResetInputValue(event) {
776
- const columnId = event.target.name;
777
- const editor = this._editors?.[columnId];
778
- if (typeof editor?.reset === 'function') {
779
- editor.reset();
780
- }
781
- delete this._formValues?.[columnId];
782
- }
783
- /** Callback which processes a Mass Update or Mass Selection Changes */
784
- async handleMassSaving(modalType, executePostCallback) {
785
- if (!this.formValues || Object.keys(this.formValues).length === 0) {
786
- this.executeOnError({ type: 'warning', code: 'NO_CHANGES_DETECTED', message: 'Sorry we could not detect any changes.' });
787
- }
788
- else {
789
- const applyCallbackFnName = modalType === 'mass-update' ? 'applySaveMassUpdateChanges' : 'applySaveMassSelectionChanges';
790
- this.executeOnSave(this[applyCallbackFnName].bind(this), executePostCallback.bind(this));
791
- }
792
- }
793
- /** Anytime an input of the Composite Editor form changes, we'll add/remove a "modified" CSS className for styling purposes */
794
- handleOnCompositeEditorChange(_e, args) {
795
- const columnId = args.column?.id ?? '';
796
- this._formValues = { ...this._formValues, ...args.formValues };
797
- const editor = this._editors?.[columnId];
798
- const isEditorValueTouched = editor?.isValueTouched?.() ?? editor?.isValueChanged?.() ?? false;
799
- this._itemDataContext = editor?.dataContext ?? {}; // keep reference of the item data context
800
- // add extra css styling to the composite editor input(s) that got modified
801
- const editorElm = this._modalElm.querySelector(`[data-editorid='${columnId}']`);
802
- if (editorElm?.classList) {
803
- if (isEditorValueTouched) {
804
- editorElm.classList.add('modified');
805
- }
806
- else {
807
- editorElm.classList.remove('modified');
808
- }
809
- }
810
- // after any input changes we'll re-validate all fields
811
- this.validateCompositeEditors();
812
- }
813
- /** Check wether the grid has the Row Selection enabled */
814
- hasRowSelectionEnabled() {
815
- const selectionModel = this.grid.getSelectionModel();
816
- const isRowSelectionEnabled = this.gridOptions.enableRowSelection || this.gridOptions.enableCheckboxSelector;
817
- return !!(isRowSelectionEnabled && selectionModel);
818
- }
819
- /** Reset Form button handler */
820
- handleResetFormClicked() {
821
- for (const columnId of Object.keys(this._editors)) {
822
- const editor = this._editors[columnId];
823
- if (editor?.reset) {
824
- editor.reset();
825
- }
826
- }
827
- this._formValues = (0, utils_1.emptyObject)(this._formValues);
828
- }
829
- /** switch case handler to determine which code to execute depending on the modal type */
830
- async handleSaveClicked() {
831
- const modalType = this._options?.modalType;
832
- switch (modalType) {
833
- case 'mass-update':
834
- this.handleMassSaving(modalType, () => {
835
- this.grid.getEditController()?.cancelCurrentEdit();
836
- this.grid.setActiveCell(0, 0, false);
837
- if (this._options.shouldClearRowSelectionAfterMassAction) {
838
- this.grid.setSelectedRows([]);
839
- }
840
- });
841
- break;
842
- case 'mass-selection':
843
- this.handleMassSaving(modalType, () => {
844
- this.grid.getEditController()?.cancelCurrentEdit();
845
- this.grid.setActiveRow(this._lastActiveRowNumber);
846
- if (this._options.shouldClearRowSelectionAfterMassAction) {
847
- this.grid.setSelectedRows([]);
848
- }
849
- });
850
- break;
851
- case 'clone':
852
- // the clone object will be a merge of the selected data context (original object) with the changed form values
853
- const clonedItemDataContext = { ...this._originalDataContext, ...this.formValues };
854
- // post save callback (before closing modal)
855
- const postSaveCloneCallback = () => {
856
- this.grid.getEditController()?.cancelCurrentEdit();
857
- this.grid.setActiveCell(0, 0, false);
858
- };
859
- // call the onSave execution and provide the item data context so that it's available to the user
860
- this.executeOnSave(this.insertNewItemInDataView.bind(this, clonedItemDataContext), postSaveCloneCallback, this.resetCurrentRowDataContext.bind(this), clonedItemDataContext);
861
- break;
862
- case 'create':
863
- case 'edit':
864
- default:
865
- // commit the changes into the grid
866
- // if it's a "create" then it will triggered the "onAddNewRow" event which will in term push it to the grid
867
- // while an "edit" will simply applies the changes directly on the same row
868
- let isFormValid = this.grid.getEditController()?.commitCurrentEdit();
869
- // if the user provided the "onSave" callback, let's execute it with the item data context
870
- if (isFormValid && typeof this._options?.onSave === 'function') {
871
- const itemDataContext = modalType === 'create'
872
- ? this._originalDataContext // the inserted item was previously assigned to this ref when "onAddNewRow" is triggered
873
- : this.grid.getDataItem(this._lastActiveRowNumber); // for clone, we can get item data context directly from DataView
874
- isFormValid = await this._options?.onSave(this.formValues, this.getCurrentRowSelections(), itemDataContext);
875
- }
876
- if (isFormValid) {
877
- this.dispose(); // when the form is valid, we can close the modal
878
- }
879
- break;
880
- }
881
- }
882
- /** Insert an item into the DataView or throw an error when finding duplicate id in the dataset */
883
- insertNewItemInDataView(item) {
884
- const fullDatasetLength = this.dataView?.getItemCount() || 0;
885
- const newId = this._options.insertNewId ?? fullDatasetLength + 1;
886
- item[this.gridOptions.datasetIdPropertyName || 'id'] = newId;
887
- if (!this.dataView.getItemById(newId)) {
888
- this.gridService?.addItem(item, this._options.insertOptions);
889
- }
890
- else {
891
- this.executeOnError({
892
- type: 'error',
893
- code: 'ITEM_ALREADY_EXIST',
894
- message: `The item object which you are trying to add already exist with the same Id:: ${newId}`,
895
- });
896
- }
897
- return item;
898
- }
899
- parseText(inputText, mappedArgs) {
900
- return inputText.replace(/\{\{(.*?)\}\}/g, (match, group) => {
901
- return mappedArgs[group] !== undefined ? mappedArgs[group] : match;
902
- });
903
- }
904
- /** Put back the current row to its original item data context using the DataView without triggering a change */
905
- resetCurrentRowDataContext() {
906
- const idPropName = this.gridOptions.datasetIdPropertyName || 'id';
907
- const dataView = this.grid.getData();
908
- dataView.updateItem(this._originalDataContext[idPropName], this._originalDataContext);
909
- }
910
- /** Validate all the Composite Editors that are defined in the form */
911
- validateCompositeEditors(targetElm) {
912
- let validationResults = { valid: true, msg: '' };
913
- const currentEditor = this.grid.getCellEditor();
914
- if (currentEditor) {
915
- validationResults = currentEditor.validate(targetElm);
916
- }
917
- return validationResults;
918
- }
919
- /** Validate the current cell editor */
920
- validateCurrentEditor() {
921
- const currentEditor = this.grid.getCellEditor();
922
- if (currentEditor?.validate) {
923
- currentEditor.validate();
924
- }
925
- }
926
- }
927
- exports.SlickCompositeEditorComponent = SlickCompositeEditorComponent;
928
- //# sourceMappingURL=slick-composite-editor.component.js.map