Telerik Forums
KendoReact Forum
0 answers
46 views

We are encountering an issue in our React application where the UI does not display the correct data in a grid component, even though the logged data is accurate. The issue persists when scrolling up and down in the grid.

Steps to Reproduce:

  1. Load the grid with paginated or virtualized data.
  2. Scroll down to load additional rows.
  3. Scroll back up to view previously rendered rows.
  4. Observe that the data displayed in the UI does not match the expected data.

Expected Behavior:

The UI should reflect the correct data for each row based on the logs and the data passed to the grid.

Observed Behavior:

  • The logged values for each grid cell (dataItem[field]) are correct.
  • However, the displayed data in the UI does not align with these logs.
  • This issue appears to occur when using the following custom cell rendering logic:
<GridColumn
field="columnNo"
title="columnNo"
width="100px"
cell={({ dataItem, field }) => {
// eslint-disable-next-line no-console
console.log('value: ', dataItem[field]);
return (
<td key={`row-${dataItem.id}`}>
<span itemProp={`columnNo${dataItem[field]}`}>
{dataItem[field]}
</span>
</td>
);
}}
/>

Troubleshooting Done:

  1. Data Validation: Logged the dataItem, field, and dataItem[field] values, all of which are correct.
  2. Key Prop: Verified that the key prop is used, though it may need adjustment.
  3. React State Updates: Ensured the data is updated correctly and is not stale.
  4. Grid Behavior: Temporarily removed custom cell rendering, but the issue persists with virtualization.
  5. DevTools Inspection: Confirmed that DOM elements and attributes do not align with expected values during scrolling.

Environment Details:

  • Frontend Framework: React 18.2
  • Grid Component: @progress/kendo-react-grid": "^4.14.1"
  • Browser: Version 131.0.6778.140 (Official Build) (arm64)
  • State Management: Redux
return (
<Wrapper itemProp="smart-table-selection">
{loaders?.isLoading && (
<>
<Loading className="floated" />
<LoadingMask />
</>
)}
<div ref={refKendoTable}>
<GridWrapper
className="react-kendo-table"
ref={kendoRef}
style={{
height: tableHeight + 56 - 16,
marginBottom: 0,
}}
height={tableHeight - 16}
rowHeight={56}
data={orders.slice(page.skip, page.skip + PAGE_SIZE)}
pageSize={PAGE_SIZE}
total={numberOfRows}
skip={page.skip}
scrollable={'virtual'}
onPageChange={pageChange}
dataItemKey={tableDataCenter.selectionFieldName}
>
{/* Header selection checkbox */}
<GridColumn
field="selected"
width="50px"
headerCell={() => (
<input
type="checkbox"
checked={isAllSelected}
onChange={onHeaderSelectionChange}
/>
)}
cell={(props) => (
<td>
<input
type="checkbox"
checked={
selectedState[
// eslint-disable-next-line react/prop-types
props.dataItem[tableDataCenter.selectionFieldName]
] || false
}
// eslint-disable-next-line react/prop-types
onChange={(e) => handleSelectionChange(e, props.dataItem)}
/>
</td>
)}
/>
<GridColumn
field="columnNo"
title="columnNo"
width="100px"
cell={({ dataItem, field }) => {
// eslint-disable-next-line no-console
console.log('value: ', dataItem[field]);
return (
<td key={`row-${dataItem.id}`}>
<span itemProp={`columnNo${dataItem[field]}`}>
{dataItem[field]}
</span>
</td>
);
}}
/>
<GridColumn
field={tableDataCenter.selectionFieldName}
title={tableDataCenter.selectionFieldName}
width="100px"
/>
{/* {columnsRender} */}
</GridWrapper>
</div>
</Wrapper>
);
};
Trustin
Top achievements
Rank 1
Iron
 asked on 04 Jan 2025
1 answer
50 views

Hi, I'm having problems trying to render grouped columns:

I have this grid:

/**
     * Renderiza una columna del grid.
     */
    const renderColumn = useCallback(
        (col: ColumnDef<T>, index: number) => (
            <GridColumn
                key={index}
                field={col.field as string}
                title={col.title}
                width={col.width}
                sortable={col.sortable}
                filterable={col.filterable}
                filter={enableFiltering ? col.filter : undefined}
                cell={CustomCell}
                resizable
            />
        ),
        [enableFiltering]
    );
    /**
     * Memoizar las columnas para evitar renderizados innecesarios.
     */
    const renderedColumns = useMemo(() => {
        if (columnsRowGrouped && !columns) {
            return columnsRowGrouped.map((group, groupIndex) => (
                <GridColumn key={groupIndex} title={group.title}>
                    {group.columns.map((col, colIndex) =>
                        renderColumn(col, colIndex)
                    )}
                </GridColumn>
            ));
        }
        if (columns && !columnsRowGrouped) {
            return columns.map((col, index) => renderColumn(col, index));
        }
        return null;

    }, [columns, columnsRowGrouped, renderColumn]);

 return (
        <div
            className={`${styles.telerik_generic_grid}`}
            style={gridProps.style}
        >
            <LocalizationProvider language="es-ES">
                <IntlProvider locale="es">
                    <ExcelExport
                        ref={_export}
                        data={Array.isArray(data) ? data : (data as DataResult).data || []}
                        fileName={exportFileName}
                    >
                        <Grid
                            id={id}
                            ref={grid}
                            className={`${gridProps.className || 'w-full'}`}
                            data={serverPaging ? data : localData.data}
                            total={serverPaging ? totalCount : localData.total}
                            pageable={enablePaging ? pageable : false}
                            sortable={enableSorting ? gridProps.sortable : false}
                            onSortChange={gridProps.onSortChange}
                            onPageChange={gridProps.onPageChange}
                            filterable={enableFiltering ? gridProps.filterable : false}
                            skip={dataState.skip}
                            take={dataState.take}
                            sort={dataState.sort}
                            resizable={gridProps.resizable}
                            style={{ width: '100%' }}
                            scrollable="scrollable"
                            onDataStateChange={handleDataStateChange}
                            onSelectionChange={gridProps.onSelectionChange}
                            {...gridProps}
                        >
                            {renderedColumns}
                        </Grid>
                    </ExcelExport>
                </IntlProvider>
            </LocalizationProvider>
        </div>
    );
}

 

 

with this data for example :

const sampleColumnsRowGrouped = [
  {
      title: "Grupo 1",
      columns: [
          { field: "field1" as "field1", title: "Campo 1", width: "auto" },
          { field: "field2" as "field2", title: "Campo 2", width: "auto" },
      ],
  },
  {
      title: "Grupo 2",
      columns: [
          { field: "field3" as "field3", title: "Campo 3", width: "auto" },
          { field: "field4" as "field4", title: "Campo 4", width: "auto" },
      ],
  },
];
const sampleData = [
  {
      field1: "Dato 1",
      field2: "Dato 2",
      field3: "Dato 3",
      field4: "Dato 4",
  },

];

da esta respuesta 

y este html


<div class="telerik-generic-grid_telerik_generic_grid__tK_ST">
  <div id="joins__grid_" style="width:100%" class="k-grid k-grid-md w-full" data-keyboardnavscope="true">
    <div class="k-grid-aria-root" role="grid" aria-colcount="4" aria-rowcount="1" id="joins__grid_-role-element-id" aria-label="Table">
      <div class="k-grid-header" role="presentation">
        <div class="k-grid-header-wrap" style="border-width:0" role="presentation">
          <table class="k-table k-grid-header-table k-table-md" role="presentation">
            <colgroup>
              <col width="NaNpx">
              <col width="NaNpx">
              <col width="NaNpx">
              <col width="NaNpx">
            </colgroup>
            <thead class="k-table-thead" role="rowgroup" data-keyboardnavheader="true">
              <tr class="k-table-row" style="touch-action:none" role="row" aria-rowindex="1">
                <th aria-sort="none" aria-colindex="1" aria-selected="false" colspan="32" rowspan="1" role="columnheader" class="k-table-th k-header" style="left: 0px; right: 0px;">
                  <span class="k-cell-inner">
                    <span class="k-link !k-cursor-default">
                      <span class="k-column-title">Grupo 1</span>
                    </span>
                  </span>
                  <span class="k-column-resizer" style="touch-action:none" draggable="false"></span>
                </th>
                <th aria-sort="none" aria-colindex="33" aria-selected="false" colspan="32" rowspan="1" role="columnheader" class="k-table-th k-header" style="left: 0px; right: 0px;">
                  <span class="k-cell-inner">
                    <span class="k-link !k-cursor-default">
                      <span class="k-column-title">Grupo 2</span>
                    </span>
                  </span>
                  <span class="k-column-resizer" style="touch-action:none" draggable="false"></span>
                </th>
              </tr>
              <tr class="k-table-row" style="touch-action:none" role="row" aria-rowindex="2">
                <th aria-sort="none" aria-colindex="1" aria-selected="false" colspan="1" rowspan="1" role="columnheader" class="k-table-th k-header" style="left: 0px; right: 0px;">
                  <span class="k-cell-inner">
                    <span class="k-link !k-cursor-default">
                      <span class="k-column-title">Campo 1</span>
                    </span>
                  </span>
                  <span class="k-column-resizer" style="touch-action:none" draggable="false"></span>
                </th>
                <th aria-sort="none" aria-colindex="2" aria-selected="false" colspan="1" rowspan="1" role="columnheader" class="k-table-th k-header" style="left: 0px; right: 0px;">
                  <span class="k-cell-inner">
                    <span class="k-link !k-cursor-default">
                      <span class="k-column-title">Campo 2</span>
                    </span>
                  </span>
                  <span class="k-column-resizer" style="touch-action:none" draggable="false"></span>
                </th>
                <th aria-sort="none" aria-colindex="3" aria-selected="false" colspan="1" rowspan="1" role="columnheader" class="k-table-th k-header" style="left: 0px; right: 0px;">
                  <span class="k-cell-inner">
                    <span class="k-link !k-cursor-default">
                      <span class="k-column-title">Campo 3</span>
                    </span>
                  </span>
                  <span class="k-column-resizer" style="touch-action:none" draggable="false"></span>
                </th>
                <th aria-sort="none" aria-colindex="4" aria-selected="false" colspan="1" rowspan="1" role="columnheader" class="k-table-th k-header" style="left: 0px; right: 0px;">
                  <span class="k-cell-inner">
                    <span class="k-link !k-cursor-default">
                      <span class="k-column-title">Campo 4</span>
                    </span>
                  </span>
                  <span class="k-column-resizer" style="touch-action:none" draggable="false"></span>
                </th>
              </tr>
            </thead>
          </table>
        </div>
      </div>
      <div class="k-grid-container" role="presentation">
        <div class="k-grid-content k-virtual-content" role="presentation">
          <div class="k-grid-table-wrap" role="presentation">
            <table class="k-table k-grid-table k-table-md" role="presentation">
              <colgroup>
                <col width="NaNpx">
                <col width="NaNpx">
                <col width="NaNpx">
                <col width="NaNpx">
              </colgroup>
              <tbody class="k-table-tbody" role="rowgroup" data-keyboardnavbody="true">
                <tr class="k-table-row k-master-row" role="row" aria-rowindex="3" absolute-row-index="0" data-grid-row-index="0">
                  <td>Dato 1</td>
                  <td>Dato 2</td>
                  <td>Dato 3</td>
                  <td>Dato 4</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
    <div class="k-pager k-pager-md k-grid-pager" role="application" aria-roledescription="pager" aria-label="Page 1 of 1" tabindex="0">
      <div class="k-pager-numbers-wrap">
        <button title="Go to the first page" role="button" aria-disabled="true" tabindex="-1" class="k-button k-button-md k-button-flat k-button-flat-base k-icon-button k-pager-nav k-pager-first k-disabled">
          <span class="k-icon k-svg-icon k-svg-i-caret-alt-to-left k-button-icon" aria-hidden="true">
            <svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
              <path d="M352 384 160 256l192-128zM128 128v256h32V128z"></path>
            </svg>
          </span>
        </button>
        <button title="Go to the previous page" role="button" aria-disabled="true" tabindex="-1" class="k-button k-button-md k-button-flat k-button-flat-base k-icon-button k-pager-nav k-disabled">
          <span class="k-icon k-svg-icon k-svg-i-caret-alt-left k-button-icon" aria-hidden="true">
            <svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
              <path d="m160 256 192-128v256z"></path>
            </svg>
          </span>
        </button>
        <select style="width:5em;margin:0px 1em;display:none" class="k-picker k-dropdown-list k-dropdown k-rounded-md k-picker-md">
          <option selected="">1</option>
        </select>
        <div class="k-pager-numbers">
          <button role="button" aria-label="Page 1" aria-current="true" tabindex="-1" class="k-button k-button-md k-button-flat k-button-flat-primary k-selected">
            <span class="k-button-text">1</span>
          </button>
        </div>
        <button title="Go to the next page" role="button" aria-disabled="true" tabindex="-1" class="k-button k-button-md k-button-flat k-button-flat-base k-icon-button k-pager-nav k-disabled">
          <span class="k-icon k-svg-icon k-svg-i-caret-alt-right k-button-icon" aria-hidden="true">
            <svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
              <path d="M352 256 160 384V128z"></path>
            </svg>
          </span>
        </button>
        <button title="Go to the last page" role="button" aria-disabled="true" tabindex="-1" class="k-button k-button-md k-button-flat k-button-flat-base k-icon-button k-pager-nav k-pager-last k-disabled">
          <span class="k-icon k-svg-icon k-svg-i-caret-alt-to-right k-button-icon" aria-hidden="true">
            <svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
              <path d="m128 128 192 128-192 128zm224 256V128h-32v256z"></path>
            </svg>
          </span>
        </button>
      </div>
      <span class="k-pager-sizes">
        <span class="k-dropdownlist k-picker k-picker-md k-picker-solid k-rounded-md" tabindex="-1" role="combobox" aria-required="false" aria-haspopup="listbox" aria-expanded="false" aria-owns=":R1lqukq:-listbox-id" aria-label="Page size" aria-describedby=":R1lqukq:-accessibility-id" aria-controls=":R1lqukq:-listbox-id" id=":R1lqukq:">
          <span id=":R1lqukq:-accessibility-id" class="k-input-inner">
            <span class="k-input-value-text">10</span>
          </span>
          <button tabindex="-1" type="button" aria-label="select" class="k-button k-button-md k-button-solid k-button-solid-base k-icon-button k-input-button">
            <span class="k-icon k-svg-icon k-svg-i-caret-alt-down k-button-icon" aria-hidden="true">
              <svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                <path d="M256 352 128 160h256z"></path>
              </svg>
            </span>
          </button>
          <select tabindex="-1" aria-hidden="true" style="opacity:0;width:1px;border:0;z-index:-1;position:absolute;left:50%">
            <option value="10"></option>
          </select>
        </span>
        <span>items per page</span>
      </span>
      <span class="k-pager-info">1 - 1 of 1 items</span>
    </div>
  </div>
</div>

If you see the colspan that it generates for the parent columns it is 32 and it should be 2 each.

If someone could help me, I've been trying for a while and nothing, thank you very much in advance

 

 

Yanko
Telerik team
 answered on 23 Dec 2024
1 answer
62 views

In our grid we are providing an expansion field and providing a detail grid as given in the Master-Detail grid example:
React Data Grid Master-Detail Grids - KendoReact

In all of the examples the detail grid takes up the entire width of the main grid. I can limit the detail grid to be the screen size and align it to the left of the master grid, but I am having difficulty having the grid be sticky within the master grid. (here is an example from MUI Data Grid - Master detail - MUI X

I have tried making the inner div
position: sticky;
width: 90vw;
left: 5vw


but it does not scroll within the grid. Am I missing something easy?

Vessy
Telerik team
 answered on 19 Dec 2024
1 answer
39 views
how to create a responsive KendoReact Grid that adjusts its width dynamically based on the viewport without relying on fixed widths or the explicit width property
Vessy
Telerik team
 answered on 16 Dec 2024
1 answer
43 views
Hello...I'm trying to add a PNG file to my export excel document.  Here is the code I'm using to try and do it.  Is it possible to even do this?  Am I doing anything wrong in my code?  This is the click even to a button in my own react component that I use to wrap the kendo ExportExcel library.

exportToExcel = async () => {
    if (this.excelExportRef.current) {
        const workbook = this.excelExportRef.current.workbookOptions();

        if (this.props.pngImage) {
            workbook.sheets[0].images = [
                {
                    name: 'pngImage',
                    src: this.props.pngImage,
                    position: {
                        type: 'twoCellAnchor',
                        from: { row: this.props.tableData.length + 10, col: 4 },
                        to: { row: this.props.tableData.length + 60, col: 10 }
                    }
                }
            ];
        }
    }

    this.excelExportRef.current.save(workbook);
}

Yanko
Telerik team
 answered on 12 Dec 2024
1 answer
32 views

Hi,

Please see example https://codesandbox.io/p/sandbox/dry-tdd-9hqysc?file=%2Fapp%2Fapp.tsx

The example shows a master grid with selection enabled. Master grid contains a detail grid which also have selection enabled. The problem is, when clicking a row in detail grid, the selection in master grid changes, and the detail grid's selection doesn't change.

 

Thanks,

Jie

 

Yanko
Telerik team
 answered on 11 Dec 2024
1 answer
90 views

Hi Team, 

Im having some trouble understanding how the GridColmn cell/cells properties are intended to be used. 

Quesion: When should I use the 'cell' property vs the 'cells' property. Historically I've used 'cell' and rendered its content based on the declarde editField. I now see there is a 'cells' property that has 'data' and 'edit' attributes. Should I be using these instead, they seem to handle that if check on the editField nativly?

What am I doing?
This example simulates what Im trying to achieve. This is an order form and each item can be ordered as units OR cases. For cases to be ordered, units must be 0 (and visa-versa). You can see in the itemChangeHandler im handling this as well as ensuring thats items cant have a negtive Qty. Thats all fine, but I want to make this UI more intutive by disabling the NumericTextBox that cannot be edited and preventing it from stepping below zero.

The problem Im having is extending the numeric editor on the GridColumn. I thought would be able to use the GridCell component and that it would manage the editor based on the grid editField, then I could either manipulate the GridCustomCellProps.children or GridCustomCellProps.render to add a disabled/max attribute to the NumericTextBox that is being rendered. 

However this does not appear to the case, the GridCell component does not consider the editField. Hence my original question? Uncomment line 80-84 to demo.

Why dont I just render a custom NumericTextBox?
This is possible but I have found that when the grid data changes, the NumericTextBox that is being edited looses focus (because all the lines are being re-rendered), which doesnt make a good UX. The native numeric editor doesnt loose focus though, so if you know how to solve that, it would help too.

!!! IMPORTANT I am using KendoReact v 5.19.0, updating it to the latest is not feasible, this needs to be resovled in the current version.

Any advice or feedback is appreciated.

Thanks,
Grant

Grant
Top achievements
Rank 3
Iron
Iron
Iron
 answered on 11 Dec 2024
1 answer
55 views

Hello, I am trying to enable single selection mode on the Kendo UI TreeView and update the styling of each node as the item is selected. However, I am running into a few challenges. I am working in TypeScript. I have looked at all the examples and while simple, they simple do not work as listed unless I am missing something. 

My TreeView is configured like this:

const [selectedLayer, setSelectedLayer] = useState(['']);
const OnLayerItemSelected = (event: TreeViewItemClickEvent) => {

const selectedItemId = String(event.item.id);
setSelectedLayer([ids]);

const item = event.item;
item.selected = !item.selected;

// other code

}

 

<TreeView
className={"margin-top-5 margin-left-minus-2p5em"}
data={nonContextualWorkspaceGroups}
item={(props) =>
_CustomNonContextualLegendItemRenderer({
...props,
onCheckChange: onLayerVisibilityChanged,
})}
selectField={"selected"}
draggable={true}
expandIcons={false}
checkboxes={false}

aria-multiselectable = {false}
onExpandChange={onLayerExpansionChanged}
onCheckChange={onLayerVisibilityChanged}
onItemClick={OnLayerItemSelected}
/>

With the above code, my application crashes with this error:

If I instead do this pasted below, the application does not crash but single select mode is not enabled and a selected node in the tree looks like this:

 



const [selectedLayer, setSelectedLayer] = useState({
ids: ["100"],
idField : "id"
});


const OnLayerItemSelected = (event: TreeViewItemClickEvent) => {

const selectedItemId = String(event.item.id);
setSelectedLayer({ids : [selectedItemId], idField:'id'});

const item = event.item;
item.selected = !item.selected;

// other code

}

<TreeView
className={"margin-top-5 margin-left-minus-2p5em"}
data={processTreeViewItems(nonContextualWorkspaceGroups, {
select: selectedLayer,
//check: visibleLayers,
//expand: expandedWorkspace,
})}
item={(props) =>
_CustomNonContextualLegendItemRenderer({
...props,
onCheckChange: onLayerVisibilityChanged,
})}
selectField={"selected"}
draggable={true}
expandIcons={false}
checkboxes={false}

aria-multiselectable = {false}
onExpandChange={onLayerExpansionChanged}
onCheckChange={onLayerVisibilityChanged}
onItemClick={OnLayerItemSelected}
/>

Yanko
Telerik team
 answered on 10 Dec 2024
1 answer
35 views

Hi,

I have a multi-step process form which has the Upload component on some screens. I've found that users don't wait for files to finish uploading and hit proceed to move to the next screen. Is there a way to block the user interface easily while a file is being uploaded, to prevent this from happening?  

Many thanks.

Yanko
Telerik team
 answered on 10 Dec 2024
1 answer
52 views
How can I make a custom cell in a Grid component respond to rowClick events? Currently, when I use rowClick in the Grid, it doesn't work for custom cells. What is the best way to ensure rowClick works for both regular and custom cells?
Nurik
Top achievements
Rank 2
Iron
Iron
 updated answer on 10 Dec 2024
Narrow your results
Selected tags
Tags
+? more
Top users last month
Anislav
Top achievements
Rank 6
Silver
Bronze
Bronze
Jianxian
Top achievements
Rank 1
Iron
Marco
Top achievements
Rank 3
Iron
Iron
Iron
Jim
Top achievements
Rank 2
Iron
Iron
Nurik
Top achievements
Rank 2
Iron
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Anislav
Top achievements
Rank 6
Silver
Bronze
Bronze
Jianxian
Top achievements
Rank 1
Iron
Marco
Top achievements
Rank 3
Iron
Iron
Iron
Jim
Top achievements
Rank 2
Iron
Iron
Nurik
Top achievements
Rank 2
Iron
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?