Skip to content

Infragistics Community Forum / Web / Ignite UI for Angular / Grid Data Binding, Filtering, Sorting & Grouping

Grid Data Binding, Filtering, Sorting & Grouping

New Discussion
Mark P
Mark P asked on Jul 10, 2019 10:57 AM

Hi,

Following on from this question and the provided sample:

“I don’t want to map fields of the [data]-input 1:1 onto the grid, I want to compose 1 column out of several fields, basically an n:1 relation.

I want to connect several fields with a function, and the displaying the function result.

My first idea was creating my own object for this and filling it onInit, but I got the impression igx can’t display static local data.

Right now my solution is somewhat ugly.

<igx-column width="200px" field="primaryKey" header="zb" dataType="number">
    <ng-template igxCell let-cell="cell">
        <span>{{get_zbValue(cell.value)}}</span>
    </ng-template>
</igx-column>

I take the id, and then use a function that uses it to get the data and compose the value I want. This seems horrible performance wise, even though I already have the data locally an ddon’t need to pull it from a webservice.”

“The grid columns do not support composite keys out of the box but you can still create a column out of several other columns.

Inside the cell template context the `cell` object itself has a reference to the row and the row data itself so you can access any field inside your data model object. You can also use the row data itself and pass it to a method/pipe in your case.

I’ve prepared a sample with 2 grids, one bound to a array of flat objects and one bound to a more nested version of the objects where the User Details column is composed out of 3 different data fields.”

https://stackblitz.com/edit/angular-ea5meq

In the example where the grid is bound to the nested data source, I am looking for ways to implement Filtering, Sorting & Grouping on a similar column where an ng-template is used for the grid column and the column is bound to an object.

Can anyone provide an example where this is implemented, or extend the above sample to demonstrate?

Sign In to post a reply

Replies

  • 0
    Hristo Anastasov
    Hristo Anastasov answered on Jul 3, 2019 1:28 PM

    Hi Mark,

    I have created a sample demonstrating how to do Filtering on such a column in the igxGrid, please feel free to explore it here.

    What is important to note is that I have bound an external input for filtering the data, instead of using the default UI, which I am not sure would be achieved ( will confirm later).

    In the input change event, we need to:

    1) create a filtering expressions tree, based on the value entered and filter the data collection using those expressions

    2) Pass the filtered data to the grid

        public filter(term) {
          const filtExpressionsTree = new FilteringExpressionsTree(FilteringLogic.Or);
          filtExpressionsTree.filteringOperands = [
                      {
                        fieldName: "name",
                        condition: IgxStringFilteringOperand.instance().condition("contains"),
                        searchVal: term},
                      {
                        fieldName: "email",
                        condition: IgxStringFilteringOperand.instance().condition("contains"),
                        searchVal: term
                      }
                    ];
          const state: IFilteringState = { expressionsTree: filtExpressionsTree, strategy: new SimpleFilteringStrategy() };
          const filteredData = DataUtil.filter(this.nestedData, state);
          this.grid1.data = filteredData;
      }
    }

    Will update you later with details on how to implement the sorting as well.

    Hristo

    • 0
      Mark P
      Mark P answered on Jul 4, 2019 7:00 AM

      Hi Hristo,

      Thanks for providing the sample.

      I am also interested in filtering by a single property of a column bound to an object using the grid UI. I have seen a way to do this in the below question and sample:

      https://es.infragistics.com/community/forums/f/ignite-ui-for-angular/119621/default-filtering-with-ng-template

      https://stackblitz.com/edit/angular-hyy2sb-zzmxdu

      I am now looking for a way to extend this UI filtering sample to make the CustomStringFilter reusable across string properties with different names.

      Currently the sample filter is set to look for a field called 'link'. It would be good if this could be modified to take an object and a string containing the name of the property to filter by.

      Appreciate I would need different logic for e.g. filtering strings and dates but would like to reuse the filtering logic for the same data types instead of creating separate similar filters for many different grid columns across my application.

      I am looking for a flexible, reusable way to filter/sort/group a column where an object and the name of a single object property to use can be provided to custom filtering/sorting/grouping logic.

      Thanks,

      Mark

      • 0
        Hristo Anastasov
        Hristo Anastasov answered on Jul 4, 2019 10:28 AM

        Hello Mark,

        The sample that you shared demonstrate the other way to achieve filtering on a column, whose value is compound of other columns` values. As you see it is not that effective to use it, as you need to implement all conditions for the custom operand, while the only thing that is changed in regards to the default conditions is the logic method.

        The ideal way to solve this issue would be the ability to provide a custom filtering strategy per column and I am going to log this as a feature request in our product, and I will provide you with the link to the issue. Meanwhile I will try to find other ways to improve this approach in order not to hardcode values like "link" and achieve reusability.

        I will keep you posted.

        Hristo

    • 0
      Hristo Anastasov
      Hristo Anastasov answered on Jul 8, 2019 12:58 PM

      Hi Mark,

      I have updated the sample to do Sorting and Grouping on the use column, based on the registered value of the user:

      https://stackblitz.com/edit/angular-cscspe

      Please note that to achieve the above, is required to:

      1) Define a custom sortStrategy, that extends the DefaultSortingStrategy. We need to override the compareObjects method, to work with the "registered" field of the object. Also, define a custom groupingComparer function for the column, that will work with the "registered" field of the object

      sortingStrategy = CustomSortingStrategy.instance();
      groupingComparer = (a: any, b: any) => { return a.registered === b.registered ? 0 : 1; };
      export class CustomSortingStrategy extends DefaultSortingStrategy {
        protected compareObjects()
            …

            return reverse * this.compareValues(a.registered, b.registered);

          }
      }

      2) Set the custom strategy and groupingComparer inputs for the column:

      <igx-column field="user" [sortStrategy]="sortingStrategy"
      [groupingComparer]="groupingComparer">

      Please let me know if you have further questions, I will be glad to help!

      Hristo

      • 0
        Mark P
        Mark P answered on Jul 8, 2019 1:39 PM

        Hi Hristo,

        Thanks for the update. I’ve also been working on this and have another approach which seems to work for me at the moment.

        For example in my application I have a “client”.

        First define a class for the data which will be bound to the column and override the toString() method.

        Then map data from the API to the class before binding to the grid column.

        This way I am able to use the built in sorting, filtering and grouping functions of the grid, so I don’t have any repeated code for the various strategies that are otherwise required. This approach also removes the need to use an ng-template for displaying the cell. For editing I am using an ng-template with an igx-select component.

        I think your example with the custom strategies will also be useful for more complex scenarios.

        Do you have any comments on my approach, or any reason not to use this approach with the Ignite UI components?

        Regards,

        Mark

      • 0
        Hristo Anastasov
        Hristo Anastasov answered on Jul 8, 2019 2:27 PM

        Hi Mark,

        I am not able to evaluate any reasons for not to use this approach. However, I am not exactly sure how this would work, if it is only mapping the data to the corresponding type. Our source code works with the object itself, not  with the value, returned by the toString() method exposed by the object.

        Hristo

      • 0
        Mark P
        Mark P answered on Jul 8, 2019 3:49 PM

        Hi Hristo,

        In the following sample I used the approach with a class and toString() implementation.

        https://stackblitz.com/edit/angular-cscspe-weaqaa

        If you comment out the toString() implementation in the User class then the "User Details" column will display [object Object] in every row as this is returned by the default implementation of toString().

        With the toString implemented in the class, it will display the required value and sorting, filtering and grouping are working based on the value retured by toSting().

        This approach will only work if we want to sort, filter & group by the same property or properties of the object.

        It seems that toString() is called when binding to an object in order to get a string representation of the object, I guess this is done internally by Angular, rather than the Ignite UI code although haven't looked into that in any detail.

        Regards,

        Mark

      • 0
        Hristo Anastasov
        Hristo Anastasov answered on Jul 9, 2019 7:24 AM

        Hi Mark !

        As documentation says:

        "Every object has a toString() method that is automatically called when the object is to be represented as a text value or when an object is referred to in a manner in which a string is expected."

        For example, default filtering conditions in the IgniteUI for Angular treat the value as string, which actually calls the .toString() override:

        export class IgxStringFilteringOperand extends IgxFilteringOperand {
        ...
        logic: (target: string, searchVal: string, ignoreCase?: boolean) => {
              // target will be the value returned by the .toString() override
        ...

        When doing sorting and grouping, the JavaScript compare operator will attempt to convert the object to a primitive value, therefore it again uses the override of the toString() method.

        There are no issues to consider about this approach, it is solid. Just you need to decide if you would be satisified with the grouping that is being done. but even in this case you may supplement the implementation with a custom sorting strategy and a grouping comparer.

        Hristo

      • 0
        Mark P
        Mark P answered on Jul 10, 2019 10:57 AM

        Hi Hristo,

        Thanks for confirming. I will continue with the toString() approach where I can and use the custom strategy approach where needed.

        Thanks for your assistance.

        Mark

  • You must be logged in to reply to this topic.
Discussion created by
Favorites
Replies
Created On
Last Post
Discussion created by
Mark P
Favorites
0
Replies
9
Created On
Jul 10, 2019
Last Post
6 years, 7 months ago

Suggested Discussions

Created by

Created on

Jul 10, 2019 10:57 AM

Last activity on

Feb 24, 2026 9:07 AM