DevExtreme v26.1 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.

Angular Select Box - Customize Drop-Down Button

Use the dropDownButtonTemplate to customize the drop-down button.

This demo illustrates three customization cases:

  • Custom image
    Declare an img element in the template.

  • Load indicator
    Declare the load indicator and a regular icon in the template. Display the load indicator while hiding the icon, and vice versa.

  • Icon that depends on the selected value
    Declare the default and the selected item's icon in the template. If there is a selected item, display its icon; otherwise, show the default icon.

Backend API
<div class="dx-fieldset"> <div class="dx-field"> <div class="dx-field-label">Image as the icon</div> <div class="dx-field-value"> <dx-select-box [dataSource]="simpleProducts" [inputAttr]="{ 'aria-label': 'Simple Product' }" > <div *dxTemplate="let data of 'dropDownButton'"> <img alt="Custom icon" src="../../../../images/icons/custom-dropbutton-icon.svg" class="custom-icon" /> </div> </dx-select-box> </div> </div> <div class="dx-field"> <div class="dx-field-label">Load indicator as the icon</div> <div class="dx-field-value"> <dx-select-box [dataSource]="deferredProducts" [inputAttr]="{ 'aria-label': 'Deferred Product' }" > <div *dxTemplate="let data of 'dropDownButton'"> <dx-load-indicator [visible]="!isLoaded"></dx-load-indicator> <span [hidden]="!isLoaded"> <img alt="Custom icon" src="../../../../images/icons/custom-dropbutton-icon.svg" class="custom-icon" /> </span> </div> </dx-select-box> </div> </div> <div class="dx-field"> <div class="dx-field-label">Value-dependent icon</div> <div class="dx-field-value"> <dx-select-box [dataSource]="products" [inputAttr]="{ 'aria-label': 'Templated Product' }" [(selectedItem)]="selectedItem" [value]="1" showClearButton="true" displayExpr="Name" valueExpr="ID" > <div *dxTemplate="let data of 'dropDownButton'"> @if (selectedItem) { <img alt="Custom icon" src="../../../../images/icons/{{ selectedItem.IconSrc }}" class="custom-icon" /> <div class="dx-dropdowneditor-icon"></div> } </div> <div *dxTemplate="let data of 'item'" class="custom-item"> <img alt="{{ data.Name }}" src="../../../../images/icons/{{ data.IconSrc }}" /> <div class="product-name">{{ data.Name }}</div> </div> </dx-select-box> </div> </div> </div>
import { bootstrapApplication } from '@angular/platform-browser'; import { ChangeDetectorRef, Component, enableProdMode, provideZoneChangeDetection, } from '@angular/core'; import { DxSelectBoxModule, DxLoadIndicatorModule, } from 'devextreme-angular'; import { Product, Service } from './app.service'; if (!/localhost/.test(document.location.host)) { enableProdMode(); } @Component({ selector: 'demo-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers: [Service], imports: [ DxSelectBoxModule, DxLoadIndicatorModule, ], }) export class AppComponent { simpleProducts: string[]; products: Product[]; isLoaded = true; selectedItem: Product; deferredProducts = { loadMode: 'raw', load: () => { this.isLoaded = false; const promise = new Promise((resolve) => { setTimeout(() => { resolve(this.simpleProducts); this.isLoaded = true; this.changeDetectorRef.detectChanges(); }, 3000); }); return promise; }, }; constructor(service: Service, private changeDetectorRef: ChangeDetectorRef) { this.products = service.getProducts(); this.selectedItem = this.products[0]; this.simpleProducts = service.getSimpleProducts(); } } bootstrapApplication(AppComponent, { providers: [ provideZoneChangeDetection({ eventCoalescing: true, runCoalescing: true }), ], });
::ng-deep .dx-dropdowneditor-button .dx-button-content { text-align: center; } ::ng-deep .dx-dropdowneditor-button .dx-button-content .dx-loadindicator { width: 1.5em; height: 1.5em; } ::ng-deep .custom-icon { max-height: 100%; max-width: 100%; font-size: 28px; display: inline-block; vertical-align: middle; } ::ng-deep .custom-item img { float: right; } ::ng-deep .custom-item .product-name { line-height: 32px; padding-left: 5px; }
import { Injectable } from '@angular/core'; export class Product { ID: number; Name: string; Price: number; Current_Inventory: number; Backorder: number; Manufacturing: number; Category: string; IconSrc: string; } const simpleProducts: string[] = [ 'HD Video Player', 'SuperHD Video Player', 'SuperPlasma 50', 'SuperLED 50', 'SuperLED 42', ]; const products: Product[] = [{ ID: 1, Name: 'HD Video Player', Price: 330, Current_Inventory: 225, Backorder: 0, Manufacturing: 10, Category: 'Video Players', IconSrc: 'video-player.svg', }, { ID: 2, Name: 'SuperHD Player', Price: 400, Current_Inventory: 150, Backorder: 0, Manufacturing: 25, Category: 'Video Players', IconSrc: 'video-player.svg', }, { ID: 3, Name: 'SuperPlasma 50', Price: 2400, Current_Inventory: 0, Backorder: 0, Manufacturing: 0, Category: 'Televisions', IconSrc: 'tv.svg', }, { ID: 4, Name: 'SuperLED 50', Price: 1600, Current_Inventory: 77, Backorder: 0, Manufacturing: 55, Category: 'Televisions', IconSrc: 'tv.svg', }, { ID: 5, Name: 'SuperLED 42', Price: 1450, Current_Inventory: 445, Backorder: 0, Manufacturing: 0, Category: 'Televisions', IconSrc: 'tv.svg', }]; @Injectable() export class Service { getSimpleProducts(): string[] { return simpleProducts; } getProducts(): Product[] { return products; } }
<!DOCTYPE html> <html lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/26.1.5/css/dx.light.css" /> </head> <body class="dx-viewport"> <div class="demo-container"> <demo-app>Loading...</demo-app> </div> <script src="https://cdn.jsdelivr.net/npm/zone.js@0.16.2/bundles/zone.umd.js"></script> <script src="./bundle.js" type="module"></script> </body> </html>