Skip to main content Skip to footer

Expanding FlexGrid Rows to Show Full Text in React

FlexGrid row expanded to show full text

Background:

When using Wijmo FlexGrid, some cells may contain long text values that are truncated because rows use a fixed height. In this scenario, users may need a way to expand only the row they are viewing, show the full wrapped text, and then collapse the row again.

FlexGrid does not require the Row Detail plugin for this specific use case. Row Detail is better when you need to show an additional detail panel below a row. For simply showing more text inside the existing cells, a lighter approach is to toggle the row’s wordWrap property and call autoSizeRow for the selected row.

The process involves adding a custom expand/collapse icon to the row header, checking whether the target cell content is overflowing, and resizing the row when the icon is clicked.

Steps to Complete:

  1. Install Wijmo packages.
  2. Import Wijmo styles.
  3. Create a FlexGrid with long text content.
  4. Add a row header template with expand/collapse icons.
  5. Handle icon clicks and toggle row word wrapping.
  6. Auto-size the selected row.

Getting Started:

Install Wijmo packages

Ensure the required Wijmo React packages are available in your project.

npm i @mescius/wijmo @mescius/wijmo.react.grid @mescius/wijmo.styles
  • @mescius/wijmo.react.grid includes the React wrapper for FlexGrid.
  • @mescius/wijmo includes the core Wijmo utilities.
  • @mescius/wijmo.styles includes the default Wijmo CSS.

 

Import Wijmo styles

This loads the default styling required by Wijmo controls.

import '@mescius/wijmo.styles/wijmo.css';
  • If this step is missed, the grid and built-in Wijmo glyph icons will not display correctly.

 

Create sample data

This creates a dataset where every other row contains a long description value.

function getData(count) {
  const countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
  const data = [];

  for (let i = 0; i < count; i++) {
    data.push({
      id: i,
      country: countries[i % countries.length],
      description:
        i % 2 === 0
          ? 'This is a long description for the countries, designed to overflow the cell text. This is a long description for the countries, designed to overflow the cell text.'
          : 'Description',
      active: i % 4 === 0,
    });
  }

  return data;
}
  • The description field is the target column.
  • Long descriptions will be truncated when the row height is fixed.
  • Short descriptions do not need an expand icon.

 

Create a FlexGrid with long text content

This creates the grid and binds it to data that includes a long text field. The description column contains text that may be too long to fit inside the default row height.

import React from 'react';
import { FlexGrid } from '@mescius/wijmo.react.grid';

const ExpandableRowsGrid = ({ data }) => {
  return (
    <FlexGrid itemsSource={data}>
      {/* Grid columns can be auto-generated, or you can define them manually */}
    </FlexGrid>
  );
};

export default ExpandableRowsGrid;

 

Add a row header template with expand/collapse icons

This adds a custom template to the row header. The template checks whether the target cell content is overflowing. If the row is collapsed and the text overflows, it shows a plus icon. If the row is expanded, it shows a minus icon.

import { FlexGrid, FlexGridCellTemplate } from '@mescius/wijmo.react.grid';

const rowHeaderTemplate = (ctx) => {
  const grid = ctx.row.grid;
  const row = ctx.row;
  const targetCols = ['description'];

  let isOverflow = false;

  for (let i = 0; i < targetCols.length; i++) {
    const col = grid.getColumn(targetCols[i]);

    if (col) {
      const cell = grid.cells.getCellElement(row.index, col.index);

      if (cell) {
        isOverflow = cell.scrollWidth > cell.clientWidth;
      }

      if (isOverflow) {
        break;
      }
    }
  }

  if (isOverflow && row.renderHeight <= grid.rows.defaultSize) {
    return <span className="row-btn wj-glyph-plus" title="Expand row"></span>;
  }

  if (row.renderHeight > grid.rows.defaultSize) {
    return <span className="row-btn wj-glyph-minus" title="Collapse row"></span>;
  }

  return null;
};

Use the template inside the grid:

<FlexGrid itemsSource={data}>
  <FlexGridCellTemplate
    cellType="RowHeader"
    template={rowHeaderTemplate}
    autoSizeRows={false}
  />
</FlexGrid>
  • The row header template checks whether the description cell is overflowing.
  • wj-glyph-plus displays the expand icon.
  • wj-glyph-minus displays the collapse icon.

 

Handle icon clicks and toggle row word wrapping

This listens for clicks inside the grid. When the user clicks the plus or minus icon in the row header, the code finds the clicked row and toggles its wordWrap property.

import * as wjCore from '@mescius/wijmo';

const initGrid = (grid) => {
  grid.rows.defaultSize = 26;

  grid.addEventListener(grid.hostElement, 'click', (e) => {
    const ht = grid.hitTest(e);
    const target = e.target;

    if (wjCore.hasClass(target, 'row-btn') && ht.panel === grid.rowHeaders) {
      const row = grid.rows[ht.row];

      row.wordWrap = row.renderHeight <= grid.rows.defaultSize;
    }
  });
};

Attach initGrid to the initialized event:

<FlexGrid
  itemsSource={data}
  initialized={initGrid}
>
  <FlexGridCellTemplate
    cellType="RowHeader"
    template={rowHeaderTemplate}
    autoSizeRows={false}
  />
</FlexGrid>
  • row.wordWrap controls whether text wraps inside the selected row.

 

Auto-size the selected row

Toggling wordWrap alone is not enough. The row also needs to be resized so the wrapped text can actually appear. This is where autoSizeRow comes in.

const initGrid = (grid) => {
  grid.rows.defaultSize = 26;

  grid.addEventListener(grid.hostElement, 'click', (e) => {
    const ht = grid.hitTest(e);
    const target = e.target;

    if (wjCore.hasClass(target, 'row-btn') && ht.panel === grid.rowHeaders) {
      const row = grid.rows[ht.row];

      row.wordWrap = row.renderHeight <= grid.rows.defaultSize;

      // Resize only the clicked row.
      grid.autoSizeRow(row.index);
    }
  });
};
  • grid.autoSizeRow(row.index) resizes only the clicked row.

 

With this React setup:

  • Long text rows show an expand icon in the row header.
  • Clicking the icon enables wrapping and auto-sizes that specific row.
  • Clicking again disables wrapping and collapses the row.
  • Rows without overflowing text do not show an icon.
  • The implementation avoids unnecessary row detail panels.

Happy coding!

Andrew Peterson

Technical Engagement Engineer