What are "data operations"

This article will guide you through the process of enabling one or all of the data operations available as built-in functionality into the RadListView. The component provides all of the basic data operations with an easy to use API that enables powerful configuration of the grouping, filtering and sorting criteria to achieve any desired configuration of the displayed items in the RadListView.

By 'data operations' in the context of the RadListView we mean doing operations on the 'raw' source collection that is set to the items property. Those operations can be grouping, sorting and filtering. Each one can be used separately or combined with the others, this way you can filter the items and group them without changing the 'raw' business object collection you have provided to the items.

Grouping

In order to enable grouping you simply need to set the groupingFunction property to a function that simply returns the object which will be used as criteria for grouping functionality. Here is a simple example of such function:

get myGroupingFunc(): (item: any) => any {
    return (item: DataItem) => {
        return item.category;
    };
}

Sorting

Sorting is enabled by simply setting the sortingFunction property to a function that takes two parameters and returns 0 (the params are equal), 1 (first param is greater) or -1 (second param is greater). Here is a simple example of such function:

get mySortingFunc(): (item: any, otherItem: any) => number {
    return (item: DataItem, otherItem: DataItem) => {
        var res = item.id < otherItem.id ? -1 : item.id > otherItem.id ? 1 : 0;
        return res;
    };
}

Filtering

To enable filtering in the RadListView simply set its filteringFunction property to a function that takes two parameters and returns 0 (the params are equal), 1 (first param is greater) or -1 (second param is greater). Here is a simple example of such function:

get myFilteringFunc(): (item: any) => boolean {
    return (item: DataItem) => {
        return item.itemName.includes("Special Item");
    };
}

Example 1: Implementing grouping, filtering and sorting

In this example we are going to enable all of the data operations on the same RadListView with the following criteria:

  • Filter the business objects which itemName property contains the string "Special Item"
  • Sort the business objects by the value of their id property
  • Group the business objects by the value of their category property
<GridLayout rows="*, 7*">
    <StackLayout orientation="horizontal">
        <Button width="33%" text="{{isFilteringEnabled ? 'Disable filtering' : 'Enable filtering'}}" tap="toggleFilter"/>

        <Button width="33%" text="{{isSortingEnabled ? 'Disable sorting' : 'Enable sorting'}}" tap="toggleSorting"/>

        <Button width="33%" text="{{isGroupingEnabled ? 'Disable grouping' : 'Enable grouping'}}" tap="toggleGrouping"/>

    </StackLayout>
    <lv:RadListView id="myListView" row="1" items="{{ dataItems }}" 

                    sortingFunction="{{ mySortingFunc }}"

                    filteringFunction="{{ myFilteringFunc }}"

                    groupingFunction="{{ myGroupingFunc }}">

        <lv:RadListView.itemTemplate>
            <StackLayout orientation="vertical">
                <Label fontSize="20" text="{{ itemName }}"/>

                <Label fontSize="14" text="{{ itemDescription }}"/>

            </StackLayout>
        </lv:RadListView.itemTemplate>
    </lv:RadListView>
</GridLayout>
import { ViewModel } from "./multiple-model";
import { Page } from "tns-core-modules/ui/page";
import { RadListView } from "nativescript-pro-ui/listview";

var page: Page;
var bindingContext: ViewModel;

export function onPageLoaded(args) {
    page = args.object;
    bindingContext = new ViewModel();
    page.bindingContext = bindingContext;
}

export function toggleFilter() {
    var listView = page.getViewById("myListView") as RadListView;
    if (!listView.filteringFunction) {
        listView.filteringFunction = bindingContext.myFilteringFunc;
        bindingContext.isFilteringEnabled = true;
    } else {
        listView.filteringFunction = undefined;
        bindingContext.isFilteringEnabled = false;
    }
}

export function toggleSorting() {
    var listView = page.getViewById("myListView") as RadListView;
    if (!listView.sortingFunction) {
        listView.sortingFunction = bindingContext.mySortingFunc;
        bindingContext.isSortingEnabled = true;
    } else {
        listView.sortingFunction = undefined;
        bindingContext.isSortingEnabled = false;
    }
}

export function toggleGrouping() {
    var listView = page.getViewById("myListView") as RadListView;
    if (!listView.groupingFunction) {
        listView.groupingFunction = bindingContext.myGroupingFunc;
        bindingContext.isGroupingEnabled = true;
    } else {
        listView.groupingFunction = undefined;
        bindingContext.isGroupingEnabled = false;
    }
}
import { ObservableArray } from "tns-core-modules/data/observable-array";
import * as timer from "tns-core-modules/timer";
import { Observable } from"tns-core-modules/data/observable";

export class ViewModel extends Observable {

    private _items: ObservableArray<DataItem>;
    private _words = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"];

    constructor() {
        super();
        this.set("_items", new ObservableArray<DataItem>(items));
        this.isGroupingEnabled = true;
        this.isFilteringEnabled = true;
        this.isSortingEnabled = true;
    }

    get isGroupingEnabled() {
        return this.get("_isGroupingEnabled");
    }

    set isGroupingEnabled(value: boolean) {
        this.set("_isGroupingEnabled", value);
    }

    get isFilteringEnabled() {
        return this.get("_isFilteringEnabled");
    }

    set isFilteringEnabled(value: boolean) {
        this.set("_isFilteringEnabled", value);
    }

    get isSortingEnabled() {
        return this.get("_isSortingEnabled");
    }

    set isSortingEnabled(value: boolean) {
        this.set("_isSortingEnabled", value);
    }

    get dataItems() {
        return this.get("_items");
    }

    get myGroupingFunc(): (item: any) => any {
        return (item: DataItem) => {
            return item.category;
        };
    }

    get myFilteringFunc(): (item: any) => any {
        return (item: DataItem) => {
            return item.itemName.includes("Special Item");
        };
    }

    get mySortingFunc(): (item: any, otherItem: any) => number {
        return (item: DataItem, otherItem: DataItem) => {
            var res = item.id < otherItem.id ? -1 : item.id > otherItem.id ? 1 : 0;
            return res;
        };
    }

    private getRandomLengthString() {
        var sentenceLength = Math.round((Math.random() * 15));
        var result = this._words[0];
        for (var i = 0; i < sentenceLength; i++) {
            result += (this._words[i % this._words.length] + " ");
        }
        return result;
    }
}

export class DataItem {
    public id: number;
    public itemName: string;
    public itemDescription: string;
    public category: string;

    constructor(id: number, name: string, description: string, category: string) {
        this.id = id;
        this.itemName = name;
        this.itemDescription = description;
        this.category = category;
    }
}

var items: DataItem[] = [
    new DataItem(89, "Special Item 89", "This is item category is: Category 1", "Category 1"),
    new DataItem(23, "Item 23", "This is item category is: Category 2", "Category 2"),
    new DataItem(1, "Item 1", "This is item category is: Category 1", "Category 1"),
    new DataItem(34, "Item 34", "This is item category is: Category 3", "Category 3"),
    new DataItem(55, "Special Item 55", "This is item category is: Category 3", "Category 3"),
    new DataItem(78, "Item 78", "This is item category is: Category 1", "Category 1"),
    new DataItem(5, "Item 5", "This is item category is: Category 1", "Category 1"),
    new DataItem(111, "Special Item 111", "This is item category is: Category 2", "Category 2"),
    new DataItem(665, "Special Item 665", "This is item category is: Category 2", "Category 2"),
    new DataItem(1134, "Item 1134", "This is item category is: Category 1", "Category 1"),
    new DataItem(22, "Special Item 22", "This is item category is: Category 3", "Category 3"),
    new DataItem(345, "Item 345", "This is item category is: Category 1", "Category 1"),
    new DataItem(80, "Item 80", "This is item category is: Category 1", "Category 1"),
    new DataItem(54, "Item 54", "This is item category is: Category 3", "Category 3"),
];

This will produce the following UI with the filtered, sorted and grouped objects:

Figure 1: Grouping, filtering and sorting enabled in RadListView:

RadListView Data-Operations on iOS RadListView Data-Operations on Android

References

Want to see this scenario in action?
Check our SDK examples repo on GitHub. You will find this and many other practical examples with NativeScript UI.

Related articles you might find useful: