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

Sorting Grid with dynamic data using Column Templates seems to sort on all columns and filter all data?

I am working on an app which uses a grid to display some very dynamic data, the contents (field names, column count, row count) are NOT known at design time, so the data is held in a custom class which has some column metadata (headings, field types, etc) as one property and the data itself represented via an IEnumerable<IEnumerable<string>>, so the overall data looks like this:


public class GridData
{
    /// <summary>
    /// This has the definitions of the columns in it...
    /// </summary>
    public List<ColumnDef> ColumnDefs{ get; set; }

    //then this has the Row data in it - everything's a string for now.
    //each entry in the "outer" IEnumerable represents a row, and then
    //for that entry each entry in that "inner" IEnumerable is a single cell.
    public IEnumerable<IEnumerable<string>> RowData{ get; set; }
}

So I can't define the columns in the grid at design time, and I cannot refer to the properties which make up the columns in each row by field name, as they are all entries in an IEnumerable.  I have managed to get this to work OK using Templates for the columns in a loop:


<SfGrid
    TValue="IEnumerable<string>"
    DataSource="@_gridData.RowData"
    AllowSorting="true"
    >


    <GridColumns>
        @foreach (var c in _gridData.ColumnDefs)
    {
            <GridColumn
                HeaderText="@c.Name"
            AllowSorting="true"
            Uid="@c.Idx.ToString()"
            >
        <Template>
            @{
                var row = (context as List<string>);
                var thisField = row[c.Idx];
                <span>@thisField</span>
            }
        </Template>
        </GridColumn>
    }
    </GridColumns>

</SfGrid>

But the problem with this is the sorting doesn't work at all - when I click a column heading, the grid appears to show that all​ columns are "sorted" (via small arrows) but all the data vanishes completely.  if I click again, the arrow switches to indicate descending sorting (still no data) and a third click results in removal of the arrows (unsorted) and the data re-appears.

It looks to me like it is struggling to uniquely identify the column being sorted.

I will need to customise the sorting a bit (as the data is all represented as strings, so I'll need to apply some custom comparison to convert to int/float/date/etc to sort correctly) but I didn't anticipate it behaving like this.

I have attached a minimal project which broadly illustrates the problem.  It just generates some random data on load to represent the variability present in the actual application.

I accept I'm doing something a bit wrong here, but could you explain how to fix this sorting issue, and how I might "inject" a custom comparison method somewhere?

Thanks


Attachment: DynamicGrid_cb55f913.zip

5 Replies

GW Giles Wakefield January 3, 2023 09:15 AM UTC

Hi,


I appreciate that we've had the festive season, but I've seen no indication that anyone has considered this yet - I've only received an email confirmation that I've posted to the forum and nothing else, and normally there's some response within a day or two - has this slipped through some cracks?



SG Suganya Gopinath Syncfusion Team January 4, 2023 01:37 PM UTC

Giles, 

Sorry for the inconvenience caused. 

Team will get back to you with the details shortly. 

Regards,

Suganya Gopinath. 



VN Vignesh Natarajan Syncfusion Team January 5, 2023 04:31 AM UTC

Hi Giles,


Sorry for the delay in getting back to you.


Query:” But the problem with this is the sorting doesn't work at all - when I click a column heading, the grid appears to show that all​ columns are "sorted" (via small arrows) but all the data vanishes completely.


We would like to inform you that the Field property of the GridColumn component is necessary to perform the Data Operations (Filtering, Sorting, searching, etc.) in Grid. Based on the Field property value only data only sorting will take place. If you have displayed the values using the Template feature, then the Field property is necessary to perform sorting. This is default behavior of the Grid.


Refer to our UG documentation note section for your reference



https://blazor.syncfusion.com/documentation/datagrid/columns


We request you define the Field property of the Grid with the correct value to resolve the reported issue. If the Field values are not known during the definition, we request you to fetch the datasource first and identify the columns and then render the SfGrid column with the known column name.


Please get back to us if you require any further assistance from us. We are happy to assist you.


Regards,

Vignesh Natarajan



GW Giles Wakefield replied to Vignesh Natarajan January 5, 2023 01:15 PM UTC

OK, well as I pointed out in great detail there is no Column Name​.  The column values are just an index into a List, and I cannot see how to specify the "Field" using an index like this.

I have for now worked around this problem by making my "Data Row" class inherit from DynamicObject and in effect make all my index-based properties accessible via "properties" named "__F78" or similar, and the overridden TryGetMember method parses this property name to find the appropriate entry in the list.  


Can I suggest you add a property to DataColumn which allows you to specify a function which can retrieve the "ValueForSortingAndFiltering" or something?  so you could optionall do something like this and avoid having to "name" fields in this way:

<GridColumns>
    @foreach (var c in _gridData.ColumnDefs)
{
        <GridColumn
            HeaderText="@c.Name"
            AllowSorting="true"
            Uid="@c.Idx.ToString()"
            ValueForSortingAndFiltering="@GetThisFieldValue(context,c)")"
            >
         <Template>
           @{
                var row = (context as SingleRowData);
                var thisField = row[c.Idx];
                <span>@thisField</span>
            }
        </Template>
        </GridColumn>
    }
    </GridColumns>
...

@code
{
    ...
    private string GetThisFieldValue(RowData rowItem, ColumnDef colDef)
{
return rowItem[colDef.FieldIndex];
}
}



VN Vignesh Natarajan Syncfusion Team January 6, 2023 04:52 AM UTC

Hi Giles,


Thanks for your update and suggestions.


Query: “The column values are just an index into a List, and I cannot see how to specify the "Field" using an index like this. && Can I suggest you add a property to DataColumn which allows you to specify a function which can retrieve the "ValueForSortingAndFiltering" or something?  


We understand your requirement of adding a property to GridColumn, but as informed in the previous update. DataOperation like filtering, sorting, and searching actions and CRUD operations like Insert, Update, and delete actions will take place based on the Field property only. It will not be possible for us to perform sorting or filtering operations based on the values alone without using the Field property.


Also, we would like to inform you that the datasource can be assigned to Grid either using the DataSource property or the SfDataManager component. So once the sorting operation is initiated at the column level we generate the sorting query/predicates and send that predicates either to SfDataManager or built-in Adaptor to perform the corresponding operations. This is the default behavior of Grid. So it will not be possible for us to consider your requirement of providing property to GridColumn and perform the data operation.


Regards,

Vignesh Natarajan


Loader.
Live Chat Icon For mobile
Up arrow icon