IgniteUI / igniteui-blazor

Ignite UI for Blazor component library packs 35+ native Blazor UI Controls with 60+ high-performance Charts designed for any Blazor WASM or Server-side app scenario.
https://www.infragistics.com/products/ignite-ui-blazor
3 stars 3 forks source link

Add inline editor for grid cell #62

Closed wnvko closed 2 months ago

wnvko commented 1 year ago

Description

I want to add IgbSelect as inline editor for a grid cell.

Steps to reproduce

This is what I have in my grid:

        <IgbColumn Field="LastName"
                   Header="Last Name"
                   Editable=true>
            <BodyTemplate>
                @(context.Cell.Value.ToString() ?? string.Empty) CT
            </BodyTemplate>
            <InlineEditorTemplate>
                <IgbSelect Value="@(context.Cell.EditValue.ToString())" Change="@(e => context.Cell.Value = e.Detail.Value)">
                    @foreach (var item in dashboardDataAllTeamMembers)
                    {
                        <IgbSelectItem Value="@item.FirstName">@item.FirstName</IgbSelectItem>
                    }
                </IgbSelect>
            </InlineEditorTemplate>
        </IgbColumn>

Result

  1. Select does not show cell value selected in the select drop-down. It seems that this part does not work Value="@(context.Cell.EditValue.ToString())".
  2. After selecting an item in the select the selected value is not applied to the grid cell. It seems that this part does not work too Change="@(e => context.Cell.Value = e.Detail.Value)".

Expected result

I want to be able to put IgbSelect as inline editor. When cell enters edit mode the select should show the cell value as selected item. When an item is selected in the select the value of the item should be applied as a value to the grid cell.

mddifilippo89 commented 1 year ago

@wnvko I would JS to populate the template, follow the example at the bottom of this discussion https://github.com/IgniteUI/igniteui-blazor/issues/53

There is a caveat where you can't add items directly within the component while inside the template. I see exceptions when selecting items using the code you provided.

-elements.4112d35dd7f73b825fc3.bundle.js:1 Unhandled Promise rejection: Cannot read properties of undefined (reading 'reference') ; Zone: ; Task: Promise.then ; Value: TypeError: Cannot read properties of undefined (reading 'reference') at apply (igniteui-webcomponents.0a01635c2b3a611b73e9.bundle.js:8879:7343) at fn (341.ad85da54e00262c7a9ad.bundle.js:2:6082) at async a (341.ad85da54e00262c7a9ad.bundle.js:2:1119) TypeError: Cannot read properties of undefined (reading 'reference') at apply (https://localhost:7295/_content/IgniteUI.Blazor/igniteui-webcomponents.0a01635c2b3a611b73e9.bundle.js:8879:7343) at fn (https://localhost:7295/_content/IgniteUI.Blazor/341.ad85da54e00262c7a9ad.bundle.js:2:6082) at async a (https://localhost:7295/_content/IgniteUI.Blazor/341.ad85da54e00262c7a9ad.bundle.js:2:1119) i.onUnhandledError @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 h @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 i.microtaskDrainDone @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 w @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 Promise.then (async) v @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 y @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 scheduleTask @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 scheduleTask @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 scheduleMicroTask @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 k @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 I @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 (anonymous) @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 (anonymous) @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 Promise.then (async) (anonymous) @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 O @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 F.e.then @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 validate @ igniteui-webcomponents.0a01635c2b3a611b73e9.bundle.js:9928 a.willUpdate @ igniteui-webcomponents.0a01635c2b3a611b73e9.bundle.js:1 performUpdate @ 341.ad85da54e00262c7a9ad.bundle.js:2 scheduleUpdate @ 341.ad85da54e00262c7a9ad.bundle.js:2 $E @ 341.ad85da54e00262c7a9ad.bundle.js:2 await in $E (async) requestUpdate @ 341.ad85da54e00262c7a9ad.bundle.js:2 set @ 341.ad85da54e00262c7a9ad.bundle.js:2 activateItem @ igniteui-webcomponents.0a01635c2b3a611b73e9.bundle.js:9585 selectItem @ igniteui-webcomponents.0a01635c2b3a611b73e9.bundle.js:9585 handleClick @ igniteui-webcomponents.0a01635c2b3a611b73e9.bundle.js:9585 handleEvent @ app.5a2ae1f380de4449300a.bundle.js:2 s.handleEvent.e.callback @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 invokeTask @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 runTask @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 invokeTask @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 c @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 h @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 u @ igniteui-angular-elements.4112d35dd7f73b825fc3.bundle.js:1 igniteui-webcomponents.0a01635c2b3a611b73e9.bundle.js:8879 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'reference') at apply (igniteui-webcomponents.0a01635c2b3a611b73e9.bundle.js:8879:7343) at fn (341.ad85da54e00262c7a9ad.bundle.js:2:6082) at async a (341.ad85da54e00262c7a9ad.bundle.js:2:1119) apply @ igniteui-webcomponents.

wnvko commented 1 year ago

@mddifilippo89 I know how to add select as editor via InlineEditorTemplateScript. However, I do not want to make it via JS. I do want to add the inline editor via Blazor and C# with no JS. Actually the code above seams to work without the part where I am setting the value of the select and the value of the cell. This is what is not working.

mddragnev commented 2 months ago

@wnvko One part of the issue is fixed here: https://github.com/IgniteUI/igniteui-blazor/issues/111. Then another part of the issue is that we try to update the cell editValue on the server but the cell should be also updated on the client, also this should be somewhat async operation. We do not have a way to do this yet because there are not a igc-cell representation on the client, thus the server cannot find a reference to update. I think that same will happen with the row. @damyanpetev Let me know if you have any thoughts on that. The only workaround I can think of is this: use the grid reference to call the updateCellAsync API

    <IgbGrid @ref="grid" Data=@CustomersData Width="100%" PrimaryKey="ID">
        <IgbColumn Field="ID"></IgbColumn>
        <IgbColumn Field="CompanyName" Editable=true>
            <InlineEditorTemplate>
                <IgbSelect Value="@(context.Cell.EditValue.ToString())"
                    Change="@(async e => {
                    await grid.UpdateCellAsync(e.Detail.Value,context.Cell.Id.RowID,context.Cell.Column.Field);
                    })">
                    @foreach (var item in CustomersData)
                    {
                        <IgbSelectItem Value="@item.CompanyName">@item.CompanyName</IgbSelectItem>
                    }
                </IgbSelect>
            </InlineEditorTemplate>
        </IgbColumn>
        <IgbColumn Field="ContactName" Editable=true></IgbColumn>
        <IgbColumn Field="ContactTitle" Editable=true></IgbColumn>
    </IgbGrid>
damyanpetev commented 2 months ago

Yeah, this issue is quite old, possibly before official docs were live, at this point we don't really recommend using RenderFragment templates for anything high-intensity (read: most things in the grid, especially in virtualized window) or in need of synchronous interaction with the client component. Editing falls in both categories and is best suited using a JS template is the best approach for that. The suggestion for updateCellAsync is only somewhat valid (ignoring the performance hit) - it skips the editing process though and it won't respect row editing behavior and likely more, so not ideal.

@wnvko We should be using JS templates all around now and unless there's anything else, I believe this can be closed.