Introduction
A <select>
element can serve as a single-select or multiple-select "picker" depending on whether the multiple
attribute is present. The binding system supports both use cases. The samples below demonstrate a variety scenarios, all use a common series of steps to configure the select element:
- Add a
<select>
element to the template and decide whether themultiple
attribute should be applied. - Bind the select element's
value
attribute to a property. In "multiple" mode, the property should be an array. In singular mode it can be any type. - Define the select element's
<option>
elements. You can use therepeat
or add each option element manually. - Specify each option's value via the
model
property:<option model.bind="product.id">${product.name}</option>
You can use the standardvalue
attribute instead ofmodel
, just remember- it will coerce anything it's assigned to a string.
Select Number
export class App {
products = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
selectedProductId = null;
}
export interface IProduct {
id: number;
name: string;
}
export class App {
products: IProduct[] = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
selectedProductId: number = null;
}
<template>
<label>
Select product:<br>
<select value.bind="selectedProductId">
<option model.bind="null">Choose...</option>
<option repeat.for="product of products"
model.bind="product.id">
${product.id} - ${product.name}
</option>
</select>
</label>
Selected product ID: ${selectedProductId}
</template>
Select Object
export class App {
products = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
selectedProduct = null;
}
export interface IProduct {
id: number;
name: string;
}
export class App {
products: IProduct[] = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
selectedProduct: IProduct = null;
}
<template>
<label>
Select product:<br>
<select value.bind="selectedProduct">
<option model.bind="null">Choose...</option>
<option repeat.for="product of products"
model.bind="product">
${product.id} - ${product.name}
</option>
</select>
</label>
Selected product: ${selectedProduct.id} - ${selectedProduct.name}
</template>
Select Object with Matcher
You may run into situations where the object your select element's value is bound does not have reference equality with any of the objects your option element model properties are bound to. The select's value object might "match" one of the option objects by id, but they may not be the same object instance. To support this scenario you can override Aurelia's default "matcher" which is a equality comparison function that looks like this: (a, b) => a === b
. You can substitute a function of your choosing that has the right logic to compare your objects.
export class App {
products = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
productMatcher = (a, b) => a.id === b.id;
selectedProduct = { id: 1, name: 'CPU' };
}
export interface IProduct {
id: number;
name: string;
}
export class App {
products: IProduct[] = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
productMatcher = (a, b) => a.id === b.id;
selectedProduct: IProduct = { id: 1, name: 'CPU' };
}
<template>
<label>
Select product:<br>
<select value.bind="selectedProduct" matcher.bind="productMatcher">
<option model.bind="null">Choose...</option>
<option repeat.for="product of products"
model.bind="product">
${product.id} - ${product.name}
</option>
</select>
</label>
Selected product: ${selectedProduct.id} - ${selectedProduct.name}
</template>
Select Boolean
export class App {
likesTacos = null;
}
export class App {
likesTacos = null;
}
<template>
<label>
Do you like tacos?:
<select value.bind="likesTacos">
<option model.bind="null">Choose...</option>
<option model.bind="true">Yes</option>
<option model.bind="false">No</option>
</select>
</label>
likesTacos: ${likesTacos}
</template>
Select String
export class App {
products = ['Motherboard', 'CPU', 'Memory'];
selectedProduct = '';
}
export class App {
products: string[] = ['Motherboard', 'CPU', 'Memory'];
selectedProduct: string = '';
}
<template>
<label>
Select product:<br>
<select value.bind="selectedProduct">
<option value="">Choose...</option>
<option repeat.for="product of products"
value.bind="product">
${product}
</option>
</select>
</label>
Selected product: ${selectedProduct}
</template>
Multiple Select Numbers
export class App {
products = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
selectedProductIds = [];
}
export interface IProduct {
id: number;
name: string;
}
export class App {
products: IProduct[] = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
selectedProductIds: number[] = [];
}
<template>
<label>
Select products:
<select multiple value.bind="selectedProductIds">
<option repeat.for="product of products"
model.bind="product.id">
${product.id} - ${product.name}
</option>
</select>
</label>
Selected product IDs: ${selectedProductIds}
</template>
Multiple Select Objects
export class App {
products = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
selectedProducts = [];
}
export interface IProduct {
id: number;
name: string;
}
export class App {
products: IProduct[] = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
selectedProducts: IProduct[] = [];
}
<template>
<label>
Select products:
<select multiple value.bind="selectedProducts">
<option repeat.for="product of products"
model.bind="product">
${product.id} - ${product.name}
</option>
</select>
</label>
Selected products:
<ul>
<li repeat.for="product of selectedProducts">${product.id} - ${product.name}</li>
</ul>
</template>
Multiple Select Strings
export class App {
products = ['Motherboard', 'CPU', 'Memory'];
selectedProducts = [];
}
export class App {
products: string[] = ['Motherboard', 'CPU', 'Memory'];
selectedProducts: string[] = [];
}
<template>
<label>
Select products:
<select multiple value.bind="selectedProducts">
<option repeat.for="product of products"
value.bind="product">
${product}
</option>
</select>
</label>
Selected products: ${selectedProducts}
</template>