Programmatically add columns

I am building a component which inherits the data grid component for common settings etc.. and am looking to create a parameter for specifying whether to show a command column or not and what buttons to have in the command column. I.e. Edit, Delete etc...

What I want to do then do is programmatically check that parameter and if set to true append a column to the list of columns on the grid. This will save me having to always define the command column on every grid, but rather can just set a parameter of say ShowRowEditButton="true".

I have tried to do this via OnAfterRender, OnSetParameters etc.. but am not having any luck.

Do you have any examples of how to achieve this?


5 Replies

RN Rahul Narayanasamy Syncfusion Team September 27, 2021 12:42 PM UTC

Hi Peter, 

Greetings from Syncfusion. 

We have validated your query and you want to show the Command column based on the parameter passed to the component. Here, we have prepared a simple sample based on your requirement. Find the below code snippets and sample for your reference. 

[Index.razor] 
 
<CommonGrid ShowRowEditButton="false"></CommonGrid>   //Command column won’t be shown 

[Counter.razor] 
<CommonGrid ShowRowEditButton="true"></CommonGrid>     //command column will be shown 
 
@using Syncfusion.Blazor.Grids 
 
<SfGrid @ref="GridInstance" DataSource="@Orders" AllowPaging="true" Height="315"> 
    <GridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true"></GridEditSettings> 
    <GridColumns> 
        . . . 
        <GridColumn Field=@nameof(Order.Freight) HeaderText="Freight" Format="C2" TextAlign="TextAlign.Right" Width="120"></GridColumn> 
        @if (ShowRowEditButton) 
        { 
         <GridColumn HeaderText="Manage Records" Width="150"> 
            <GridCommandColumns> 
                <GridCommandColumn Type="CommandButtonType.Edit" ButtonOption="@(new CommandButtonOptions() { IconCss = "e-icons e-edit", CssClass = "e-flat" })"></GridCommandColumn> 
                <GridCommandColumn Type="CommandButtonType.Delete" ButtonOption="@(new CommandButtonOptions() { IconCss = "e-icons e-delete", CssClass = "e-flat" })"></GridCommandColumn> 
                . . . 
            </GridCommandColumns> 
         </GridColumn> 
        } 
         
    </GridColumns> 
</SfGrid> 
 
@code{ 
    SfGrid<Order> GridInstance { get; set; } = new SfGrid<Order>(); 
    [Parameter] 
    public bool ShowRowEditButton { get; set; } 
    public List<Order> Orders { get; set; } 
 
    . . . 
} 


Please let us know if  you have any concerns. 

Regards, 
Rahul 



PH Peter Harrison September 27, 2021 11:57 PM UTC

Hi Rahul,

Thanks for the reply. I did however already try what you have suggested above, and while it kind of works what I found is that if you also supply the grid columns on the page, then because the component has a <GridColumns> tag that overrides and all I ended up with was the command column.

How can I have it so that it will still render the <GridColumns> specified on the page / component that is referencing the common grid?


I was trying to do it in code. I.e. onAfterRender or onParametersSet and getting reference to the grids columns and if the ShowRowEditButton was true, dynamically appending a column to the list of grid columns, but that had issues as well.


I.e. in the below case, all you will actually see rendered on the page is the command column.

Page

<CommonGrid ShowRowEditButton="true" DataSource="@DataSource" TValue="@TValue">

      <GridColumns>

           <GridColumn Field="@FieldName" HeaderText="HeaderText" />

           <GridColumn Field="@FieldName" HeaderText="HeaderText" />

      </GridColumns>

</CommonGrid>


Component

<sfGrid ...>

     <GridColumns>

          @if(ShowRowEditButton) {

                   <GridColumn>

                        ...command column syntax

                   </GridColumn>

          }

     </GridColumns>

</sfGrid>




RN Rahul Narayanasamy Syncfusion Team September 28, 2021 03:23 PM UTC

Hi Peter, 

Thanks for the update. 

We have validated your query with the provided details. You have defined some GridColumns in main page and want to render the Grid with those columns and add the Command column based on the condition. Here, we modified the sample based on your case. 

Here, we have defined some GridColumns(using programmatic way(new GridColumn)) in main page(Index.razor and Counter.razor). We have passed the defined columns to the CommonGrid component. In CommonGrid component, we have iterated the passed columns and rendered GridColumns and finally added the Command column based on the passed parameter value(ShowRowEditButton). Find the below code snippets and sample for your reference. 

[Index.razor] 
@using Syncfusion.Blazor.Grids 
 
<CommonGrid ShowRowEditButton="false" Columns="@Columns"></CommonGrid> 
 
@code{ 
    List<GridColumn> Columns = new List<GridColumn>(){ 
        new GridColumn(){ Field = "OrderID", HeaderText = "Order ID", TextAlign = TextAlign.Right,Width = "120"}, 
        new GridColumn(){ Field = "CustomerID", HeaderText = "Customer Name", TextAlign = TextAlign.Center ,Width = "120"} 
    }; 
} 
[Counter.razor] 
@using Syncfusion.Blazor.Grids 
 
<CommonGrid ShowRowEditButton="true" Columns="@Columns"></CommonGrid> 
 
@code{ 
    List<GridColumn> Columns = new List<GridColumn>(){ 
        new GridColumn(){ Field = "Freight", HeaderText = "Freight", TextAlign = TextAlign.Right,Width = "120"}, 
        new GridColumn(){ Field = "ShipCountry", HeaderText = "Ship Country", TextAlign = TextAlign.Center ,Width = "120"} 
    }; 
} 
 

[CommonGrid.razor] 
<SfGrid @ref="GridInstance" DataSource="@Orders" AllowPaging="true" Height="315"> 
    <GridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true"></GridEditSettings> 
    <GridColumns> 
        @foreach( var cols in Columns) 
        { 
        }   
        @if (ShowRowEditButton) 
        { 
         <GridColumn HeaderText="Manage Records" Width="150"> 
            <GridCommandColumns> 
                <GridCommandColumn Type="CommandButtonType.Edit" ButtonOption="@(new CommandButtonOptions() { IconCss = "e-icons e-edit", CssClass = "e-flat" })"></GridCommandColumn> 
                . . . 
         </GridColumn> 
        } 
         
    </GridColumns> 
</SfGrid> 
 
@code{ 
    SfGrid<Order> GridInstance { get; set; } = new SfGrid<Order>(); 
    [Parameter] 
    public bool ShowRowEditButton { get; set; } 
    public List<Order> Orders { get; set; } 
 
    [Parameter] 
    public List<GridColumn> Columns { get; set; } 
 
    . . . 
} 


Please let us know if you have any concerns. 

Regards, 
Rahul 




PH Peter Harrison September 29, 2021 12:04 AM UTC

Great thanks.

In the above scenario how would you handle if one of the columns needed to have a template specified?

I was able to get it working another way, but not sure if it is the advisable way (see below)?. Note how I have used @ChildContent in the middle of the grid columns. Then in the page / component referencing the grid I just put in grid columns and it works.

<GridColumns>

        @if(ShowCheckboxColumn)

        {

            <GridColumn Type="ColumnType.CheckBox" Width="50"></GridColumn>

        }


        @if((ShowRowEditButton || ShowRowDeleteButton) && CommandColumnPosition == CommandColumnPosition.Start)

        {

             <GridColumn HeaderText="@CommandColumnHeaderText" Width="150" ShowInColumnChooser="false">

                <GridCommandColumns>

                    @if (ShowRowEditButton)

                    {

                        <GridCommandColumn Type="CommandButtonType.Edit" ButtonOption="@(new CommandButtonOptions() { IconCss = "e-icons e-edit", CssClass = "e-flat" })"></GridCommandColumn>

                    }

                    @if(ShowRowDeleteButton)

                    {

                        <GridCommandColumn Type="CommandButtonType.Delete" ButtonOption="@(new CommandButtonOptions() { IconCss = "e-icons e-delete", CssClass = "e-flat" })"></GridCommandColumn>

                    }                 

                    @CustomCommandColumns

                </GridCommandColumns>

             </GridColumn>

        }       


        @ChildContent


        @if((ShowRowEditButton || ShowRowDeleteButton) && CommandColumnPosition == CommandColumnPosition.End)

        {

             <GridColumn HeaderText="@CommandColumnHeaderText" Width="150" ShowInColumnChooser="false">

                <GridCommandColumns>

                    @if (ShowRowEditButton)

                    {

                        <GridCommandColumn Type="CommandButtonType.Edit" ButtonOption="@(new CommandButtonOptions() { IconCss = "e-icons e-edit", CssClass = "e-flat" })"></GridCommandColumn>

                    }

                    @if(ShowRowDeleteButton)

                    {

                        <GridCommandColumn Type="CommandButtonType.Delete" ButtonOption="@(new CommandButtonOptions() { IconCss = "e-icons e-delete", CssClass = "e-flat" })"></GridCommandColumn>

                    }

                    @CustomCommandColumns

                </GridCommandColumns>

             </GridColumn>

        }

    </GridColumns>     



RN Rahul Narayanasamy Syncfusion Team September 30, 2021 03:46 AM UTC

Hi Peter,  
 
Thanks for the update. 
 
Query: In the above scenario how would you handle if one of the columns needed to have a template specified? 
 
We have validated your query and we suspect that you want to know how to define Template while using the mentioned way. You can define the template in GridColumn by using RenderFragment like below code example. You can define template using RenderFragment and assign it to the Template property of GridColumn. 
 
@code{ 
    List<GridColumn> Columns = new List<GridColumn>(){ 
        new GridColumn(){ Field = "OrderID", HeaderText = "Order ID", TextAlign = TextAlign.Right,Width = "120"}, 
        new GridColumn(){ Field = "CustomerID", HeaderText = "Customer Name", TextAlign = TextAlign.Center ,Width = "120"}, 
        new GridColumn(){ HeaderText = "Template Column", Template = g, TextAlign = TextAlign.Right,Width = "120"} 
    }; 
     static RenderFragment<object> g = (value) => 
    { 
            Order order = value as Order; 
            return b => 
            { 
                b.AddContent(1,@"name"); 
            }; 
    }; 
    public class Order 
    { 
        . . . 
    } 
} 
 
The above way achieving the requirement is little bit tedious way. 
 
We are happy to hear that you have achieved your requirement by using another way. If it is work correct based on your requirement, then we suggest you to achieve your requirement by using the way you have used. 
 
Please let us know if you have any concerns. 
 
Regards, 
Rahul 
 
 


Loader.
Up arrow icon