Skip to content

Datetime Editor

Double-click a value to edit. Apply or Ctrl/Cmd+Enter saves the draft. Cancel, Escape or outside dismissal discards it. Read-only cells cannot open or commit an editor.

Source code
Vuevue
<template>
  <p>Double-click a value to edit. Apply saves; Cancel discards the draft.</p>
  <RevoGrid
    :source="source"
    :columns="columns"
    :plugins="plugins"
    :theme="isDark ? 'darkMaterial' : 'material'"
    style="height: 340px"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { currentThemeVue } from '../composables/useRandomData';
import RevoGrid from '@revolist/vue3-datagrid';
import { editorColumns, editorRows } from './editor-data';
const { isDark } = currentThemeVue();
const source = ref(editorRows());
const columns = editorColumns();
const plugins = [];
</script>
TypeScriptts
import { currentTheme } from '../composables/useRandomData';
import { defineCustomElements } from '@revolist/revogrid/loader';
import { editorColumns, editorRows } from './editor-data';
defineCustomElements();
export function load(parentSelector: string, rows = editorRows()) {
  const grid = document.createElement('revo-grid');
  grid.theme = currentTheme().isDark() ? 'darkMaterial' : 'material';
  grid.style.height = '340px';
  grid.columns = editorColumns();
  document.querySelector(parentSelector)?.append(grid);
  grid.source = rows;
  return () => grid.remove();
}
Reacttsx
import { currentTheme } from '../composables/useRandomData';
import { useMemo } from 'react';
import { RevoGrid } from '@revolist/react-datagrid';
import { editorColumns, editorRows } from './editor-data';
export default function EditorDatetime({ rows }: { rows?: any[] }) {
  const columns = useMemo(editorColumns, []);
  const fallback = useMemo(editorRows, []);
  const plugins = useMemo(() => [], []);
  return (
    <>
      <p>
        Double-click a value to edit. Apply saves; Cancel discards the draft.
      </p>
      <RevoGrid
        source={rows?.length ? rows : fallback}
        columns={columns}
        plugins={plugins}
        theme={currentTheme().isDark() ? 'darkMaterial' : 'material'}
        style={{ height: '340px' }}
      />
    </>
  );
}
Angularts
import { currentTheme } from '../composables/useRandomData';
import { Component, ViewEncapsulation } from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import { editorColumns, editorRows } from './editor-data';
@Component({
  selector: 'editor-datetime-grid',
  standalone: true,
  imports: [RevoGrid],
  encapsulation: ViewEncapsulation.None,
  template: `<p>
      Double-click a value to edit. Apply saves; Cancel discards the draft.
    </p>
    <revo-grid
      [source]="source"
      [columns]="columns"
      [plugins]="plugins"
      [theme]="theme"
      style="height:340px"
    ></revo-grid>`,
})
export class EditorDatetimeGridComponent {
  theme = currentTheme().isDark() ? 'darkMaterial' : 'material';
  source = editorRows();
  columns = editorColumns();
  plugins = [];
}
Editor configurationts
import type { ColumnRegular } from '@revolist/revogrid';
import { DateAndTimeEditor } from '@revolist/revogrid-pro';
export const editorRows = () => [
  {
    name: 'London booking',
    value: '2026-10-12T09:30:15.000Z',
    range: { from: '2026-10-12T09:00:00.000Z', to: '2026-10-15T17:30:00.000Z' },
  },
  { name: 'Optional booking', value: null, range: null },
];
export const editorColumns = (): ColumnRegular[] => [
  { prop: 'name', name: 'Booking', size: 190, readonly: true },
  {
    prop: 'value',
    name: 'Date and time · London',
    size: 290,
    editor: DateAndTimeEditor,
    dateEditor: {
      timeZone: 'Europe/London',
      precision: 'second',
      timeFormat: '24h',
      calendar: { locale: 'en-GB' },
    },
  },
  {
    prop: 'range',
    name: 'Date and time range · London',
    size: 360,
    editor: DateAndTimeEditor,
    dateEditor: {
      timeZone: 'Europe/London',
      selection: 'range',
      timeFormat: '24h',
      calendar: { numberOfMonths: 2, locale: 'en-GB' },
    },
    cellTemplate: (_h, { value }) =>
      value ? `${value.from} – ${value.to}` : '',
  },
];

The editor uses TemporalPicker from @revolist/ui/date-time, combining the original shared CalendarPicker with TimeControl. Range mode uses the same controls for both endpoints and forwards the configured calendar options.

Use DateAndTimeEditor, or DateTimeEditor with dateEditor.kind: 'datetime'. New values store ISO timestamps; ranges store { from, to } and expose independent dates and times for both endpoints.

Set timeZone to the application’s IANA zone. precision, timeFormat, timeStep, minTime and maxTime configure time entry; calendar forwards the shared calendar options. Nonexistent local times are rejected. An unchanged instant preserves its original fold and precision; newly entered repeated times use the shared earlier-instant rule. Existing Date, spreadsheet-date number and string formats remain preserved by adapters.

Gantt’s separate Start/Finish fields, inline date editors, Scheduler event/dispatch dialogs, Kanban date fields and calendar exceptions use the same control. Product adapters retain their scheduling commands and timezone policies.

Localize dateEditor.text, partial dateEditor.actions and dateEditor.calendar.translations for popup, time and calendar controls. Set the IANA timezone on dateEditor.timeZone or dateEditor.calendar.timeZone; the editor setting takes precedence for both display and commit. Date/time labels do not change stored timestamp precision.