Overview: Item Selection states

When using Item Selection with RadListView one would want to have a different visual state for selected vs. deselected items. The default selection behavior of RadListView differs in terms of how selection is represented. It is a common scenario to unify the behavior by providing a single visual representation for the state of the items. This article represents a step-by-step guide for implementing visual states for the item containers depending on whether they are selected or not.

Prerequisites

For the purposes of this article, we need to have a RadListView instance defined on our page with the following properties set:

We also need to provide handlers and subscribe for the following events:

Implementing selection states

The item 'model'

When implementing a visual state we normally associate a given property of a visual element with a property value on our model or Angular 'Component'. We create a 'binding' which makes sure that once the model property changes the container's appearance is also changed. For that purpose we will create a selected property in our Component's 'data item' object. After that we will update this property when an item is selected/deselected and will wire the background color of the container to it.

Using instances of this class we go on and create an ObservableArray of objects that we will bind to the items.

export class DataItem {
    constructor(public id?: number, public name?: string, public description?: string, public title?: string, public text?: string, public image?: string, public selected?: boolean, public type?: string) {
    }
}
import { Component, OnInit } from "@angular/core";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { DataItem } from "../dataItem";
import { DataItemService } from "../dataItem.service";
import { ListViewEventData } from "nativescript-telerik-ui-pro/listview";

@Component({
    moduleId: module.id,
    selector: "tk-listview-selection-states",
    providers: [DataItemService],
    templateUrl: "listview-selection-states.component.html",
    styleUrls: ["listview-selection-states.component.css"]
})
export class ListViewSelectionStatesComponent implements OnInit {
    private _dataItems: ObservableArray<DataItem>;

    constructor(private _dataItemService: DataItemService) {
    }

    get dataItems(): ObservableArray<DataItem> {
        return this._dataItems;
    }

    ngOnInit() {
        this._dataItems = new ObservableArray(this._dataItemService.getIdenticalDataItems(25));
    }

    public itemSelected(args: ListViewEventData) {
        var item = this.dataItems.getItem(args.index);
        item.selected = true;
    }

    public itemDeselected(args: ListViewEventData) {
        var item = this.dataItems.getItem(args.index);
        item.selected = false;
    }
}

The UI

Essential part of the implementation of 'Item Selection States' is the template that defines the item's visual structure. To update the appearance of the containers according to the selection state we will update the background color of the root element of each container. For that purpose we will create a HTML binding to the selected property defined on our DataItem objects. This binding will return red when the item is selected and white when the item is deselected. Here's the tkListItemTemplate of the RadListView:

<ng-template tkListItemTemplate let-item="item">
    <StackLayout [backgroundColor]="item.selected ? 'red' : 'white'">
        <Label class="nameLabel" [text]="item.name"></Label>
        <Label class="descriptionLabel" [text]="item.description"></Label>
    </StackLayout>
</ng-template>

Handling the 'itemSelected' and 'itemDeselected' events

The last part of the task is to update the selected property of the DataItems when the selection state is changed. This is done using the corresponding selection events exposed by RadListView:

The snippet demonstrates how these events are subscribed for:

<RadListView [items]="dataItems" row="1" multipleSelection="true" selectionBehavior="Press" (itemSelected)="itemSelected($event)"
    (itemDeselected)="itemDeselected($event)">

Having the selected property defined on our business objects we update this property as follows:

public itemSelected(args: ListViewEventData) {
    var item = this.dataItems.getItem(args.index);
    item.selected = true;
}

public itemDeselected(args: ListViewEventData) {
    var item = this.dataItems.getItem(args.index);
    item.selected = false;
}