0
# Cell Editing
1
2
Interactive editing capabilities with validation, custom editors, and edit state management for dynamic data modification.
3
4
## Capabilities
5
6
### Cell Editing Control
7
8
Methods for controlling cell editing behavior and state management.
9
10
```javascript { .api }
11
/**
12
* Start editing cell (added to CellComponent by Edit module)
13
*/
14
edit(): void;
15
16
/**
17
* Cancel current cell editing operation
18
*/
19
cancelEdit(): void;
20
21
/**
22
* Set cell value programmatically
23
* @param value - New value for cell
24
* @param mutate - Apply mutators during value setting
25
* @returns Promise resolving when value is set
26
*/
27
setValue(value: any, mutate?: boolean): Promise<void>;
28
29
/**
30
* Get current cell value
31
* @returns Current cell value
32
*/
33
getValue(): any;
34
35
/**
36
* Get previous cell value before current edit
37
* @returns Previous cell value
38
*/
39
getOldValue(): any;
40
41
/**
42
* Get original cell value from initial data load
43
* @returns Initial cell value
44
*/
45
getInitialValue(): any;
46
47
/**
48
* Check if cell has been edited since last data load
49
* @returns True if cell has been modified
50
*/
51
isEdited(): boolean;
52
53
/**
54
* Clear edited flag for cell
55
*/
56
clearEdited(): void;
57
58
/**
59
* Restore cell to previous value
60
*/
61
restoreOldValue(): void;
62
63
/**
64
* Restore cell to initial value from data load
65
*/
66
restoreInitialValue(): void;
67
```
68
69
**Usage Examples:**
70
71
```javascript
72
// Get cell and start editing
73
const cell = table.getRow(1).getCell("name");
74
cell.edit();
75
76
// Programmatic value changes
77
await cell.setValue("New Name");
78
console.log("Current:", cell.getValue());
79
console.log("Previous:", cell.getOldValue());
80
console.log("Original:", cell.getInitialValue());
81
82
// Edit state management
83
if (cell.isEdited()) {
84
console.log("Cell has been modified");
85
cell.restoreOldValue(); // Undo changes
86
}
87
88
// Cancel editing
89
cell.cancelEdit();
90
```
91
92
### Cell Navigation
93
94
Navigation methods for moving between editable cells during editing sessions.
95
96
```javascript { .api }
97
/**
98
* Navigate to previous editable cell
99
*/
100
navigatePrev(): void;
101
102
/**
103
* Navigate to next editable cell
104
*/
105
navigateNext(): void;
106
107
/**
108
* Navigate to cell to the left
109
*/
110
navigateLeft(): void;
111
112
/**
113
* Navigate to cell to the right
114
*/
115
navigateRight(): void;
116
117
/**
118
* Navigate to cell above
119
*/
120
navigateUp(): void;
121
122
/**
123
* Navigate to cell below
124
*/
125
navigateDown(): void;
126
```
127
128
**Usage Examples:**
129
130
```javascript
131
// Set up keyboard navigation
132
table.on("cellEdited", function(cell) {
133
// Auto-advance to next cell after edit
134
cell.navigateNext();
135
});
136
137
// Custom navigation logic
138
table.on("keyDown", function(e, cell) {
139
if (e.key === "Tab") {
140
e.preventDefault();
141
if (e.shiftKey) {
142
cell.navigatePrev();
143
} else {
144
cell.navigateNext();
145
}
146
}
147
});
148
```
149
150
## Editor Configuration
151
152
### Built-in Editors
153
154
Tabulator provides numerous built-in editors for different data types and input scenarios.
155
156
```javascript { .api }
157
interface EditorTypes {
158
/** Basic text input editor */
159
"input": {
160
/** Search functionality */
161
search?: boolean;
162
/** Input mask pattern */
163
mask?: string;
164
/** Select text on focus */
165
selectContents?: boolean;
166
/** Element attributes */
167
elementAttributes?: { [key: string]: string };
168
};
169
170
/** Multi-line text editor */
171
"textarea": {
172
/** Number of visible rows */
173
verticalNavigation?: "editor" | "table";
174
/** Element attributes */
175
elementAttributes?: { [key: string]: string };
176
};
177
178
/** Numeric input editor */
179
"number": {
180
/** Minimum value */
181
min?: number;
182
/** Maximum value */
183
max?: number;
184
/** Step increment */
185
step?: number;
186
/** Decimal places */
187
precision?: number;
188
/** Select text on focus */
189
selectContents?: boolean;
190
/** Vertical navigation */
191
verticalNavigation?: "editor" | "table";
192
};
193
194
/** Dropdown select editor */
195
"select": {
196
/** Option values */
197
values?: any[] | { [key: string]: string } | string;
198
/** Default empty option */
199
defaultValue?: any;
200
/** Clear button */
201
clearable?: boolean;
202
/** Allow filtering options */
203
searchable?: boolean;
204
/** Multiple selection */
205
multiselect?: boolean;
206
/** Max selections for multiselect */
207
maxSelections?: number;
208
};
209
210
/** Checkbox editor */
211
"tickCross": {
212
/** Value for checked state */
213
trueValue?: any;
214
/** Value for unchecked state */
215
falseValue?: any;
216
/** Allow indeterminate state */
217
tristate?: boolean;
218
/** Value for indeterminate state */
219
indeterminateValue?: any;
220
};
221
222
/** Date picker editor */
223
"date": {
224
/** Date format */
225
format?: string;
226
/** Minimum date */
227
min?: string;
228
/** Maximum date */
229
max?: string;
230
/** Vertical navigation */
231
verticalNavigation?: "editor" | "table";
232
};
233
234
/** Date and time picker editor */
235
"dateTime": {
236
/** DateTime format */
237
format?: string;
238
/** Minimum datetime */
239
min?: string;
240
/** Maximum datetime */
241
max?: string;
242
/** Time picker format */
243
timeFormat?: string;
244
/** Vertical navigation */
245
verticalNavigation?: "editor" | "table";
246
};
247
248
/** Time picker editor */
249
"time": {
250
/** Time format */
251
format?: string;
252
/** Vertical navigation */
253
verticalNavigation?: "editor" | "table";
254
};
255
256
/** Star rating editor */
257
"star": {
258
/** Number of stars */
259
stars?: number;
260
};
261
262
/** Range slider editor */
263
"range": {
264
/** Minimum value */
265
min?: number;
266
/** Maximum value */
267
max?: number;
268
/** Step increment */
269
step?: number;
270
};
271
}
272
```
273
274
### Custom Editors
275
276
Create custom editors for specialized input requirements.
277
278
```javascript { .api }
279
interface CustomEditor {
280
/**
281
* Create custom editor element
282
* @param cell - Cell component being edited
283
* @param onRendered - Callback when editor is rendered
284
* @param success - Callback to call with new value on successful edit
285
* @param cancel - Callback to call when edit is cancelled
286
* @param editorParams - Parameters from column definition
287
* @returns HTML element for the editor
288
*/
289
(
290
cell: CellComponent,
291
onRendered: (callback: Function) => void,
292
success: (value: any) => void,
293
cancel: (value: any) => void,
294
editorParams: any
295
): HTMLElement;
296
}
297
```
298
299
**Usage Examples:**
300
301
```javascript
302
// Column definitions with editors
303
const editableColumns = [
304
{
305
title: "Name",
306
field: "name",
307
editor: "input",
308
editorParams: {
309
search: true,
310
selectContents: true,
311
elementAttributes: { placeholder: "Enter full name" }
312
}
313
},
314
{
315
title: "Age",
316
field: "age",
317
editor: "number",
318
editorParams: {
319
min: 0,
320
max: 120,
321
step: 1,
322
selectContents: true
323
}
324
},
325
{
326
title: "Department",
327
field: "department",
328
editor: "select",
329
editorParams: {
330
values: {
331
"eng": "Engineering",
332
"sales": "Sales",
333
"marketing": "Marketing",
334
"hr": "Human Resources"
335
},
336
clearable: true,
337
searchable: true
338
}
339
},
340
{
341
title: "Active",
342
field: "active",
343
editor: "tickCross",
344
editorParams: {
345
trueValue: true,
346
falseValue: false
347
}
348
},
349
{
350
title: "Start Date",
351
field: "startDate",
352
editor: "date",
353
editorParams: {
354
format: "YYYY-MM-DD",
355
min: "2020-01-01",
356
max: "2030-12-31"
357
}
358
},
359
{
360
title: "Rating",
361
field: "rating",
362
editor: "star",
363
editorParams: {
364
stars: 5
365
}
366
}
367
];
368
369
// Custom color picker editor
370
function colorEditor(cell, onRendered, success, cancel, editorParams) {
371
const editor = document.createElement("input");
372
editor.type = "color";
373
editor.value = cell.getValue() || "#ffffff";
374
375
editor.style.padding = "3px";
376
editor.style.width = "100%";
377
editor.style.border = "1px solid #ccc";
378
379
onRendered(function() {
380
editor.focus();
381
});
382
383
editor.addEventListener("change", function() {
384
success(editor.value);
385
});
386
387
editor.addEventListener("blur", function() {
388
success(editor.value);
389
});
390
391
return editor;
392
}
393
394
// Use custom editor in column
395
{
396
title: "Color",
397
field: "color",
398
editor: colorEditor,
399
formatter: function(cell) {
400
const value = cell.getValue();
401
return `<div style="width: 20px; height: 20px; background-color: ${value}; border: 1px solid #ccc; display: inline-block;"></div> ${value}`;
402
}
403
}
404
```
405
406
## Edit Triggers and Behavior
407
408
### Edit Triggers
409
410
Configure when and how editing is initiated.
411
412
```javascript { .api }
413
interface EditTriggers {
414
/** Click to edit */
415
editTrigger?: "click" | "dblclick" | "focus";
416
/** Manual edit trigger only */
417
editTriggerManual?: boolean;
418
}
419
```
420
421
### Edit Validation
422
423
Validate cell values during editing with built-in and custom validators.
424
425
```javascript { .api }
426
interface ValidationConfig {
427
/** Validation rules */
428
validator?: string | Function | Array<string | Function>;
429
/** Custom validation function */
430
validationFunction?: (value: any, validators: any[]) => boolean | string;
431
}
432
433
// Built-in validators
434
type BuiltInValidators =
435
| "required" // Value must not be empty
436
| "unique" // Value must be unique in column
437
| "integer" // Must be integer
438
| "float" // Must be float/decimal
439
| "numeric" // Must be numeric
440
| "string" // Must be string
441
| `min:${number}` // Minimum value/length
442
| `max:${number}` // Maximum value/length
443
| `minLength:${number}` // Minimum string length
444
| `maxLength:${number}` // Maximum string length
445
| "email" // Valid email format
446
| "url" // Valid URL format
447
| `regex:${string}`; // Match regex pattern
448
```
449
450
**Usage Examples:**
451
452
```javascript
453
// Validation examples
454
const validatedColumns = [
455
{
456
title: "Email",
457
field: "email",
458
editor: "input",
459
validator: ["required", "email"]
460
},
461
{
462
title: "Age",
463
field: "age",
464
editor: "number",
465
validator: ["required", "integer", "min:0", "max:120"]
466
},
467
{
468
title: "Username",
469
field: "username",
470
editor: "input",
471
validator: ["required", "unique", "minLength:3", "maxLength:20", "regex:^[a-zA-Z0-9_]+$"]
472
},
473
{
474
title: "Password",
475
field: "password",
476
editor: "input",
477
editorParams: { elementAttributes: { type: "password" } },
478
validator: function(value) {
479
if (value.length < 8) return "Password must be at least 8 characters";
480
if (!/[A-Z]/.test(value)) return "Password must contain uppercase letter";
481
if (!/[0-9]/.test(value)) return "Password must contain number";
482
return true;
483
}
484
}
485
];
486
487
// Edit trigger configuration
488
const editableTable = new Tabulator("#editable-table", {
489
data: tableData,
490
columns: validatedColumns,
491
editTrigger: "dblclick", // Double-click to edit
492
validationMode: "highlight" // Highlight invalid cells
493
});
494
```
495
496
## Edit State Management
497
498
### Table-wide Edit Control
499
500
```javascript { .api }
501
// Enable/disable editing globally
502
table.on("tableBuilt", function() {
503
// Disable editing for specific conditions
504
if (user.role !== "admin") {
505
table.getColumns().forEach(column => {
506
column.updateDefinition({ editable: false });
507
});
508
}
509
});
510
511
// Conditional editing based on row data
512
const conditionalColumns = [
513
{
514
title: "Salary",
515
field: "salary",
516
editor: "number",
517
editable: function(cell) {
518
const rowData = cell.getRow().getData();
519
return rowData.role === "manager" || user.role === "admin";
520
}
521
}
522
];
523
```
524
525
### Edit History and Undo
526
527
```javascript { .api }
528
// Track edit history
529
const editHistory = [];
530
531
table.on("cellEdited", function(cell) {
532
editHistory.push({
533
row: cell.getRow().getIndex(),
534
field: cell.getField(),
535
oldValue: cell.getOldValue(),
536
newValue: cell.getValue(),
537
timestamp: new Date()
538
});
539
});
540
541
// Implement undo functionality
542
function undoLastEdit() {
543
if (editHistory.length > 0) {
544
const lastEdit = editHistory.pop();
545
const cell = table.getRow(lastEdit.row).getCell(lastEdit.field);
546
cell.setValue(lastEdit.oldValue);
547
}
548
}
549
```