Angular List View Component Overview

    The Ignite UI for Angular List component displays rows of items and supports one or more header items as well as search and filtering of list items. Each list item is completely templatable and supports any valid HTML or Angular component. The list component also providers built in panning functionality, templates for empty and loading states, and supports virtualization for large lists using the IgxForOf directive.

    Angular List Example

    The following example represents a list populated with contacts with a name and a phone number properties. The IgxList component uses igx-avatar and igx-icon to enrich the user experience and expose the capabilities of setting avatar picture and different icon for favorite a contact. In addition, the List View expose sorting capabilities achieved by using our filtering pipe.

    Getting Started with Ignite UI for Angular List

    To get started with the Ignite UI for Angular List View component, first you need to install Ignite UI for Angular. In an existing Angular application, type the following command:

    ng add igniteui-angular
    

    For a complete introduction to the Ignite UI for Angular, read the getting started topic.

    The next step is to import the IgxListModule in the app.module.ts file.

    Note

    This component requires HammerModule to be imported in the root module of the application in order for touch interactions to work as expected..

    // app.module.ts
    
    import { HammerModule } from '@angular/platform-browser';
    import { IgxListModule } from 'igniteui-angular';
    // import { IgxListModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        ...
        imports: [..., IgxListModule, HammerModule],
        ...
    })
    export class AppModule {}
    

    Alternatively, as of 16.0.0 you can import the IgxListComponent as a standalone dependency, or use the IGX_LIST_DIRECTIVES token to import the component and all of its supporting components and directives.

    // home.component.ts
    
    import { HammerModule } from '@angular/platform-browser';
    import { IGX_LIST_DIRECTIVES } from 'igniteui-angular';
    // import { IGX_LIST_DIRECTIVES } from '@infragistics/igniteui-angular'; for licensed package
    
    @Component({
        selector: 'app-home',
        template: `
        <igx-list>
            <igx-list-item isHeader="true">Header</igx-list-item>
            <igx-list-item>Item 1</igx-list-item>
            <igx-list-item>Item 2</igx-list-item>
            <igx-list-item>Item 3</igx-list-item>
        </igx-list>
        `,
        styleUrls: ['home.component.scss'],
        standalone: true,
        imports: [IGX_LIST_DIRECTIVES, HammerModule]
        /* or imports: [IgxListComponent, IgxListItemComponent, HammerModule] */
    })
    export class HomeComponent {}
    

    Now that you have the Ignite UI for Angular List module or directives imported, you can start using the igx-list component.

    Using the Angular List

    Then in the template of our contacts component we can create our list, but what if currently (or at some point in the future) we have no items in it? In this case, the Angular list provides us with a default template that is used when the list is empty. We can always provide our own template for the look of our empty list by simply using the igxEmptyList directive. In this case, the default template will not be used:

    <!--contacts.component.html-->
    
    <igx-list>
        <ng-template igxEmptyList>
            <p class="empty">No contacts! :(</p>
        </ng-template>
    </igx-list>
    

    And our style for the empty template:

    /* contacts.component.css */
    
    .empty {
        color: rgba(0, 153, 255, 1);
        font-size: 25px;
        font-weight: 600;
        text-shadow: 2px 1px 2px rgba(150, 150, 150, 1);
    }
    

    If all went great, this is how our empty list should look like:

    Sometimes there may be a delay in your data loading. In this case you can set the list's isLoading property to true and a default template will inform the user regarding the ongoing data loading process. You can also provide your own loading template using the igxDataLoading directive:

    <!--contacts.component.html-->
    
    <igx-list>
        <ng-template igxDataLoading>
            <p class="loading">Patience, we are currently loading your data...</p>
        </ng-template>
    </igx-list>
    
    /* contacts.component.css */
    
    .loading {
        color: rgba(255, 153, 0, 1);
        font-size: 25px;
        font-weight: 600;
        text-shadow: 2px 1px 2px rgba(150, 150, 150, 1);
    }
    

    Add List Items

    It's nice having a template for when the list is empty, but now let's add some items! We can add the following code to get a simple list of items:

    <!--contacts.component.html-->
    
    <igx-list>
        <igx-list-item isHeader="true">Header</igx-list-item>
        <igx-list-item>Item 1</igx-list-item>
        <igx-list-item>Item 2</igx-list-item>
        <igx-list-item>Item 3</igx-list-item>
    </igx-list>
    

    If all went well, you should see the following in your browser:

    Let's up our game a bit and enhance our list items. Say we want to create an Angular list of contacts with a name and a phone number displayed under the name. In our component typescript file we can define a list of contacts:

    // contacts.component.ts
    ...
    public contacts = [{
        name: "Terrance Orta",
        phone: "770-504-2217"
    }, {
        name: "Richard Mahoney",
        phone: "423-676-2869"
    }, {
        name: "Donna Price",
        phone: "859-496-2817"
    }, {
        name: "Lisa Landers",
        phone: "901-747-3428"
    }, {
        name: "Dorothy H. Spencer",
        phone: "573-394-9254"
    }];
    

    Now that we have some data we want to render, let's set up some markup. If we want some styling out of the box we can use some of the directives that come with the list items.

    Let's look at how we can use some of them in the next example:

    <!--contacts.component.html-->
    
    <igx-list>
      <igx-list-item isHeader="true">
        Contacts
      </igx-list-item>
      <igx-list-item *ngFor="let contact of contacts">
        <h4 igxListLineTitle>{{ contact.name }}</h4>
        <p igxListLineSubTitle>{{ contact.phone }}</p>
      </igx-list-item>
    </igx-list>
    

    Both directives igxListLineTitle and igxListLineSubTitle gives our list items some default look.

    After all that our Angular list should now look like that:

    Adding Avatar and Icons

    We can use some of our other components in conjunction with the IgxList component to enrich the experience and add some functionality. We can have a nice picture avatar to the left of the name and phone values. Additionally, we can add a star icon to the right of them to allow the user to favorite a contact. To do that let's grab the IgxAvatar and IgxIcon modules and import them in our app.module.ts file.

    // app.module.ts
    
    ...
    import {
        IgxListModule,
        IgxAvatarModule,
        IgxIconModule
    } from 'igniteui-angular';
    // import { IgxListModule, IgxAvatarModule, IgxIconModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        ...
        imports: [..., IgxAvatarModule, IgxIconModule],
    })
    export class AppModule {}
    

    Next, we need to add some more information to our contact object, like a photo source for our avatar and a isFavorite property to indicate the contact's favorite status.

    // contacts.component.ts
    
    public contacts = [{
        name: 'Terrance Orta',
        phone: '770-504-2217',
        photo: 'https://randomuser.me/api/portraits/men/27.jpg',
        isFavorite: false
    }, {
        name: 'Richard Mahoney',
        phone: '423-676-2869',
        photo: 'https://randomuser.me/api/portraits/men/1.jpg',
        isFavorite: true
    }, {
        name: 'Donna Price',
        phone: '859-496-2817',
        photo: 'https://randomuser.me/api/portraits/women/50.jpg',
        isFavorite: false
    }, {
        name: 'Lisa Landers',
        phone: '901-747-3428',
        photo: 'https://randomuser.me/api/portraits/women/3.jpg',
        isFavorite: false
    }, {
        name: 'Dorothy H. Spencer',
        phone: '573-394-9254',
        photo: 'https://randomuser.me/api/portraits/women/67.jpg',
        isFavorite: true
    }];
    

    Cool, now let's update the template for our contacts list to show the avatar and icon. Again we can do that by using some of the list directives.

    <!--contacts.component.html-->
    
    <igx-list>
      <igx-list-item isHeader="true">
        Contacts
      </igx-list-item>
      <igx-list-item #item *ngFor="let contact of contacts;">
          <igx-avatar igxListThumbnail [src]="contact.photo" shape="circle"></igx-avatar>
          <h4 igxListLineTitle>{{ contact.name }}</h4>
          <p igxListLineSubTitle class="phone">{{ contact.phone }}</p>
          <span igxListLine>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta, laborum.</span>
          <igx-icon igxListAction [color]="contact.isFavorite ? 'orange' : 'lightgray'" (click)="toggleFavorite(item)">star</igx-icon>
      </igx-list-item>
    </igx-list>
    
    • igxListThumbnail is meant to be used if we need to add some kind of media at the beginning of our list items. The directive will wrap the target element in our case igx-avatar in a container that will provide some default position and spacing.
    • igxListAction is meant to be used for list items that have some kind of action or metadata, for example, switch, radio-button, checkbox, etc. In our case the action is will be represented by an igx-icon. Again, the directive will wrap the target element in a container that will have the correct position and spacing.
    • igxListLine is meant to be used if we need some text in-between igxListThumbnail and igxListAction the directive will make sure that the text position, spacing and alignment will look great with the other two directives around.

    Next we listen for a click event on the IgxIcon component to toggle the isFavorite property in our contact object.

    // contacts.component.ts
    
    ...
    toggleFavorite(item: IgxListItem) {
        const contact = this.contacts[item.index - 1];
        contact.isFavorite = !contact.isFavorite;
    }
    

    Let's also allow the user to choose the size of the list by using the --ig-size CSS custom property. We will do this by importing the IgxButtonGroupModule and using the IgxButtonGroup to display all size values. This way whenever one gets selected, we will update the size of the list.

    // app.module.ts
    ...
    import { IgxButtonGroupModule } from 'igniteui-angular';
    // import { IgxButtonGroupModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        imports: [..., IgxButtonGroupModule]
    })
    
    <!--contacts.component.html-->
    
    <igx-buttongroup [values]="sizes" (selected)="selectSize($event)"></igx-buttongroup>
    ...
    <igx-list>
        ...
    </igx-list>
    
    // contacts.component.ts
    
    public size = 'large';
    public sizes;
    
    public ngOnInit() {
        this.sizes = [
            { label: 'large', selected: this.size === 'large', togglable: true },
            { label: 'medium', selected: this.size === 'medium', togglable: true },
            { label: 'small', selected: this.size === 'small', togglable: true }
        ];
    }
    
    public selectSize(event: any) {
        this.size = this.sizes[event.index].label;
    }
    
    
    @HostBinding('style.--ig-size')
    protected get sizeStyle() {
        return `var(--ig-size-${this.size})`;
    }
    

    And here's the result of all that work:

    List Items Panning

    Now that we have such a beautiful Angular list with contacts and their phone numbers, why don't we implement an ability to call a contact. The IgxList has the perfect solution for this - list item panning. To do this you have to implement the following steps:

    • Enable the panning using the allowLeftPanning and/or the allowRightPanning properties
    • Define template(s) for the left and/or right panning
    • Handle the list item's panning event(s) and perform the desired action

    The following example demonstrates how to handle both left and right panning. The event handler for right panning shows a toast message. The event handler for the left panning deletes an item from the IgxList.

    Note

    Please note that the list item removal is an application task. The IgxList itself cannot remove items from the data source because the IgxList does not have reference to the data source.

    Here is the HTML code of the example:

    <!-- contacts.component.html -->
    
    <igx-list [allowLeftPanning]="true" [allowRightPanning]="true"
      (leftPan)="leftPanPerformed($event)" (rightPan)="rightPanPerformed($event)">
      <ng-template igxListItemLeftPanning>
        <div class="listItemLeftPanningStyle">
          <igx-icon [color]="white" style="margin-left:10px">delete</igx-icon>Delete
        </div>
      </ng-template>
      <ng-template igxListItemRightPanning>
        <div class="listItemRightPanningStyle">
          <igx-icon [color]="white" style="margin-right:10px">call</igx-icon>Dial
        </div>
      </ng-template>
      <igx-list-item isHeader="true">Contacts</igx-list-item>
      <igx-list-item #item *ngFor="let contact of contacts">
        <igx-avatar igxListThumbnail [src]="contact.photo" shape="circle"></igx-avatar>
        <h4 igxListLineTitle>{{ contact.name }}</h4>
        <p igxListLineSubTitle class="phone">{{ contact.phone }}</p>
        <igx-icon igxListAction [color]="contact.isFavorite ? 'orange' : 'lightgray'" (click)="toggleFavorite(item)">star</igx-icon>
      </igx-list-item>
    </igx-list>
    
    <igx-toast #toast></igx-toast>
    

    The above example is using some CSS styles which may be found here:

    /* contacts.component.css */
    
    igx-icon {
        cursor: pointer;
        user-select: none;
    }
    
    .listItemLeftPanningStyle {
        display: flex;
        flex-direction: row-reverse;
        background-color:orange;
        color: white;
        width: 100%;
        padding-right: 10px;
        align-items: center;
    }
    
    .listItemRightPanningStyle {
        display: flex;
        flex-direction: row;
        background-color:limegreen;
        color: white;
        width: 100%;
        padding-left: 10px;
        align-items: center;
    }
    

    And finally here is the typescript code handling the panning events:

    // contacts.component.ts
    
    ...
    @ViewChild('toast')
    public toast: IgxToastComponent;
    
    public rightPanPerformed(args) {
      args.keepItem = true;
      this.toast.message = 'Dialing ' + this.contacts[args.item.index - 1].name;
      this.toast.open();
    }
    
    public leftPanPerformed(args) {
      args.keepItem = false;
      setTimeout((idx = args.item.index - 1) => {
        this.toast.message = 'Contact ' + this.contacts[idx].name + ' removed.';
        this.toast.open();
        this.contacts.splice(idx, 1);
      }, 500);
    }
    
    ...
    
    Note

    When panning list items there is a threshold which must be reached in order for the panning events to be emitted. You can change the threshold using the IgxList's panEndTriggeringThreshold property. By default this property has a value of 0.5 which means 50% of list item's width.

    Now try panning the list items for yourself:

    Angular filter list

    Our list is looking good, but wouldn't it be even better if we could search for contacts by name? We can easily achieve that by using our filtering pipe. Let's do this.

    Let's add an input field to the top in our Angular component template first and bind it to a property in our component called searchContact:

    <!--contacts.component.html-->
    
    <igx-input-group type="search" class="search">
        <igx-prefix>
            <igx-icon>search</igx-icon>
        </igx-prefix>
        <input #search igxInput placeholder="Search Contacts" [(ngModel)]="searchContact">
        <igx-suffix *ngIf="search.value.length > 0" (click)="searchContact = null">
            <igx-icon>clear</igx-icon>
        </igx-suffix>
    </igx-input-group>
    

    It's time to import the IgxFilterModule and the IgxInputGroupModule in our app.module.ts file and IgxFilterOptions in our contacts component:

    // app.module.ts
    ...
    import { IgxFilterModule, IgxInputGroupModule } from 'igniteui-angular';
    // import { IgxFilterModule, IgxInputGroupModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        imports: [..., IgxFilterModule, IgxInputGroupModule]
    })
    
    // contacts.component.ts
    ...
    import { IgxFilterOptions } from 'igniteui-angular';
    // import { IgxFilterOptions } from '@infragistics/igniteui-angular'; for licensed package
    
    @Component({...})
    export class ContactListComponent {
        public searchContact: string;
        ...
        get filterContacts(): IgxFilterOptions {
            const fo = new IgxFilterOptions();
            fo.key = 'name';
            fo.inputValue = this.searchContact;
            return fo;
        }
    }
    

    After importing the IgxFilterOptions, we need to register a new getter method that will return the filtering options to be used by the pipe each time the searchContact property gets updated. For the filter to work we need to register a key to filter the contact object by. In our case that would be the name of each contact. The second property that has to be registered on the IgxFilterOptions object is the value that we should check against when comparing our contact name. This would be the searchContact property that we bound to the input field above our contacts list.

    Finally, we need to apply the filtering pipe to our contacts data before we can use it. So in our template we simply add:

    <!--contacts.component.html-->
    
    <igx-list-item *ngFor="let contact of contacts | igxFilter: filterContacts; let i = index">
        ...
    </igx-list-item>
    

    List Item Selection

    As you probably have already noticed, list items do not provide selection states. However, if your application requires your list to keep track of which item is selected, we give you an example of how this can be achieved. All you need to do is keep track of the state somewhere in your component, or in the data the list is bound to.

    Here's an example, in which we apply a background color to the list according to the theme's secondary 500 color, based on state tracking coming from the data the list is bound to:

    What we are doing is we are adding an additional selected property to each data member, which defaults to false. Upon list item click, we're resetting all the selected properties in the data collection and setting the one corresponding to the clicked item to true. Based on the selected property, we're applying a css class to the list item which gives it the selected background.

    <igx-list>
        <igx-list-item isHeader="true">Contacts</igx-list-item>
        <igx-list-item [ngClass]="contact.selected ? 'selected' : ''"
                        (click)="selectItem(contact)"
                        *ngFor="let contact of contacts | igxFilter: filterContacts;">
            <igx-avatar igxListThumbnail [src]="contact.photo" shape="circle"></igx-avatar>
            <span igxListLineTitle>{{ contact.name }}</span>
            <span igxListLineSubTitle>{{ contact.phone }}</span>
            <igx-icon igxListAction [style.color]="contact.isFavorite ? 'orange' : 'lightgray'" (click)="toggleFavorite(contact, $event)">star</igx-icon>
        </igx-list-item>
    </igx-list>
    
    public selectItem(item) {
        if (!item.selected) {
            this.contacts.forEach(c => c.selected = false);
            item.selected = true;
        }
    }
    
    .selected {
        background-color: hsla(var(--igx-secondary-500))
    }
    

    Applying theme to the list component

    Let's see how we can change the background of our list. First we need to import index.scss in to our component .scss file.

    @use "igniteui-angular/theming" as *;
    
    // IMPORTANT: Prior to Ignite UI for Angular version 13 use:
    // @import '~igniteui-angular/lib/core/styles/themes/index';
    

    Then we need to create a theme for our component.

    :host ::ng-deep {
        $my-list-theme: list-theme(
            $background: #0568ab
        );
    
        @include list($my-list-theme);
    }
    

    The result from the above code is

    Note

    Please note that if we create our component theme in the component .scss file we need to use ::ng-deep in order to pass the view encapsulation otherwise our new theme will not work! for more info please refer to: Component Themes.

    For full list of parameters that you can change for the list component please refer to: IgxListComponent Styles

    API References

    In this article we covered a lot of ground with the Angular list component. We created a list of contact items. Used some additional Ignite UI for Angular components inside our list items, like avatars and icons. Created some custom item layout and styled it. Finally, we added list filtering. The list component has a few more APIs to explore, which are listed below.

    Additional Angular components that were used:

    Theming Dependencies

    Additional Resources

    Our community is active and always welcoming to new ideas.