Skip to content

Instantly share code, notes, and snippets.

@gpulido
Created March 1, 2020 12:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gpulido/4bae80a5be4fd5c7ed61f1f1667da039 to your computer and use it in GitHub Desktop.
Save gpulido/4bae80a5be4fd5c7ed61f1f1667da039 to your computer and use it in GitHub Desktop.
mockup for a mdc autocomplete component
<div #surfaceAnchor mdcMenuSurfaceAnchor (click)="onClick($event)">
<ng-content (keydown)="onKeydown($event)" select="mdc-text-field"></ng-content>
<ng-content select="mdc-menu"></ng-content>
</div>
import {
Component,
OnInit,
ContentChild,
ViewChild,
AfterViewInit,
Input,
Output,
ViewEncapsulation,
ChangeDetectionStrategy,
forwardRef
} from '@angular/core';
import {
MdcMenu,
MdcTextField,
MdcMenuSurfaceAnchor,
AnchorMargin
} from '@angular-mdc/web';
import { DefaultFocusState } from '@material/menu';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
@Component({
selector: 'mdc-autocomplete',
templateUrl: './mdc-autocomplete.component.html',
styleUrls: ['./mdc-autocomplete.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MdcAutocompleteComponent),
multi: true
}
],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MdcAutocompleteComponent<T> implements OnInit, AfterViewInit, ControlValueAccessor {
@Input() items: Array<T>;
@Input() propertySelector = '';
@Output() filteredItems: Array<T> = new Array<T>();
@ViewChild(MdcMenuSurfaceAnchor, { static: false }) _selectAnchor!: MdcMenuSurfaceAnchor;
@ContentChild(MdcTextField, { static: false }) _textField!: MdcTextField;
@ContentChild(MdcMenu, { static: false }) _menu!: MdcMenu;
@Input() item: T;
isDisabled: boolean;
onChange = (_: any) => {};
onTouch = () => {};
constructor() {}
writeValue(value: T): void {
console.log(value);
if (value) {
this.item = value || null;
if (this._textField) {
this._textField.value = this.item[this.propertySelector];
}
} else {
this.item = null;
if (this._textField) {
this._textField.value = '';
}
}
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouch = fn;
}
setDisabledState(isDisabled: boolean): void {
this._textField.disabled = coerceBooleanProperty(isDisabled);
this.isDisabled = isDisabled;
}
ngOnInit() {}
ngAfterViewInit() {
this.filteredItems = this.items;
this._menu.anchorElement = this._selectAnchor.elementRef.nativeElement;
this._menu.anchorCorner = 'bottomStart';
this._menu.anchorMargin = '{top: 10}' as AnchorMargin;
this._menu.defaultFocusState = DefaultFocusState.NONE;
this._menu.selected.asObservable().subscribe(item => {
this.writeValue(item.source.value);
this.onChange(this.item);
});
if (this.item) {
this._textField.value = this.item[this.propertySelector];
}
this._textField.registerOnChange(() => {
if (!this._menu.open && this.filteredItems.length > 0) {
this._menu.open = true;
}
this.filteredItems = this.items.filter(item =>
item[this.propertySelector].toUpperCase().includes(this._textField?.value.toUpperCase() ?? '')
);
});
}
onClick(evt: MouseEvent | TouchEvent) {
if ((evt.target as Element).nodeName === 'INPUT') {
setTimeout(() => {
if (this.filteredItems.length > 0) {
this._menu.open = true;
}
}, 100);
}
}
onFocus(focus: boolean) {
console.log('focus');
setTimeout(() => {
if (focus) {
this._menu.open = true;
}
}, 100);
}
onKeyDown() {
console.log('keydown');
}
}
<mdc-autocomplete
[items]="clubs" #autocomplete
[propertySelector]="'name'"
formControlName="club"
fxFlex="76%">
<mdc-text-field
label="Club"
[outlined]="true"
></mdc-text-field>
<mdc-helper-text [validation]="true">
<span *ngIf="form.controls.club.hasError('required')">Club is required</span>
</mdc-helper-text>
<mdc-menu>
<mdc-list [avatar]="true">
<mdc-list-item *ngFor="let club of autocomplete.filteredItems" [value]="club">
<img mdcListItemGraphic [src]="club.imageUrl" />{{ club.name }}
</mdc-list-item>
</mdc-list>
</mdc-menu>
</mdc-autocomplete>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment