Skip to content

Commit

Permalink
feat(select): add ability to customize the select trigger (#3341)
Browse files Browse the repository at this point in the history
Adds the `md-select-trigger` directive which allows users to customize the selected value. E.g. it is now possible to do something like this, if the user wanted to reverse the selected label for some reason:

```ts
<md-select placeholder="Food" [formControl]="control" #select="mdSelect">
  <md-select-trigger>
    {{ select.selected?.viewValue.split('').reverse().join('') }}
  </md-select-trigger>
  <md-option *ngFor="let food of foods" [value]="food.value">
    {{ food.viewValue }}
  </md-option>
</md-select>
```

Fixes #2275.
crisbeto authored and mmalerba committed Aug 9, 2017
1 parent 2286ad5 commit 72c5d39
Showing 5 changed files with 71 additions and 6 deletions.
6 changes: 3 additions & 3 deletions src/lib/select/index.ts
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {MdSelect, MD_SELECT_SCROLL_STRATEGY_PROVIDER} from './select';
import {MdSelect, MdSelectTrigger, MD_SELECT_SCROLL_STRATEGY_PROVIDER} from './select';
import {MdCommonModule, OverlayModule, MdOptionModule} from '../core';


@@ -19,8 +19,8 @@ import {MdCommonModule, OverlayModule, MdOptionModule} from '../core';
MdOptionModule,
MdCommonModule,
],
exports: [MdSelect, MdOptionModule, MdCommonModule],
declarations: [MdSelect],
exports: [MdSelect, MdSelectTrigger, MdOptionModule, MdCommonModule],
declarations: [MdSelect, MdSelectTrigger],
providers: [MD_SELECT_SCROLL_STRATEGY_PROVIDER]
})
export class MdSelectModule {}
6 changes: 5 additions & 1 deletion src/lib/select/select.html
Original file line number Diff line number Diff line change
@@ -11,8 +11,12 @@
[@transformPlaceholder]="_getPlaceholderAnimationState()"
[style.opacity]="_getPlaceholderOpacity()"
[style.width.px]="_selectedValueWidth"> {{ placeholder }} </span>

<span class="mat-select-value" *ngIf="_hasValue()">
<span class="mat-select-value-text">{{ triggerValue }}</span>
<span class="mat-select-value-text" [ngSwitch]="!!customTrigger">
<span *ngSwitchDefault>{{ triggerValue }}</span>
<ng-content select="md-select-trigger, mat-select-trigger" *ngSwitchCase="true"></ng-content>
</span>
</span>

<span class="mat-select-arrow"></span>
10 changes: 10 additions & 0 deletions src/lib/select/select.md
Original file line number Diff line number Diff line change
@@ -72,6 +72,16 @@ Global default placeholder options can be specified by setting the `MD_PLACEHOLD
})
```

### Customizing the trigger label
If you want to display a custom trigger label inside a select, you can use the `md-select-trigger` element:

```html
<md-select placeholder="Favorite food" #select="mdSelect">
<md-select-trigger>You have selected: {{ select.selected?.viewValue }}</md-select-trigger>
<md-option *ngFor="let food of foods" [value]="food.value">{{ food.viewValue }}</md-option>
</md-select>
```

Here are the available global options:

| Name | Type | Values | Description |
40 changes: 38 additions & 2 deletions src/lib/select/select.spec.ts
Original file line number Diff line number Diff line change
@@ -74,7 +74,8 @@ describe('MdSelect', () => {
BasicSelectWithoutForms,
BasicSelectWithoutFormsPreselected,
BasicSelectWithoutFormsMultiple,
SelectInsideFormGroup
SelectInsideFormGroup,
SelectWithCustomTrigger
],
providers: [
{provide: OverlayContainer, useFactory: () => {
@@ -951,7 +952,6 @@ describe('MdSelect', () => {

});


describe('animations', () => {
let fixture: ComponentFixture<BasicSelect>;
let trigger: HTMLElement;
@@ -2529,6 +2529,21 @@ describe('MdSelect', () => {
expect(panel.classList).toContain('mat-warn');
});

it('should allow the user to customize the label', () => {
fixture.destroy();

const labelFixture = TestBed.createComponent(SelectWithCustomTrigger);
labelFixture.detectChanges();

labelFixture.componentInstance.control.setValue('pizza-1');
labelFixture.detectChanges();

const label = labelFixture.debugElement.query(By.css('.mat-select-value')).nativeElement;

expect(label.textContent).toContain('azziP',
'Expected the displayed text to be "Pizza" in reverse.');
});

});

describe('reset values', () => {
@@ -3212,3 +3227,24 @@ class BasicSelectWithoutFormsMultiple {

@ViewChild(MdSelect) select: MdSelect;
}

@Component({
selector: 'select-with-custom-trigger',
template: `
<md-select placeholder="Food" [formControl]="control" #select="mdSelect">
<md-select-trigger>
{{ select.selected?.viewValue.split('').reverse().join('') }}
</md-select-trigger>
<md-option *ngFor="let food of foods" [value]="food.value">
{{ food.viewValue }}
</md-option>
</md-select>
`
})
class SelectWithCustomTrigger {
foods: any[] = [
{ value: 'steak-0', viewValue: 'Steak' },
{ value: 'pizza-1', viewValue: 'Pizza' },
];
control = new FormControl();
}
15 changes: 15 additions & 0 deletions src/lib/select/select.ts
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
import {
AfterContentInit,
Component,
ContentChild,
ContentChildren,
ElementRef,
EventEmitter,
@@ -27,6 +28,7 @@ import {
Inject,
ChangeDetectionStrategy,
InjectionToken,
Directive,
} from '@angular/core';
import {NgForm, FormGroupDirective} from '@angular/forms';
import {MdOption, MdOptionSelectionChange, MdOptgroup} from '../core/option/index';
@@ -147,6 +149,16 @@ export class MdSelectBase {
}
export const _MdSelectMixinBase = mixinColor(mixinDisabled(MdSelectBase), 'primary');


/**
* Allows the user to customize the trigger that is displayed when the select has a value.
*/
@Directive({
selector: 'md-select-trigger, mat-select-trigger'
})
export class MdSelectTrigger {}


@Component({
moduleId: module.id,
selector: 'md-select, mat-select',
@@ -293,6 +305,9 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
/** Classes to be passed to the select panel. Supports the same syntax as `ngClass`. */
@Input() panelClass: string|string[]|Set<string>|{[key: string]: any};

/** User-supplied override of the trigger element. */
@ContentChild(MdSelectTrigger) customTrigger: MdSelectTrigger;

/** Placeholder to be shown if no value has been selected. */
@Input()
get placeholder() { return this._placeholder; }

0 comments on commit 72c5d39

Please sign in to comment.