Conditional templating with dynamic columns

Hi! I'm generating columns dynamically in SF Blazor Grid.

Is there any way to conditionally add HeaderTemplate or Template in column? I can't put if-statement straight in as a child content of a column since it's expecting one of the template component declarations... If i create the template component and put the if statement inside it, it causes the template to render even my if-check does not pass.

Another one regarding dynamic column creation. A feature that would allow me to access the default data context of row / cell would be highly appreciated. Ie.  if i declare the column component with Field -parameter i could then in the column template access the default data context of cell... maybe just get access to the default value of the cell as object... There is a similiar feature in grid aggregate footer where you can access the default values of the footer datacontext in the footer template. I'm planning to add custom cell tooltip using the template but without the ability described above i would need to send all the row items with the column model to the view model to be evaluated for cell value. 


5 Replies 1 reply marked as answer

JP Jeevakanth Palaniappan Syncfusion Team November 26, 2020 02:21 PM UTC

Hi Ville, 

Greetings from Syncfusion support. 

We have validated your query and based on your requirement we have prepared a sample for your reference. 


In the sample we are able to use if-statement inside the header template and it is working as expected and also you can access the context as like in below code snippet. 

<SfGrid DataSource="@OrderData"> 
    <GridEditSettings AllowEditing="true" AllowAdding="true" AllowDeleting="true"></GridEditSettings> 
    <GridColumns> 
        @foreach (var prop in typeof(Order).GetProperties()) 
        { 
            <GridColumn Field="@prop.Name" IsPrimaryKey="@(prop.Name == "OrderID")" AllowEditing="@prop.CanWrite"> 
                <HeaderTemplate> 
                    @{ 
                        //You can access the context here 
                        var con = (context as Order); 
                    } 
                    @if (prop.Name == "OrderID") 
                    { 
                        <span>HeaderTemplate - ifcondition</span> 
                    } 
                    else 
                    { 
                        <span>HeaderTemplate - elsecondition</span> 
                    } 
                </HeaderTemplate> 
                <Template> 
                    @{ 
                        //You can access the context here 
                        var con = (context as Order); 
                        <span>@con.OrderID</span> 
                    } 
                </Template> 
            </GridColumn> 
        } 
    </GridColumns> 
</SfGrid> 

Please get back to us if you have any other queries. 

Regards, 
Jeevakanth SP. 





FW Ferdinand Weinberger January 8, 2021 09:26 AM UTC

Hi Jeevakanth!

I have a question about your proposed solution ...
With the Template or HeaderTemplate tag in place, I have to code each type of output myself.
Is there some way to access the default behavior in the template?
I only need templates for a few types of columns. Most columns use standard output based on ColumnType.

regards,
Ferdinand


JP Jeevakanth Palaniappan Syncfusion Team January 11, 2021 11:50 AM UTC

Hi Ferdinard, 

We would like to let you know that the Template/HeaderTemplate support is to customize the content/headers of the grid. So for your case, it is not possible to do the default behavior in the templates. 

Please get back to us if you have any further queries. 

Regards, 
Jeevakanth SP. 



VI Ville replied to Jeevakanth Palaniappan January 12, 2021 07:24 AM UTC

Hi Ville, 

Greetings from Syncfusion support. 

We have validated your query and based on your requirement we have prepared a sample for your reference. 


In the sample we are able to use if-statement inside the header template and it is working as expected and also you can access the context as like in below code snippet. 

<SfGrid DataSource="@OrderData"> 
    <GridEditSettings AllowEditing="true" AllowAdding="true" AllowDeleting="true"></GridEditSettings> 
    <GridColumns> 
        @foreach (var prop in typeof(Order).GetProperties()) 
        { 
            <GridColumn Field="@prop.Name" IsPrimaryKey="@(prop.Name == "OrderID")" AllowEditing="@prop.CanWrite"> 
                <HeaderTemplate> 
                    @{ 
                        //You can access the context here 
                        var con = (context as Order); 
                    } 
                    @if (prop.Name == "OrderID") 
                    { 
                        <span>HeaderTemplate - ifcondition</span> 
                    } 
                    else 
                    { 
                        <span>HeaderTemplate - elsecondition</span> 
                    } 
                </HeaderTemplate> 
                <Template> 
                    @{ 
                        //You can access the context here 
                        var con = (context as Order); 
                        <span>@con.OrderID</span> 
                    } 
                </Template> 
            </GridColumn> 
        } 
    </GridColumns> 
</SfGrid> 

Please get back to us if you have any other queries. 

Regards, 
Jeevakanth SP. 




Hi Jeevakanth,

Just noticed that you have replied to this thread already some time ago.

The sample you have provided doesn't resolve my problems. 

Header template & content template
My point is to switch between column cell default content and column content template (also header cell) depending on if user model for that column contains data for that template, so that in same grid some columns could use default content of GridColumn defined by parameters and some columns could use the Template based content.
Reflecting to my original post my goal desired behavior is as follows:
- Inside grid column declaration i would like to check if column model contains information for content template (if(column.HeaderContentTemplate != null))
-    If does => populate header template tag and create content for the  template based on column model ("column.HeaderContentTemplate").
-  If doesn't => do not populate header template tag and instead use default behavior of grid column for header content
- Same requirement is for cell content template.

The sample that i originally provided also works, but the way the SfGrid is designed, it doesn't allow using that if statement where it should be used in order to conditionally switch between default mode and / templated mode from column to another. Using the if statement inside that template tag forces the template component to render regardless of the user model contains data or doesn't while the desired behavior would be to use the GridColumn parameters defined default when there is no template data in the user model.

Accessing default data context of row / cell
My point was not to access the context / model of the row as you suggested in your reply. I am already doing that in my sample.
What my point was, is to access the abstraction that sits between user model (in my case the "column") and the actual visible cell ie. the default data context of column that the GridColumn component uses to populate cell contents. And as i have earlier described in my original post
the context should at least have some sort of property (type of object or type of string) that is referenceable in design time that will contain the runtime data of the cell content. Like this the default content of the row & cell would be accessible inside the content template just like in the aggregate footer mentioned.

another example what im trying to do:

<GridColumn Field="@column.Field HeaderText="@column.Header".... 
<Template>
@{
          var cellCont = cellDataContext as [CellDataContext]
          
          if(cellCont.Content is string stringContent)
          {
               <span>@stringContent</span>
          }
}
</Template>
</GridColumn>.

... here the CellDataContext represents the abstraction class that is the destination where the user model gets deserialized based on those GridColumn parameters. This is the actual context that the component uses to populate data in the grid cells. The "Content" -property (type of object) represents the deserialized data from the user bound model that will be rendered in the cell. It might be beneficial for CelDataContext to have also other properties that would expose the default behavior of the grid to be used in templates.

br. Ville




JP Jeevakanth Palaniappan Syncfusion Team January 18, 2021 02:40 PM UTC

Hi Ville, 

Query 1: Header template & content template 
 
We have validated your query and we suggest you to achieve your requirement by rendering a separate if-else statement based on the model information for the columns to render with Header, Content template and for the columns that doesn’t want to render with Header, Content template. Please refer the below code snippet for your reference. 
 
<SfGrid DataSource="@OrderData"> 
    <GridEditSettings AllowEditing="true" AllowAdding="true" AllowDeleting="true"></GridEditSettings> 
    <GridColumns> 
        @foreach (..) 
        { 
            @if (column.HeaderContentTemplate != null) 
            { 
                <GridColumn Field=".."> 
                    <HeaderTemplate> 
                        <span>Header Template </span> 
                    </HeaderTemplate> 
                </GridColumn> 
            } 
            else { 
                <GridColumn Field=".."></GridColumn> 
            } 
        } 
</GridColumns> 
</SfGrid> 

Query 2: Accessing default data context of row / cell 
 
We suspect that you want to access the data of that particular column in the context instead of the row data. We would like to inform you that the grid will be in the row wise and so the content will have only the row data information. This is the default behavior of the grid component. 
 
Please get back to us if you have any other queries. 
 
Regards, 
Jeevakanth SP. 


Marked as answer
Loader.
Up arrow icon