Ad

Best Way To Make A Custom Select In Angular?

I'm using the MEAN stack (Angular 6) and I'm still looking for the best way to build a custom and reusable <select> form control which uses an Array of strings returned from the BE to generate all <option> tags. Let's say for example we have 3 materials wood, metal and plastic and the returned Array can be one of the following (stored in the materials variable):

(in my example.component.ts)

form = new FormGroup({
  'material' = new FormControl('')
});

get material() {return this.form.get('material');}

materials = [
  {
    key: "mat_wood",
    value: "Wood"
  },
  {
    key: "mat_metal",
    value: "Metal"
  },
  {
    key: "mat_plastic",
    value: "Plastic"
  }
]

or

(in my example.component.ts)

form = new FormGroup({
  'material' = new FormControl('')
});

get material() {return this.form.get('material');}

materials = [
  {"mat_wood": "Wood"},
  {"mat_metal": "Metal"},
  {"mat_plastic": "Plastic"}
]

and we have this HTML structure:

(in my example.component.html)

<form [formGroup]="form">
  <div class="select-wrap">
    <span class="select-value">{{}}</span>

    <select formControlName="material">
      <option *ngFor="let mat of materials" value="{{}}">{{}}</option>
    </select>
  </div>
</form>

Which eventually has to be compiled to this:

  <select formControlName="material">
    <option value="mat_wood">Wood</option>
    <option value="mat_metal">Metal</option>
    <option value="mat_plastic">Plastic</option>
  </select>

Here we have a classical example of a custom select structure. The <span class="select-value"> displays the selected option's text to the user. The <select> has opacity set to 0 and is positioned on top of the <span>, so when the user clicks, he clicks on it and activates it.

For each option I need to put the mat_[something] in the value attribute and the readable Something as text in the option, just like in the example above:
<option value="mat_wood">Wood</option>.

Question is: How can I put the selected option text inside the <span>? I'm looking for a reusable way of doing it.


EDIT:
Looking at the first answer shows (and I forgot to mention) that using a template variable does the job. But if we have an enclosing *ngFor loop that generates multiple selects, then we need to have dynamically generated template variables. Is that even possible?

Ad

Answer

One way is you could refer to select as template variable say mySelect.

<select #mySelect formControlName="material">
  <option value="mat_wood">Wood</option>
  <option value="mat_metal">Metal</option>
  <option value="mat_plastic">Plastic</option>
</select>

And refer to its options.text property like this. {{ mySelect && mySelect.selectedIndex > -1 ? mySelect.options[mySelect.selectedIndex].text : ''}} inside your span element.

You can read about template variables here

Ad
source: stackoverflow.com
Ad