Skip to content

Counter Editor

The editorCounter is a custom cell editor for RevoGrid that provides plus and minus buttons to increment/decrement numeric values within a specified range directly within the grid cells.

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

defineCustomElements();

export function load(parentSelector: string) {
  const parent = document.querySelector(parentSelector);
  if (!parent) return;

  const grid = document.createElement('revo-grid');

  // Sample data
  const source = [
    { id: 1, quantity: 5, name: 'Product A' },
    { id: 2, quantity: 10, name: 'Product B' },
    { id: 3, quantity: 15, name: 'Product C' },
    { id: 4, quantity: 20, name: 'Product D' },
    { id: 5, quantity: 25, name: 'Product E' },
  ];

  // Column configuration
  const columns = [
    {
      prop: 'id',
      name: 'ID',
      readonly: true,
    },
    {
      prop: 'name',
      name: 'Product Name',
    },
    {
      prop: 'quantity',
      name: 'Quantity',
      readonly: true,
      cellTemplate: editorCounter,
      min: 0,
      max: 100,
      step: 5,
    },
  ];

  // Grid configuration
  grid.source = source;
  grid.columns = columns;
  const { isDark } = currentTheme();
  grid.theme = isDark() ? 'darkCompact' : 'compact';
  grid.resize = true;
  grid.hideAttribution = true;
  parent.appendChild(grid);
}
Vue vue
<template>
  <RevoGrid
    class="rounded-lg overflow-hidden cell-border"
    :columns="columns"
    :source="source"
    :theme="isDark ? 'darkMaterial' : 'material'"
    :plugins="[RowOddPlugin]"
    hide-attribution
    style="min-height: 300px;"
  />
</template>

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

const { isDark } = currentThemeVue();

const source = ref([
  { name: 'Product A', quantity: 5, stock: 100 },
  { name: 'Product B', quantity: 10, stock: 150 },
  { name: 'Product C', quantity: 15, stock: 200 },
  { name: 'Product D', quantity: 20, stock: 250 },
  { name: 'Product E', quantity: 25, stock: 300 },
]);

const columns: ColumnRegular[] = [
  { 
    prop: 'name',
    name: 'Product Name',
    size: 150,
  },
  {
    name: 'Q (0-50)',
    prop: 'quantity',
    size: 100,
    readonly: true,
    cellTemplate: editorCounter,
    min: 0,
    max: 50,
    step: 5,
  },
  {
    name: 'Q preview',
    prop: 'quantity',
    size: 100,
  },
];
</script>
React tsx
import React, { useMemo } from 'react';
import { RevoGrid, type ColumnRegular } from '@revolist/react-datagrid';
import { editorCounter } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';

const { isDark } = currentTheme();

function EditorCounter() {
  const source = [
    { name: 'Product A', quantity: 5, stock: 100 },
    { name: 'Product B', quantity: 10, stock: 150 },
    { name: 'Product C', quantity: 15, stock: 200 },
    { name: 'Product D', quantity: 20, stock: 250 },
    { name: 'Product E', quantity: 25, stock: 300 },
  ];

  const columns: ColumnRegular[] = useMemo(
    () => [
      { 
        prop: 'name',
        name: 'Product Name',
        size: 150,
        readonly: true
      },
      {
        name: 'Quantity (0-50)',
        prop: 'quantity',
        size: 200,
        readonly: true,
        cellTemplate: editorCounter,
        min: 0,
        max: 50,
        step: 5,
      },
      {
        name: 'Stock Level (0-500)',
        prop: 'stock',
        size: 200,
        readonly: true,
        cellTemplate: editorCounter,
        min: 0,
        max: 500,
        step: 50,
      },
    ],
    []
  );

  return (
    <div>
      <RevoGrid
        source={source}
        columns={columns}
        hideAttribution
        theme={isDark() ? 'darkCompact' : 'compact'}
        style={{ height: '400px' }}
      />
    </div>
  );
}

export default EditorCounter; 
Angular ts
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import { editorCounter } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';

@Component({
  selector: 'editor-counter-grid',
  standalone: true,
  imports: [RevoGrid],
  template: `
    <revo-grid
      [source]="source"
      [columns]="columns"
      [theme]="theme"
      [hideAttribution]="true"
      style="min-height: 400px;"
    ></revo-grid>
  `,
  encapsulation: ViewEncapsulation.None,
})
export class EditorCounterGridComponent implements OnInit {
  source = [
    { name: 'Product A', quantity: 5, stock: 100 },
    { name: 'Product B', quantity: 10, stock: 150 },
    { name: 'Product C', quantity: 15, stock: 200 },
    { name: 'Product D', quantity: 20, stock: 250 },
    { name: 'Product E', quantity: 25, stock: 300 },
  ];

  columns = [
    { 
      prop: 'name',
      name: 'Product Name',
      size: 150,
      readonly: true
    },
    {
      name: 'Quantity (0-50)',
      prop: 'quantity',
      size: 200,
      readonly: true,
      cellTemplate: editorCounter,
      min: 0,
      max: 50,
      step: 5,
    },
    {
      name: 'Stock Level (0-500)',
      prop: 'stock',
      size: 200,
      readonly: true,
      cellTemplate: editorCounter,
      min: 0,
      max: 500,
      step: 50,
    },
  ];

  theme = currentTheme().isDark() ? 'darkCompact' : 'compact';

  ngOnInit() {
    // Any additional initialization logic
  }
} 

Features:

  • Renders plus and minus buttons for easy value adjustment
  • Supports customizable minimum and maximum values through column properties
  • Configurable step size for increments/decrements
  • Shows current value with optional display toggle
  • Automatically dispatches a celledit event upon change
  • Seamless integration with RevoGrid’s data model
  • Modern, responsive design with customizable theming

Import the editorCounter and assign it to the cellTemplate property of a column in the RevoGrid:

import { editorCounter } from '@revolist/revogrid-pro'
grid.columns = [
{
prop: 'quantity',
name: 'Quantity',
cellTemplate: editorCounter,
min: 0, // Minimum value (default: 0)
max: 100, // Maximum value (default: 100)
step: 5, // Step size for increments/decrements (default: 1)
hideValue: false, // Set to true to hide the value display
},
];

The counter editor supports several configuration options through column properties:

  • min (number): The minimum allowed value (default: 0)
  • max (number): The maximum allowed value (default: 100)
  • step (number): The increment/decrement step size (default: 1)
  • hideValue (boolean): Whether to hide the numeric value display (default: false)

The counter editor dispatches a celledit event whenever the value changes. The event detail contains:

  • rgCol: The column index of the edited cell
  • rgRow: The row index of the edited cell
  • type: The type of the cell
  • prop: The property of the cell being edited
  • val: The new numeric value after the change
  • preventFocus: A flag to control grid focus behavior (default: true)
  1. Step Size: Choose a step size that makes sense for your data. For example:

    • Use 1 for integer values like quantities
    • Use 0.1 or 0.01 for decimal values like prices
    • Use 5 or 10 for larger ranges
  2. Value Range: Set appropriate min and max values to prevent invalid data:

    • For quantities: min = 0, max = maximum stock level
    • For percentages: min = 0, max = 100
    • For ratings: min = 1, max = 5 (or your rating scale)
  3. Visual Feedback: The editor provides visual feedback through:

    • Disabled buttons when at min/max values
    • Hover effects on buttons
    • Clear value display (unless hidden)
  4. Accessibility: The editor supports keyboard interaction:

    • Tab navigation between buttons
    • Button states clearly indicated through styling
    • Numeric value visible by default