CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tabulator-tables

Interactive table generation JavaScript library with sorting, filtering, editing, formatting, and extensive customization capabilities

Pending
Overview
Eval results
Files

cell-editing.mddocs/

Cell Editing

Interactive editing capabilities with validation, custom editors, and edit state management for dynamic data modification.

Capabilities

Cell Editing Control

Methods for controlling cell editing behavior and state management.

/**
 * Start editing cell (added to CellComponent by Edit module)
 */
edit(): void;

/**
 * Cancel current cell editing operation
 */
cancelEdit(): void;

/**
 * Set cell value programmatically
 * @param value - New value for cell
 * @param mutate - Apply mutators during value setting
 * @returns Promise resolving when value is set
 */
setValue(value: any, mutate?: boolean): Promise<void>;

/**
 * Get current cell value
 * @returns Current cell value
 */
getValue(): any;

/**
 * Get previous cell value before current edit
 * @returns Previous cell value
 */
getOldValue(): any;

/**
 * Get original cell value from initial data load
 * @returns Initial cell value
 */
getInitialValue(): any;

/**
 * Check if cell has been edited since last data load
 * @returns True if cell has been modified
 */
isEdited(): boolean;

/**
 * Clear edited flag for cell
 */
clearEdited(): void;

/**
 * Restore cell to previous value
 */
restoreOldValue(): void;

/**
 * Restore cell to initial value from data load
 */
restoreInitialValue(): void;

Usage Examples:

// Get cell and start editing
const cell = table.getRow(1).getCell("name");
cell.edit();

// Programmatic value changes
await cell.setValue("New Name");
console.log("Current:", cell.getValue());
console.log("Previous:", cell.getOldValue());
console.log("Original:", cell.getInitialValue());

// Edit state management
if (cell.isEdited()) {
  console.log("Cell has been modified");
  cell.restoreOldValue(); // Undo changes
}

// Cancel editing
cell.cancelEdit();

Cell Navigation

Navigation methods for moving between editable cells during editing sessions.

/**
 * Navigate to previous editable cell
 */
navigatePrev(): void;

/**
 * Navigate to next editable cell
 */
navigateNext(): void;

/**
 * Navigate to cell to the left
 */
navigateLeft(): void;

/**
 * Navigate to cell to the right
 */
navigateRight(): void;

/**
 * Navigate to cell above
 */
navigateUp(): void;

/**
 * Navigate to cell below
 */
navigateDown(): void;

Usage Examples:

// Set up keyboard navigation
table.on("cellEdited", function(cell) {
  // Auto-advance to next cell after edit
  cell.navigateNext();
});

// Custom navigation logic
table.on("keyDown", function(e, cell) {
  if (e.key === "Tab") {
    e.preventDefault();
    if (e.shiftKey) {
      cell.navigatePrev();
    } else {
      cell.navigateNext();
    }
  }
});

Editor Configuration

Built-in Editors

Tabulator provides numerous built-in editors for different data types and input scenarios.

interface EditorTypes {
  /** Basic text input editor */
  "input": {
    /** Search functionality */
    search?: boolean;
    /** Input mask pattern */
    mask?: string;
    /** Select text on focus */
    selectContents?: boolean;
    /** Element attributes */
    elementAttributes?: { [key: string]: string };
  };
  
  /** Multi-line text editor */
  "textarea": {
    /** Number of visible rows */
    verticalNavigation?: "editor" | "table";
    /** Element attributes */
    elementAttributes?: { [key: string]: string };
  };
  
  /** Numeric input editor */
  "number": {
    /** Minimum value */
    min?: number;
    /** Maximum value */
    max?: number;
    /** Step increment */
    step?: number;
    /** Decimal places */
    precision?: number;
    /** Select text on focus */
    selectContents?: boolean;
    /** Vertical navigation */
    verticalNavigation?: "editor" | "table";
  };
  
  /** Dropdown select editor */
  "select": {
    /** Option values */
    values?: any[] | { [key: string]: string } | string;
    /** Default empty option */
    defaultValue?: any;
    /** Clear button */
    clearable?: boolean;
    /** Allow filtering options */
    searchable?: boolean;
    /** Multiple selection */
    multiselect?: boolean;
    /** Max selections for multiselect */
    maxSelections?: number;
  };
  
  /** Checkbox editor */
  "tickCross": {
    /** Value for checked state */
    trueValue?: any;
    /** Value for unchecked state */
    falseValue?: any;
    /** Allow indeterminate state */
    tristate?: boolean;
    /** Value for indeterminate state */
    indeterminateValue?: any;
  };
  
  /** Date picker editor */
  "date": {
    /** Date format */
    format?: string;
    /** Minimum date */
    min?: string;
    /** Maximum date */
    max?: string;
    /** Vertical navigation */
    verticalNavigation?: "editor" | "table";
  };
  
  /** Date and time picker editor */
  "dateTime": {
    /** DateTime format */
    format?: string;
    /** Minimum datetime */
    min?: string;
    /** Maximum datetime */
    max?: string;
    /** Time picker format */
    timeFormat?: string;
    /** Vertical navigation */
    verticalNavigation?: "editor" | "table";
  };
  
  /** Time picker editor */
  "time": {
    /** Time format */
    format?: string;
    /** Vertical navigation */
    verticalNavigation?: "editor" | "table";
  };
  
  /** Star rating editor */
  "star": {
    /** Number of stars */
    stars?: number;
  };
  
  /** Range slider editor */
  "range": {
    /** Minimum value */
    min?: number;
    /** Maximum value */
    max?: number;
    /** Step increment */
    step?: number;
  };
}

Custom Editors

Create custom editors for specialized input requirements.

interface CustomEditor {
  /**
   * Create custom editor element
   * @param cell - Cell component being edited
   * @param onRendered - Callback when editor is rendered
   * @param success - Callback to call with new value on successful edit
   * @param cancel - Callback to call when edit is cancelled
   * @param editorParams - Parameters from column definition
   * @returns HTML element for the editor
   */
  (
    cell: CellComponent,
    onRendered: (callback: Function) => void,
    success: (value: any) => void,
    cancel: (value: any) => void,
    editorParams: any
  ): HTMLElement;
}

Usage Examples:

// Column definitions with editors
const editableColumns = [
  {
    title: "Name",
    field: "name",
    editor: "input",
    editorParams: {
      search: true,
      selectContents: true,
      elementAttributes: { placeholder: "Enter full name" }
    }
  },
  {
    title: "Age", 
    field: "age",
    editor: "number",
    editorParams: {
      min: 0,
      max: 120,
      step: 1,
      selectContents: true
    }
  },
  {
    title: "Department",
    field: "department", 
    editor: "select",
    editorParams: {
      values: {
        "eng": "Engineering",
        "sales": "Sales", 
        "marketing": "Marketing",
        "hr": "Human Resources"
      },
      clearable: true,
      searchable: true
    }
  },
  {
    title: "Active",
    field: "active",
    editor: "tickCross",
    editorParams: {
      trueValue: true,
      falseValue: false
    }
  },
  {
    title: "Start Date",
    field: "startDate",
    editor: "date",
    editorParams: {
      format: "YYYY-MM-DD",
      min: "2020-01-01",
      max: "2030-12-31"
    }
  },
  {
    title: "Rating",
    field: "rating",
    editor: "star",
    editorParams: {
      stars: 5
    }
  }
];

// Custom color picker editor
function colorEditor(cell, onRendered, success, cancel, editorParams) {
  const editor = document.createElement("input");
  editor.type = "color";
  editor.value = cell.getValue() || "#ffffff";
  
  editor.style.padding = "3px";
  editor.style.width = "100%";
  editor.style.border = "1px solid #ccc";
  
  onRendered(function() {
    editor.focus();
  });
  
  editor.addEventListener("change", function() {
    success(editor.value);
  });
  
  editor.addEventListener("blur", function() {
    success(editor.value);
  });
  
  return editor;
}

// Use custom editor in column
{
  title: "Color",
  field: "color",
  editor: colorEditor,
  formatter: function(cell) {
    const value = cell.getValue();
    return `<div style="width: 20px; height: 20px; background-color: ${value}; border: 1px solid #ccc; display: inline-block;"></div> ${value}`;
  }
}

Edit Triggers and Behavior

Edit Triggers

Configure when and how editing is initiated.

interface EditTriggers {
  /** Click to edit */
  editTrigger?: "click" | "dblclick" | "focus";
  /** Manual edit trigger only */
  editTriggerManual?: boolean;
}

Edit Validation

Validate cell values during editing with built-in and custom validators.

interface ValidationConfig {
  /** Validation rules */
  validator?: string | Function | Array<string | Function>;
  /** Custom validation function */
  validationFunction?: (value: any, validators: any[]) => boolean | string;
}

// Built-in validators
type BuiltInValidators = 
  | "required"           // Value must not be empty
  | "unique"            // Value must be unique in column
  | "integer"           // Must be integer
  | "float"             // Must be float/decimal
  | "numeric"           // Must be numeric
  | "string"            // Must be string
  | `min:${number}`     // Minimum value/length
  | `max:${number}`     // Maximum value/length  
  | `minLength:${number}` // Minimum string length
  | `maxLength:${number}` // Maximum string length
  | "email"             // Valid email format
  | "url"               // Valid URL format
  | `regex:${string}`;   // Match regex pattern

Usage Examples:

// Validation examples
const validatedColumns = [
  {
    title: "Email",
    field: "email",
    editor: "input",
    validator: ["required", "email"]
  },
  {
    title: "Age",
    field: "age", 
    editor: "number",
    validator: ["required", "integer", "min:0", "max:120"]
  },
  {
    title: "Username",
    field: "username",
    editor: "input", 
    validator: ["required", "unique", "minLength:3", "maxLength:20", "regex:^[a-zA-Z0-9_]+$"]
  },
  {
    title: "Password",
    field: "password",
    editor: "input",
    editorParams: { elementAttributes: { type: "password" } },
    validator: function(value) {
      if (value.length < 8) return "Password must be at least 8 characters";
      if (!/[A-Z]/.test(value)) return "Password must contain uppercase letter";
      if (!/[0-9]/.test(value)) return "Password must contain number";
      return true;
    }
  }
];

// Edit trigger configuration
const editableTable = new Tabulator("#editable-table", {
  data: tableData,
  columns: validatedColumns,
  editTrigger: "dblclick", // Double-click to edit
  validationMode: "highlight" // Highlight invalid cells
});

Edit State Management

Table-wide Edit Control

// Enable/disable editing globally
table.on("tableBuilt", function() {
  // Disable editing for specific conditions
  if (user.role !== "admin") {
    table.getColumns().forEach(column => {
      column.updateDefinition({ editable: false });
    });
  }
});

// Conditional editing based on row data
const conditionalColumns = [
  {
    title: "Salary",
    field: "salary",
    editor: "number",
    editable: function(cell) {
      const rowData = cell.getRow().getData();
      return rowData.role === "manager" || user.role === "admin";
    }
  }
];

Edit History and Undo

// Track edit history
const editHistory = [];

table.on("cellEdited", function(cell) {
  editHistory.push({
    row: cell.getRow().getIndex(),
    field: cell.getField(),
    oldValue: cell.getOldValue(),
    newValue: cell.getValue(),
    timestamp: new Date()
  });
});

// Implement undo functionality
function undoLastEdit() {
  if (editHistory.length > 0) {
    const lastEdit = editHistory.pop();
    const cell = table.getRow(lastEdit.row).getCell(lastEdit.field);
    cell.setValue(lastEdit.oldValue);
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-tabulator-tables

docs

cell-editing.md

clipboard.md

column-management.md

data-management.md

data-sorting.md

data-trees.md

event-system.md

filtering-search.md

history-undo.md

import-export.md

index.md

pagination.md

range-selection.md

row-grouping.md

table-construction.md

validation.md

tile.json