Syncfusion Blazor Grid - Multi-Column ForeignKeyColumn Dropdown - Define EditTemplate Dynamically

Hi,

I have a large number of dynamically defined grids in my LOB application.

I have created a base Grid class and I use reflection to interrogate the properties of the base type of the grid and then formulate the GridColumns. It is effectively another implementation of the Syncfusion AutoGenerate columns function, but it gives me a lot of flexibility and consistency when creating a lot of grids.

However, there are some cases where I'd like to be able to dynamically define templates for the Grid Columns. In particular, for GridForeignKey columns, I'd like to be able to define multi-column combobox dropdowns programmatically, similar to the following links.

https://blazor.syncfusion.com/documentation/datagrid/editing#use-edit-template-in-foreign-key-column

https://www.syncfusion.com/blogs/post/easiest-way-to-create-a-multicolumn-combobox-in-blazor.aspx

The issue is that the syntax for defining the templates requires static definition of context type / referenced column etc., whereas I'd like to be able to generate this dynamically as text, which then gets interpreted and rendered.

I had a look at the new .Net6 dynamic component, but it didn't look like it could be used in this circumstance.

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/dynamiccomponent?view=aspnetcore-6.0

Following is a code snippet from Grid.razor. Refer to the attached simplified sample app for a full working example.


<SfGrid TValue="TValue" DataSource="Items" Width="100%" Height="100%" AllowResizing="true" AllowReordering="true" Toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update","Cancel" })">
    <GridEditSettings Mode="EditMode.Batch" AllowAdding="true" AllowEditing="true" ></GridEditSettings>
    <GridSelectionSettings Mode="SelectionMode.Cell" CellSelectionMode="CellSelectionMode.Box" Type="SelectionType.Multiple"></GridSelectionSettings>
    <GridColumns>
        @foreach (var col in GetColumns())
        {
            @if (!col.IsForeignKey)
            {
                <GridColumn Field="@col.Field" HeaderText="@col.HeaderText" AutoFit="true" AllowReordering="true" AllowResizing="true" AllowEditing="true" IsPrimaryKey="@col.IsPrimaryKey"
                            ></GridColumn>
            }
            else
            {
                Lookups.TryGetValue(@col.Field, out var lu);


                <GridForeignColumn TValue="LookupDTO" Field="@col.Field" HeaderText="@col.HeaderText" AutoFit="true" AllowReordering="true" AllowResizing="true" AllowEditing="true" ForeignDataSource="@lu" ForeignKeyField="ID" ForeignKeyValue="Code">
                    @*HOW CAN I PROGRAMMATICALLY / DYNAMICALLY DEFINE EDIT TEMPLATE SIMILAR TO FOLLOWING*@
@* <EditTemplate>
                        <SfComboBox TValue="int?" TItem="LookupDTO" @bind-Value="@((context as typeof(TValue).Name)[email protected])" DataSource="@lu">
                            <ComboBoxFieldSettings Value="ID" Text="Code"></ComboBoxFieldSettings>
                        </SfComboBox>
                    </EditTemplate>*@
                </GridForeignColumn>
            }
        }
    </GridColumns>
</SfGrid>


Attachment: SyncfusionBlazorApp5GridMultiColumnLookup_fb843ed3.zip


6 Replies 1 reply marked as answer

MS Monisha Saravanan Syncfusion Team September 22, 2022 03:11 PM UTC

Hi Greg,


Greetings from Syncfusion.


We are currently validating your query at our end and we will update further details within two business days on or before (26.09.2022). Until then we appreciate your patience.


Regards,

Monisha



MS Monisha Saravanan Syncfusion Team September 26, 2022 03:53 PM UTC

Hi Greg,


Thanks for the patience.


We have checked your sample and modified your sample to render the multicolumn combobox. We have used value change event and you can customize the value as per your requirement in ValueChangeEvent . Kindly check the attached sample for your reference.


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/Forum-177679-Blazor-2093266100.zip


Please let us know if you have any concerns.


Regards,

Monisha



GW Greg Wruck September 26, 2022 07:17 PM UTC

Thanks Monisha, That answer was worth waiting for!  It is exactly what I needed.  



GW Greg Wruck September 26, 2022 09:07 PM UTC

Hi Monisha,

I made a slight change to the sample so that the ItemTemplate shows the values of the lookup list, rather than the statically calculated value from the parent context.

However, I can't work out how to bind the selected value in the combo box back to the parent grid.  Do I need to do that in the event, or is there another way of implementing the binding?

               <GridForeignColumn TValue="LookupDTO" Field="@col.Field" HeaderText="@col.HeaderText" AutoFit="true" AllowReordering="true" AllowResizing="true" AllowEditing="true" ForeignDataSource="@lu" ForeignKeyField="ID" ForeignKeyValue="Code">

                  <EditTemplate>
                        @{
                             var c = (context as TValue);
                            var a = c.GetType().GetProperty(col.Field).GetValue(c);
                            int? b = Convert.ToInt32(a);


                          //@bind-Value="@((context as typeof(TValue).Name)[email protected])"


                      @*HOW CAN I BIND THE SELECTED LookupDTO.ID TO THE BASE GRID FOREIGN KEY COLUMN? *@
                            <SfComboBox TValue="int?" Value="@b" TItem="LookupDTO" CssClass="e-multi-column" DataSource="@lu" PopupWidth="500px" PopupHeight="200">
                                <ComboBoxFieldSettings Value="ID" Text="Code"></ComboBoxFieldSettings>
                                 <ComboBoxTemplates TItem="LookupDTO">
        <HeaderTemplate>
            <table ><tr><th style="width:100px">Code</th><th style="width:220px">Description</th></tr></table>
        </HeaderTemplate>
        <ItemTemplate Context="_context">
            <table>
                <tbody>
                    <tr>
                        <td style="width: 100px">@((_context as LookupDTO).Code) </td>
                        <td style="width: 220px">@((_context as LookupDTO).Description)</td>
                    </tr>
                </tbody>
            </table>
        </ItemTemplate>
    </ComboBoxTemplates>
     <ComboBoxEvents TItem="LookupDTO" TValue="int?" ValueChange="@((args) => ValueChangeHandler(args, c))"></ComboBoxEvents>

                            </SfComboBox>
                        }
                    </EditTemplate>
                </GridForeignColumn>



Attachment: SyncfusionBlazorApp5_GridMultiColumnLookupRev1_8ab69056.zip


GW Greg Wruck September 27, 2022 12:09 AM UTC

I worked it out.  You do the update in the ChangeHandler.  I just added another parameter to pull in the fieldname.  Thanks for your help on this - it introduced me to some new concepts in Blazor.  


    private void ValueChangeHandler(ChangeEventArgs<int?, LookupDTO> args, TValue val, string FieldName)
    {
        val.GetType().GetProperty(FieldName).SetValue(val, args.ItemData.ID);
    }


Attachment: SyncfusionBlazorApp5GridMultiColumnLookup_Rev2_6955731b.zip

Marked as answer

MS Monisha Saravanan Syncfusion Team September 27, 2022 04:30 AM UTC

Hi Greg,


Welcome.


We are glad to hear that the provided solution was helpful at your end. Kindly get back to us if you have further queries. As always we will be happy to help you.


Regards,

Monisha


Loader.
Up arrow icon