or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cell-editing.mdclipboard.mdcolumn-management.mddata-management.mddata-sorting.mddata-trees.mdevent-system.mdfiltering-search.mdhistory-undo.mdimport-export.mdindex.mdpagination.mdrange-selection.mdrow-grouping.mdtable-construction.mdvalidation.md

cell-editing.mddocs/

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

```