Skip to content

Row Editor

The RowEditPlugin is a custom plugin for RevoGrid that provides row-level editing capabilities, allowing users to edit entire rows inline with dedicated action buttons for saving or canceling changes.

Source code
TypeScript ts
import { defineCustomElements } from '@revolist/revogrid/loader';
import { RowEditPlugin, RowOddPlugin, editorRowActionColumn } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';

defineCustomElements();

const source = [
  { name: 'John Doe', age: 25, dateOfBirth: '1998-01-15' },
  { name: 'Jane Smith', age: 30, dateOfBirth: '1993-03-22' },
  { name: 'Jim Beam', age: 35, dateOfBirth: '1988-06-09' },
  { name: 'Anna Bell', age: 28, dateOfBirth: '1995-11-18' },
  { name: 'Chris Green', age: 41, dateOfBirth: '1982-04-03' },
  { name: 'Maria Stone', age: 33, dateOfBirth: '1990-08-27' },
  { name: 'Peter Brown', age: 46, dateOfBirth: '1977-12-12' },
  { name: 'Sofia Clark', age: 29, dateOfBirth: '1994-02-05' },
  { name: 'Leo Turner', age: 38, dateOfBirth: '1985-09-21' },
  { name: 'Nina White', age: 31, dateOfBirth: '1992-07-14' },
  { name: 'Mark Young', age: 44, dateOfBirth: '1979-10-30' },
  { name: 'Olivia Lane', age: 27, dateOfBirth: '1996-05-19' },
];

export function load(parentSelector: string) {
  const grid = document.createElement('revo-grid');
  grid.range = true;

  grid.columns = [
    { prop: 'name' },
    { prop: 'age' },
    { prop: 'dateOfBirth' },
    { prop: 'edit', ...editorRowActionColumn },
  ];

  grid.plugins = [RowEditPlugin, RowOddPlugin];

  const { isDark } = currentTheme();
  grid.theme = isDark() ? 'darkMaterial' : 'material';

  grid.hideAttribution = true;

  document.querySelector(parentSelector)?.appendChild(grid);
  grid.source = source;

  return () => grid.remove();
}
Vue vue
<template>
  <RevoGrid
    class="rounded-lg overflow-hidden cell-border"
    :plugins="plugins"
    :columns="columns"
    :source="source"
    :theme="isDark ? 'darkMaterial' : 'material'"
    :additional-data="additionalData"
    no-header
    style="min-height: 300px;"
    hide-attribution
  />
</template>

<script setup lang="ts">
import RevoGrid, { type ColumnRegular } from '@revolist/vue3-datagrid';
import {
  RowEditPlugin,
  editorRowActionColumn,
  avatarRenderer,
  ColumnStretchPlugin,
  RowOddPlugin,
  RowSelectPlugin,
} from '@revolist/revogrid-pro';
import { computed, ref } from 'vue';
import { currentThemeVue } from '../composables/useRandomData';

const { isDark } = currentThemeVue();

const source = ref([
  { avatar: 'https://i.pravatar.cc/300?img=1', name: 'John Doe', age: 25 },
  { avatar: 'https://i.pravatar.cc/300?img=2', name: 'Jane Smith', age: 30 },
  { avatar: 'https://i.pravatar.cc/300?img=3', name: 'Jim Beam', age: 35 },
  { avatar: 'https://i.pravatar.cc/300?img=4', name: 'Anna Bell', age: 28 },
  { avatar: 'https://i.pravatar.cc/300?img=5', name: 'Chris Green', age: 41 },
  { avatar: 'https://i.pravatar.cc/300?img=6', name: 'Maria Stone', age: 33 },
  { avatar: 'https://i.pravatar.cc/300?img=7', name: 'Peter Brown', age: 46 },
  { avatar: 'https://i.pravatar.cc/300?img=8', name: 'Sofia Clark', age: 29 },
  { avatar: 'https://i.pravatar.cc/300?img=9', name: 'Leo Turner', age: 38 },
  { avatar: 'https://i.pravatar.cc/300?img=10', name: 'Nina White', age: 31 },
  { avatar: 'https://i.pravatar.cc/300?img=11', name: 'Mark Young', age: 44 },
  { avatar: 'https://i.pravatar.cc/300?img=12', name: 'Olivia Lane', age: 27 },
]);

const plugins = [RowEditPlugin, ColumnStretchPlugin, RowOddPlugin, RowSelectPlugin];
const additionalData = computed(() => ({
  stretch: 'all',
}));

const columns: ColumnRegular[] = [
  { prop: 'avatar', readonly: true, size: 60, cellTemplate: avatarRenderer, rectangular: true },
  { prop: 'name' },
  { prop: 'age' },
  { prop: 'edit', ...editorRowActionColumn },
];
</script>
React tsx
import React, { useMemo } from 'react';
import { RevoGrid, type ColumnRegular } from '@revolist/react-datagrid';
import { RowEditPlugin, RowOddPlugin, editorRowActionColumn } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';

const { isDark } = currentTheme();

const editorRows = [
  { name: 'John Doe', age: 25, dateOfBirth: '1998-01-15' },
  { name: 'Jane Smith', age: 30, dateOfBirth: '1993-03-22' },
  { name: 'Jim Beam', age: 35, dateOfBirth: '1988-06-09' },
  { name: 'Anna Bell', age: 28, dateOfBirth: '1995-11-18' },
  { name: 'Chris Green', age: 41, dateOfBirth: '1982-04-03' },
  { name: 'Maria Stone', age: 33, dateOfBirth: '1990-08-27' },
  { name: 'Peter Brown', age: 46, dateOfBirth: '1977-12-12' },
  { name: 'Sofia Clark', age: 29, dateOfBirth: '1994-02-05' },
  { name: 'Leo Turner', age: 38, dateOfBirth: '1985-09-21' },
  { name: 'Nina White', age: 31, dateOfBirth: '1992-07-14' },
  { name: 'Mark Young', age: 44, dateOfBirth: '1979-10-30' },
  { name: 'Olivia Lane', age: 27, dateOfBirth: '1996-05-19' },
];

function EditorRow() {
  const source = useMemo(() => editorRows, []);

  const plugins = useMemo(() => [RowEditPlugin, RowOddPlugin], []);

  const columns: ColumnRegular[] = useMemo(
    () => [
      { prop: 'name' },
      { prop: 'age' },
      { prop: 'dateOfBirth' },
      { prop: 'edit', ...editorRowActionColumn },
    ],
    []
  );

  return (
    <div>
      <RevoGrid
        source={source}
        columns={columns}
        plugins={plugins}
        hideAttribution
        theme={isDark() ? 'darkMaterial' : 'material'}
      />
    </div>
  );
}

export default EditorRow;
Angular ts
import { Component, ViewEncapsulation } from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import { RowEditPlugin, RowOddPlugin, editorRowActionColumn } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';

@Component({
  selector: 'editor-row-grid',
  standalone: true,
  imports: [RevoGrid],
  template: `
    <revo-grid
      [source]="source"
      [columns]="columns"
      [plugins]="plugins"
      [theme]="theme"
      [hideAttribution]="true"
      style="min-height: 400px;"
    ></revo-grid>
  `,
  encapsulation: ViewEncapsulation.None,
})
export class EditorRowGridComponent {
  source = [
    { name: 'John Doe', age: 25, dateOfBirth: '1998-01-15' },
    { name: 'Jane Smith', age: 30, dateOfBirth: '1993-03-22' },
    { name: 'Jim Beam', age: 35, dateOfBirth: '1988-06-09' },
    { name: 'Anna Bell', age: 28, dateOfBirth: '1995-11-18' },
    { name: 'Chris Green', age: 41, dateOfBirth: '1982-04-03' },
    { name: 'Maria Stone', age: 33, dateOfBirth: '1990-08-27' },
    { name: 'Peter Brown', age: 46, dateOfBirth: '1977-12-12' },
    { name: 'Sofia Clark', age: 29, dateOfBirth: '1994-02-05' },
    { name: 'Leo Turner', age: 38, dateOfBirth: '1985-09-21' },
    { name: 'Nina White', age: 31, dateOfBirth: '1992-07-14' },
    { name: 'Mark Young', age: 44, dateOfBirth: '1979-10-30' },
    { name: 'Olivia Lane', age: 27, dateOfBirth: '1996-05-19' },
  ];

  columns = [
    { prop: 'name' },
    { prop: 'age' },
    { prop: 'dateOfBirth' },
    { prop: 'edit', ...editorRowActionColumn },
  ];

  plugins = [RowEditPlugin, RowOddPlugin];
  theme = currentTheme().isDark() ? 'darkMaterial' : 'material';
}
  • Features:
  • Row Editing Mode: Enables editing of entire rows by rendering editors for all cells in the selected row.
  • Inline Editors: Supports inline editing of multiple cells in a row simultaneously.
  • Action Buttons: Provides intuitive buttons for Save and Cancel actions:
    • Save: Dispatches CELL_EDIT_SAVE_EVENT to persist changes.
    • Cancel: Dispatches CELL_EDIT_CANCEL_EVENT to discard changes.
  • Event Handling: Listens for key events to manage row editing:
    • CELL_EDIT_EVENT: Initiates row editing mode.
    • CELL_EDIT_SAVE_EVENT: Saves edited data and updates the grid model.
    • CELL_EDIT_CANCEL_EVENT: Cancels editing and restores original data.
    • BEFORE_CELL_RENDER_EVENT: Ensures cells in the editing row render with editors.