We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Programatically create/change columns on the fly.

Hello,

Currently, I am failing to create/change columns of a Grid on the fly. Here's what I am trying to do :

@inherits ComponentBase
@using Syncfusion.EJ2.Blazor.Data
@using Syncfusion.EJ2.Blazor.DropDowns
@using Syncfusion.EJ2.Blazor.Grids
@using Syncfusion.EJ2.Blazor.Navigations
@using Kairos.Models.OData

@inject ApplicationState application
@inject HttpClient httpClient

@if (@configurations == null)
{
    <div on="kairos.layout.showProgress()">Loading</div>
}
else
{
    <div class="grid-odq" onload="kairos.layout.hideProgress()">
        <div>
            <EjsToolbar ID=@("toolbar" + Identifier)>
                <ToolbarItems>
                    <ToolbarItem Type="ItemType.Input" Align="ItemAlign.Left">
                        <template>
                            <EjsDropDownList ID=@("odqName" + Identifier) @Ref=@ddlConfigurations Index="@index" DataSource="@configurations" OnValueSelect="@OnConfigurationValueSelect" Width="150px">
                                <DropDownListFieldSettings Text="Name" Value="Id" />
                            </EjsDropDownList>
                        </template>
                    </ToolbarItem>
                    <ToolbarItem Type="ItemType.Separator" Align="ItemAlign.Left" />
                </ToolbarItems>
            </EjsToolbar>
        </div>
        <div>
            <EjsGrid ID=@("grid" + Identifier) @Ref=@grid AllowPaging="true" Width="100%" Height="100%" Created="@OnGridCreated">
                <GridPageSettings PageSize="5" />
            </EjsGrid>
        </div>
    </div>
}

@functions
{
    [Parameter]
    public string Identifier { get; set; }

    [Parameter]
    public string EntryPoint { get; set; }

    [Parameter]
    public string Location { get; set; }

    // UI Components
    EjsDropDownList ddlConfigurations;
    EjsGrid grid;


    string odqConfigurationsUrl;
    List<ODataConfigurationModel> configurations;
    int index = 1;

    protected override async Task OnParametersSetAsync()
    {
        await base.OnParametersSetAsync();
        var restClient = new RestClient(httpClient);
        this.odqConfigurationsUrl = RestClient.RootUrl + "odata/configurations";
        this.configurations = await restClient.GetAsync<List<ODataConfigurationModel>>("odata/configurations");
        index = 0;
    }

    protected void OnConfigurationValueSelect(Syncfusion.EJ2.Blazor.DropDowns.SelectEventArgs args)
    {
        // Get New Index
        var idParts = args.Item.ID.Split('-');
        var itemIndex = Convert.ToInt32(idParts[1]);

        this.BuildGridColumns(configurations[itemIndex]);
    }

    public void OnGridCreated(object args)
    {
        this.BuildGridColumns(configurations[index]);
    }

    void BuildGridColumns(ODataConfigurationModel configuration)
    {
        var columns = grid.Columns as List<GridColumn> ?? new List<GridColumn>();

        columns.Clear();

        foreach (var field in configuration.DisplayFields)
        {
            var column = new GridColumn
            {
                HeaderText = field.DisplayName,
                Field = field.DataName,
                Width = field.Width,
                Format = field.Format,
                Visible = field.Visible
            };

            columns.Add(column);
        }

        grid.Columns = columns;
        grid.RefreshColumns();
        BuildDataManager(configuration);
    }

    void BuildDataManager(ODataConfigurationModel configuration)
    {
        Console.WriteLine("BuildDataManager - URL : " + RestClient.RootUrl + "odata/configurations/" + Guid.Empty.ToString() + "/data");
        var dataManager = new EjsDataManager();

        dataManager.CrossDomain = true;
        dataManager.Adaptor = Adaptors.WebApiAdaptor;
        dataManager.EnableCaching = false;
        dataManager.Url = RestClient.RootUrl + "odata/configurations/" + Guid.Empty.ToString() + "/data";
        dataManager.Offline = false;

        grid.DataSource = dataManager;
        grid.DataBind();
        grid.Refresh();
    }
}


Thanks in advance for your help.


Brice.


11 Replies

VN Vignesh Natarajan Syncfusion Team July 24, 2019 02:34 PM UTC

Hi Brice,  

Thanks for contacting Syncfusion forums.  

Query: “ I am failing to create/change columns of a Grid on the fly. Here's what I am trying to do : 

We suggest you to achieve your requirement (create column dynamically) using OnAfterRender lifecycle event in Blazor. Instead of Created event we suggest you to use OnAfterRender event to create columns and push the values to Columns property of Grid.  

Refer the below code example 


<EjsGrid @Ref=@grid AllowPaging="true" Width="100%" Height="100%"> 
    <GridPageSettings PageSize="5" /> 
</EjsGrid> 
 
@code{ 
    EjsGrid grid; 
    protected override void OnAfterRender() 
    { 
        List<GridColumn> col = new List<GridColumn>(); 
        col.Add(new GridColumn() { Field = "OrderID", HeaderText = "ID" }); 
        col.Add(new GridColumn() { Field = "CustomerID", HeaderText = "Name" }); 
        grid.Columns = col; 
        var dataManager = new EjsDataManager(); 
        dataManager.CrossDomain = true; 
        dataManager.Adaptor = Adaptors.WebApiAdaptor; 
        dataManager.EnableCaching = false; 
        dataManager.Offline = false; 
        grid.DataSource = dataManager; 
    } 
} 

For your convenience we have prepared a sample which can be downloaded from below  


Please get back to us if you have further queries.  

Regards, 
Vignesh Natarajan. 



GP Gerald Peng April 6, 2020 03:38 AM UTC

Hi Syncfusion,

I tried the solution below using version 18.1.0.42 and the assignment to grid.Columns = col; does not work anymore. Could you please confirm?

Thanks!




BF Brice FROMENTIN April 6, 2020 09:10 AM UTC

I have change my solution and user RenderFragment instead


VN Vignesh Natarajan Syncfusion Team April 7, 2020 11:18 AM UTC

Hi Gerald,  
 
Thanks for contacting Syncfusion forums.  
 
Query: “I tried the solution below using version 18.1.0.42 and the assignment to grid.Columns = col; does not work anymore 
 
We are not able to reproduce the reported issue at our end while using our latest version (18.1.0.42). To validate the reported issue, we have prepared to sample to update the column in the DataBound event of grid. Please find the sample from below  
 
 
Kindly get back to us with issue reproducible sample if you are still facing the issue. 
 
Regards, 
Vignesh Natarajan 




GP Gerald Peng April 10, 2020 08:22 PM UTC

Hi Vignesh,

Do you have a sample that uses async data loads and column data loads? 

I have tried to wire in your sample into my code and get an exception. The only difference I can see is the async. Other potential one is that I assign the toolbar objects in code, which has worked before I have programmatically assigned the columns.

Exception is:

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Syncfusion.Blazor
  StackTrace:
   at Syncfusion.Blazor.Grids.Internal.PropertyInfoHelper.CreateAccessor(PropertyInfo propertyInfo)



VN Vignesh Natarajan Syncfusion Team April 13, 2020 09:51 AM UTC

Hi Gerald,  

Thanks for the update.  

Query: “Do you have a sample that uses async data loads and column data loads? 

As per your suggestion we have modified the sample to load data asynchronously. But still we are not able to reproduce the reported issue at our end. Please find the modified sample from below  


Kindly share the following details to validate the reported issue and provide the solution as soon as possible.  

  1. Grid code example.
  2. If possible try to reproduce the reported issue in provided sample and revert back to us.  

Regards, 
Vignesh Natarajan. 



BF Brice FROMENTIN April 15, 2020 09:23 AM UTC

Thanks,

I created a sample for you illustrating the problem, no columns created even if i change the dropdown.

Attachment: DynamicGrid_a16ec7b4.7z


VN Vignesh Natarajan Syncfusion Team April 18, 2020 02:29 AM UTC

Hi Brice, 
 
Thanks for the sample.  
 
Currently we are validating your query. We will update you the further details by 21st April 2020.  
 
Till then we appreciate your patience.  
 
Regards, 
Vignesh Natarajan. 



VN Vignesh Natarajan Syncfusion Team April 21, 2020 10:51 AM UTC

Hi Brice,  

Thanks for the patience.  

As we face difficulties in running your sample, we have prepared a Blazor hosted application using model controller and model class. We are able to reproduce the reported issue while preparing a sample using your code example. For WebAPI adaptor, data source has to returned in form of Items and Count. But you have not returned the data in that form in WeatherForecast controller. And also you have changed the column in the DropDownList ValueChange event (i.e) Grid is being rendered. 
Hence the reported issue has occurred. We have modified the sample and achieved your requirement using DataBound event and Columns property of the Grid to change the column on the fly.  

Refer the below code example.  

[HttpGet]        public async Task<object> Get()        {            var rng = new Random();            var data = Enumerable.Range(1, 5).Select(index => new WeatherForecast            {                Date = DateTime.Now.AddDays(index),                TemperatureC = rng.Next(-20, 55),                Summary = Summaries[rng.Next(Summaries.Length)]            }).ToList().AsQueryable();            return new { Items = data, Count = 5 };        }


<SfGrid TValue="ExpandoObject" @ref="@grid" Columns="@Cols" EnableAltRow="true" Width="500px" Height="250px"> 
       <SfDataManager Adaptor="Adaptors.WebApiAdaptor" Url="/WeatherForecast" /> 
       <GridEvents DataBound="Data" TValue="ExpandoObject"></GridEvents> 
   </SfGrid> 
. . . . . ..   

// Configuration changed   protected void OnValueChanged(ChangeEventArgs<Guid> args)   {       json = (JObject)args.ItemData;       configuration = json.ToObject<OdqConfigurationModel>();       displayFields = configuration.DisplayFields;       // will be triggered only after Grid is rendered       if (Created)       {           var columns = new List<GridColumn>();           Cols = columns; // clearing the existing column           grid.RefreshColumns();            foreach (var field in displayFields)           {               var column = new GridColumn               {                   HeaderText = field.DisplayName,. . . . . . . . .               };                columns.Add(column);           }           Cols = columns; // assigning the columns to Grid           grid.RefreshColumns();       }   }   protected void Data()   {       if (!Created) // to be triggered only during initial rendering       {           var columns = new List<GridColumn>();           Cols = columns;           grid.RefreshColumns();           foreach (var field in displayFields)           {               var column = new GridColumn               {                   HeaderText = field.DisplayName,. . . . . .. . .                };                columns.Add(column);           }            Cols = columns;           grid.RefreshColumns();           Created = true;       }   }

Kindly download the sample from below  


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

Regards, 
Vignesh Natarajan 



BF Brice FROMENTIN April 23, 2020 06:19 AM UTC

Thanks for the answer, I finally succeed to implement it in my solution.

But I found another problem, when I change the value of the dropdown, 2 queries are triggered instead of only one.


VN Vignesh Natarajan Syncfusion Team April 27, 2020 02:11 PM UTC

Hi Brice,  
 
Query: “But I found another problem, when I change the value of the dropdown, 2 queries are triggered instead of only one. 
 
In the provided sample, we could see that GET request is sent multiple times during the initial rendering and while changing the values in dropdown. If you are referring to that issue, then we have modified the solution to hide and show the grid while updating the column. Previously we have used RefreshColumn method to refresh the column, where entire Grid is refreshed on switching the columns. Now we have modified the solution to show / hide the Grid using a Boolean variable. 
 
Refer the below code example.   
 
@if (showGrid || configuration != null) 
{ 
    <SfGrid TValue="ExpandoObject" @ref="@grid" Columns="@Cols" EnableAltRow="true" Width="500px" Height="250px"> 
        <SfDataManager Adaptor="Adaptors.WebApiAdaptor" Url="/WeatherForecast" /> 
        <GridEvents DataBound="Data" TValue="ExpandoObject"></GridEvents> 
    </SfGrid> 
} 
 
 
We have enabled a Boolean variable and we have updated the values of Boolean while updating the column.  
 
@code{    public bool showGrid = false;    public bool Created = false;    List<OdqDisplayFieldModel> displayFields = new List<OdqDisplayFieldModel>();    Guid currentId = Guid.Empty;     SfGrid<ExpandoObject> grid;    OdqConfigurationModel oldConfiguration;    OdqConfigurationModel configuration;    JObject json;    public List<GridColumn> Cols = new List<GridColumn>();     // Configuration changed    protected void OnValueChanged(ChangeEventArgs<Guid> args)    {        json = (JObject)args.ItemData;        configuration = json.ToObject<OdqConfigurationModel>();        displayFields = configuration.DisplayFields;        // will be triggered only after Grid is rendered        if (Created)        {            showGrid = false// hided the Grid            var columns = new List<GridColumn>();            Cols = columns; // clearing the existing column             foreach (var field in displayFields)            {. . . . . . .            }            Cols = columns;             showGrid = true; // displyed the Grid with udpated columns.        }    }    protected void Data()    {        if (!Created) // to be triggered only during initial rendering        {            showGrid = false;            var columns = new List<GridColumn>();            foreach (var field in displayFields)            {. . . . . ..             }             Cols = columns;            Created = true;             showGrid = true// displyed the Grid with udpated columns.         }    }}
 
 
Please find the modified sample from below  
 
Kindly get back to us if you have further queries.  
 
Regards, 
Vignesh Natarajan 


Loader.
Live Chat Icon For mobile
Up arrow icon