Common Issues with React and Wijmo

  1. Official website: https://demo.mescius/wijmo/demos/Grid/Overview/react Avoid the Chinese URL, check for .cn in the suffix and remove it if present; this version lacks event triggers and APIs, and the components are incomplete.

  2. Chinese URL: (not recommended): https://demo.grapecity.com.cn/wijmo5/learningwijmo/#fZYKp

  3. API reference: Module wijmo.collections - Wijmo 5 Help (grapecity.com.cn) If you encounter issues during development and cannot find the API on the official site, the third URL is more useful, combined with the source code from node-modules.

Table of Contents

  1. After importing FlexGrid, to implement a single column click event, bind the event on initialized and then use selectionChanged, and process subsequant logic by checking rows and columns.
searchResult: {
  initialize: (grid: WjFlexGrid) => {
    grid.selectionChanged.addHandler((s, e) => {
      if (e.col === 3) {
        console.log('Executing click event', s, e);
      }
    });
  }
}
<FlexGrid
  initialized={action.searchResult.initialize}
/>

After binding the event, receive s, e.

  1. When setting up width auto-adaptation for FlexGrid, the auto-width setting does not take effect.

FlexGrid fails to apply auto-width settings using '*' or 'auto'. Investigating the source code, it is confirmed that these values are accepted. It is suspected that the lack of width setting prevents 'auto' from working. Adding an outer div with a defined width makes the auto-width effective.

columns.push({
  header: t('fileName'),
  binding: 'fileName',
  width: '*',
  minWidth: 100,
  align: 'left',
});
<div style={{ width: '800px' }}>
  <FlexGrid
    columns={state.columns}
  />
</div>
  1. Add evants to the icon column in FlexGrid.

Directly receive e: MouseEvent, where e.row.index refers to the clicked row and e.item refers to the clicked content.

searchResult: {
  columns: {
    reference: (e: MouseEvent) => {
      console.log('Clicked first column', e);
    },
    clear: (e: MouseEvent) => {
      console.log('Clicked second column', e);
    },
  },
}
columns.push({
  header: 'Icon',
  binding: 'field',
  width: 57,
  align: 'center',
  allowDragging: false,
  allowResizing: false,
  allowSorting: false,
  cellTemplate: makeAction({
    actions: [
      {
        iconName: 'Info',
        label: t('unknown'),
        click: columnsAction.reference,
      },
    ],
  }),
});

After adding, the click event throws an error. The issue is due to incomplete parameter passing. Change the signature to:

reference: (ctx: ICellTemplateContext, e: MouseEvent) => {
  console.log('Clicked first column', e, ctx);
},

Import ICellTemplateContext from '@grapecity/wijmo.grid'.

  1. When randering buttons in a loop, the click event is triggered multiple times.

Solution: Use arrow functions.

Reason: If onClick includes (), it executes the function immediately upon page load, leading to this result.

<1> If the event function does not require parameters, remove () <2> If parameters are needed, use arrow functions

<IconButton
  iconProps={{ iconName: 'Clear' }}
  style={{
    border: '1px solid #333333',
    color: 'red',
  }}
  onClick={() =>
    action.file.clear(index, file.id)
  }
/>
  1. Using a secondary-encapsulated pagination component for FlexGrid (not applicable for Biz-encapsulated ones)
<FlexGrid
  paginationProps={{
    totalCount: 222,
    pageSize: 10,
    onPageChange: action.searchResult.getData,
  }}
/>
getData: async (
  offset: number,
  criteria: SearchCriteria
) => {
  const fetchFileListData = action.searchResult.fetchData(
    offset,
    criteria
  );
  return fetchFileListData !== undefined ? fetchFileListData : [];
},
fetchData: (offset: number, criteria: SearchCriteria) => {
  console.log('Perform interface processing here', offset, criteria);
  return stateRef.current.tableItems;
},

Additionally, there is a styling issue: style={{ height: '100%' - 30px - 4px }} should be adjusted to 100-34.

Import { SearchCriteria } from '@biz-integral/biz-wijmo';

  1. Infinite scroll in FlexGrid only triggers once or not at all.

<1> Check if the height supports scrolling. If not, add max-height to the outer container. <2> Ensure data updates after the first trigger. Even if old data is used, update it to trigger again.

<FlexGrid
  infiniteScrollProps={{
    onNext: action.searchResult.render,
  }}
/>
render: async (offset: number) => {
  let results = [];
  results = [...(stateRef.current.tableItems || [])];
  return results;
},
  1. During shortcut key setup, an error occurs: [TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))]. Later, it was found to be a type error, but the cause of non-array types remains unclear.
useHotkeys(
  [
    ...props.extHotKeys!,
    // Clear
    {
      key: 'F9',
      method() {
        action.table.lineClear.execute();
        return false;
      },
    },
  ],
  hotKeyScope
);
useHotkeys(
  [
    ...(Array.isArray(props.extHotKeys!) ? props.extHotKeys! : []),
    // Clear
    {
      key: 'F9',
      method() {
        action.table.lineClear.execute();
        return false;
      },
    },
  ],
  hotKeyScope
);
  1. Columns in FlexGrid have different disable states based on conditions.
{
  ...defaultProps,
  header: t('button-edit'),
  binding: 'edit',
  width: 50,
  allowSorting: false,
  allowResizing: false,
  allowDragging: false,
  isReadOnly: true,
  cellTemplate: makeAction({
    actions: [
      {
        onCreate: (sender, ctx) => {
          sender.disabled = ctx.item.approvalFlag === '0' || ctx.item.approvalFlag === '1';
        },
        iconName: 'PageEdit',
        label: t('button-edit'),
        click: (ctx, e) => {
          context.overlay
            .open(OverlayLabelTypes.Progress, {
              zoneId: MY_MESSAGE_AREA_ZONE_ID,
            })
            .execute(async () => {
              const rowData: any = ctx.item;
              const response = { approve: '' };
              if (!response?.approve) {
                setState((prev) => ({
                  ...prev,
                }));
              }
            });
        },
      },
    ],
  }),
  align: 'center',
}

onCreate column setup

  1. After routing configuration, an error occurs: initialEntries.map is not a function at createMemoryHistory.

Fix by modifying APP.tsx:

<MemoryRouter
  initialEntries={
    AppParams.getSystemParameters()?.initialEntries ??
    props?.initialEntries ?? ['/jvFundsRequestSearch']
  }
/>
<MemoryRouter
  initialEntries={
    AppParams.getSystemParameters()?.initialEntries ??
    [props?.initialEntries ?? '/jvFundsRequestSearch']
  }
/>
  1. Remove row styles from FlexGrid.
<FlexGrid
  alternatingRowStep={0}
></FlexGrid>
  1. Apply specific styles to a single column in FlexGrid based on data conditions, along with individual disabled states.
initialize: (grid: WjFlexGrid) => {
  grid.itemFormatter = (panel, r, c, cell) => {
    if (stateRef.current.model) {
      for (let i = 0; i < stateRef.current.model?.length; i++) {
        if (stateRef.current.model[i].jvProjectNoName === '') {
          const allItems = grid.rows;
          allItems[i].isReadOnly = true;
          allItems[i].cssClass = 'cell-disabled';
          console.log(allItems[i], 'allItems[i]');
        }
      }
    }
    if (panel.cellType === CellType.Cell) {
      const column = grid.getColumn(c);
      const isReadOnly = column.isReadOnly;
      if (isReadOnly) {
        cell.classList.add('cell-disabled');
      }
    }
  };
};
  1. Hide content in disabled cells.
allItems[i].cssClass = 'cell-disabled special-cell-disabled'

.special-cell-disabled .wj-cell-check {
  display: none;
}
  1. In FlexGrid cells, input numbers are displayed as 【-】 if empty, and formatted with commas if numeric, right-aligned for numbers and centered for 【-】.
initialize: (grid: WjFlexGrid) => {
  grid.onBeginningEdit = (e) => {
    const cellData = grid.getCellData(e.row, e.col, false);
    let value;
    if (cellData !== undefined) {
      value = cellData.replace(/,/g, '');
    } else if (cellData === '-') {
      value = '';
    } else {
      value = '';
    }

    grid.setCellData(e.row, e.col, value);
    return true;
  };
  grid.onCellEditEnded = (e) => {
    const cellData = grid.getCellData(e.row, e.col, false);
    let value;
    if (cellData === '') {
      value = '-';
    } else {
      const number = parseFloat(cellData);
      if (isNaN(number)) {
        value = '-';
      } else {
        value = action.formatNumberWithCommas(cellData);
      }
    }
    grid.setCellData(e.row, e.col, value);
  };
  grid.itemFormatter = (panel, r, c, cell) => {
    if (panel.cellType === CellType.Cell) {
      const column = grid.getColumn(c);
      const isReadOnly = column.isReadOnly;
      if (isReadOnly) {
        cell.classList.add('cell-disabled');
      } else {
        const cellData = panel.getCellData(r, c, false);
        if (cellData === '-') {
          cell.style.textAlign = 'center';
        } else {
          cell.style.textAlign = 'right';
        }
      }
    }
  };
};
formatNumberWithCommas: (number: string) => {
  const numStr = number.toString();
  const parts = numStr.split('.');
  const integerPart = parts[0];
  const formattedIntegerPart = integerPart.replace(/(?=(\d{3})+(?!\d))/g, ',');
  return `${formattedIntegerPart}${parts.length > 1 ? '.' + parts[1] : ''}`;
};
  1. Custom header line break.
initialize: (grid: WjFlexGrid) => {
  grid.itemFormatter = (panel, r, c, cell) => {
    if (panel.cellType === CellType.ColumnHeader) {
      cell.innerHTML = 'header \n aaa';
      cell.innerText = 'header \n aaa';
    }
  };
};

Tags: React wijmo flexgrid issues technical

Posted on Sat, 06 Jun 2026 16:04:10 +0000 by gyoung