Angular custom select component: binding selected option

1.2k Views Asked by At

I did a custom select which hide the select and does a dropdown where you choose an item.

But i can't bind the item choosed from my dropdown to my select html element.

The custom component html

<div class="select">
  <select class="select-hidden" [(ngModel)]="selectedOption">
    <option *ngFor="let option of data" [value]="option.key">{{option.value}}</option>
  </select>

  <div class="select-styled" (click)="enableToggle()" [ngClass]="{'active' : toggle}">
    {{selectedOption.value}}
  </div>

  <ul class="select-options" [ngClass]="{'block' : toggle}">
    <li (click)="select(option)" *ngFor="let option of data" >{{option.value}}</li>
  </ul>
</div>

The custom component TS

import {Component, OnInit, Input} from '@angular/core';

export interface Option {
  key: number;
  value: string;
}

@Component({
  selector: 'alta-select',
  templateUrl: './alta-select.component.html',
  styleUrls: ['./alta-select.component.scss'],
  host: { 'class': 'alta-select' },
})
export class AltaSelectComponent implements OnInit {

  @Input() data: Option[] = [];
  toggle = false;
  selectedOption: Option;

  enableToggle = () => this.toggle = !this.toggle;

  select = (actualOption) => {
    this.enableToggle();
    this.selectedOption = actualOption;
  }

  ngOnInit(): void{
    this.selectedOption = this.data[0];
  }
}

And how you call that component (the (change) doesn't work, because the select never change value, only the dropdown does, that's the values i'm trying to bind

<alta-select [data]="options" (change)="changeTest($event)"></alta-select>
2

There are 2 best solutions below

2
On

declare your selectedOption as an input and output property in order to bind to it.

@Input() selectedOption: Option;
@Output() selectedOptionChange = new EventEmitter<Option>();

...

select = (actualOption) => {
    this.enableToggle();
    this.selectedOption = actualOption;
    this.selectedOptionChange.emit(this.selectedOption);
  }

and you can two-way bind via

<alta-select [data]="options" [(selectedOption)]="mySelection"></alta-select>

or if you are only interested in the change event

<alta-select [data]="options" (selectedOptionChange)="changeTest($event)"></alta-select>

also you might have to change the value binding in your custom select. the option should be the value not the key.

[value]="option"
0
On

When you create a custom input component, you need to implement controlValueAccessor. This should be your first step. Then you need to create a select box template and assign change and blur function. Please try this and you will get all the events work properly