Tenzolinho
Tenzolinho

Reputation: 982

Dynamic select-option using objects in Angular

I have this object:

0: {year: "2015", period: ["P1"]}
1: {year: "2016", period: ["P1", "P2"]}
2: {year: "2017", period: ["P1", "P2", "P3"]}

And I wanna do 2 select-option:

When I press on 2015 on the first select-option, the values on the second select-option to be P1.

When I press on 2016 on the first select-option, the values on the second select-option to be P1, P2.

When I press on 2017 on the first select-option, the values on the second select-option to be P1, P2, P3.

Something dinamically basically. I tried this:

<select>
  <option disabled value="null">Select year</option>
  <option *ngFor="let item of fps" [value]="item.year">
     {{ item.year }}
  </option>
</select>
&nbsp;
<select>
  <option disabled value="null">Select period</option>
  <option *ngFor="let item of fps" [value]="item.period">
     {{ item.period }}
  </option>
</select>

but this will give me: (same with 2016 and 2017)

enter image description here

How can I modify in order to obtain what I want? Thank you for your time!

Upvotes: 2

Views: 8503

Answers (5)

Eliseo
Eliseo

Reputation: 57929

"My Angular way" when we have a few relationals options is using ngValue. The disapoint it's that in "year" we have an object, not a number, but the advantage is a clear .ts

<select [(ngModel)]="year" #val>
  <option disabled value="null">Select year</option>
  <option *ngFor="let item of options" [ngValue]="item">
     {{ item.year }}
  </option>
</select>
&nbsp;
<select [(ngModel)]="periodo">
  <option disabled value="null">Select period</option>
  <option *ngFor="let item of year?.period" [value]="item">
     {{ item }}
  </option>
</select>
{{year?.year}}{{periodo}}

The .ts only need two variables year )that will be an object, but we can obtain the year by year.year) and periodo

See stactblitz

export class AppComponent  {
  options = [
    {year: "2015", period: ["P1"]},
    {year: "2016", period: ["P1", "P2"]},
    {year: "2017", period: ["P1", "P2", "P3"]}
  ];
  year:any=null;
  period:any;
}

Upvotes: 0

manu
manu

Reputation: 99

Try this.

<select (change)="changeValue($event.target.value)">
<option disabled value="null">Select year</option>
<option *ngFor="let item of fps" [value]="item.year" (change)="changeValue(item.year)">
   {{ item.year }}
</option>
</select>
&nbsp;
<select>
<option disabled value="null">Select period</option>
<option *ngFor="let item of fps1" [value]="item">
   {{ item }}
</option>
</select>

TS code

 changeValue(year){
this.fps.forEach(element => {
  if(element.year==year){
    this.fps1=element.period;
  }
});
}

Upvotes: 0

Pardeep Jain
Pardeep Jain

Reputation: 86740

You need to bind the selection of your first dropdown value to set another dropdown options, better to call event on every change of your dropdown's value. Use your code like below -

<select (change)='onSelect(val.value)' #val>
  <option disabled value="null">Select year</option>
  <option *ngFor="let item of options" [value]="item.year">
     {{ item.year }}
  </option>
</select>

<select>
  <option disabled value="null">Select period</option>
  <option *ngFor="let item of periodOptions" [value]="item">
     {{ item }}
  </option>
</select>

and Bind in Your method like this -

options = [
    {year: "2015", period: ["P1"]},
    {year: "2016", period: ["P1", "P2"]},
    {year: "2017", period: ["P1", "P2", "P3"]}
  ];
  periodOptions = [];

  onSelect(val) {
    console.log(val);
    if (val) {
      this.periodOptions = [];
      this.options.map(res => {
        if(res.year == val){
          this.periodOptions = res.period;
        }
      });
    }
  }

Working Example

Upvotes: 5

Hiren Vaghasiya
Hiren Vaghasiya

Reputation: 5544

Use this way

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template:`
   <select [(ngModel)]="firstSelectValue">
    <option *ngFor="let opt of firstSelectOptions" [value]="opt">
       {{ opt }}
    </option>
   </select> 

   <select *ngIf="firstSelectValue" [(ngModel)]="secondSelectValue" >
    <option *ngFor="let opt of secondSelectOptions" [value]="opt">
      {{ opt }}
    </option>
  </select>


  <div>
    <div>First select value: {{ firstSelectValue }}</div>
    <div>Second select value:  {{ secondSelectValue }}</div>
  </div>
  `,
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

    private opts = [ 
      {year: "2015", period: ["P1"]},
      {year: "2016", period: ["P1", "P2"]},
      {year: "2017", period: ["P1", "P2", "P3"]}
  ]

  firstSelectValue = '2015';
  secondSelectValue = null;

  get firstSelectOptions() {
    return this.opts.map(({year}) => year);
  }

  get secondSelectOptions() {
    return (this.opts.find(({year}) => year === this.firstSelectValue)).period
  }

}

Link : View Demo

Upvotes: 1

MonkeyScript
MonkeyScript

Reputation: 5121

In your TS, use a temporary variable to hold year selection

tempYearSelect : string = ''

HTML :

<select [(ngModel)]="tempYearSelect">
  <option disabled value="null">Select year</option>
  <option *ngFor="let item of fps" [value]="item.year">
     {{ item.year }}
  </option>
</select>
&nbsp;
<select>
  <option disabled value="null">Select period</option>
  <option *ngFor="let item of fps" [value]="item.period" [hidden]="item.year!=tempYearSelect">
     {{ item.period }}
  </option>
</select>

Upvotes: 1

Related Questions