Tanzeel
Tanzeel

Reputation: 4998

How to apply oneway change to two dropdowns using same array [Angular]

I'm new to Angular. Sorry for not able to frame the question very well. I'm making a sales comparison component in angular. I've two dropdown lists inside a widget. One Primary and the other one being secondary. My task is to sync these two dropdown lists. What I mean is, If I select an option in primary, that option should get selected in secondary also. But the reverse should not happen. This is what I meant by oneway change in my question.

Here's a screenshot to explain further: enter image description here

that means the reverse selection shouldn't happen. For saving everyone's time I've created an stackblitz. You can directly look into that also.

And here's my code:

timeselector.component.html

<div class="time-selector">
    <p-overlayPanel class="my-overlay" #op>
        <br />
        <div class="inner-panel">
          <h2>Time selection widget</h2>
          <br>
          <h3>Primary dropdown</h3>
          <select [(ngModel)]="primaryMode" name="source">
            <option *ngFor="let mode of modes" [value]="mode" (click)="$event.stopPropagation()">
              {{ mode }}
            </option>
          </select>
          <br><br><br><br>
          <h3>Secondary dropdown</h3>
          <select [(ngModel)]="primaryMode" name="source">
            <option *ngFor="let mode of modes" [value]="mode" (click)="$event.stopPropagation()">
              Previous {{ mode }}
            </option>
          </select>
        </div>
    </p-overlayPanel>
</div>

<div class="input-field" (click)="op.toggle($event)" style="margin-left: 100px">
    <h4 style="color: white; float: left; margin-left: 10px;">Click here</h4>
</div>

Note: Secondary dropdown is also using the same array but the values are prefixed with Previous.

timeselector.component.ts

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

@Component({
    selector: 'app-timeselector',
    templateUrl: './timeselector.component.html',
    styleUrls: ['./timeselector.component.css']
})
export class TimeselectorComponent {
    modes = ['Year', 'Quarter', 'Sprint'];
    public selectedSource = 'Year';
}

Please correct me and help me implement that logic. And please let me know whether it is even doable or not. Maybe I'm wasting mine and everyone's time.

Upvotes: 0

Views: 1873

Answers (3)

crooksey
crooksey

Reputation: 8809

When using the same variable for ngModel, when you update one form component, it will change all others using the same model.

If it was me, I would use angular reactive forms (if your app is a large form like you suggest, it will make managing it much easier):

modes = ['Year', 'Quarter', 'Sprint'];
myForm = new FormGroup({
        controlA: new FormControl(null),
        controlB: new FormControl(null)
        )}

ngOnInit() {
    this.myForm.get("controlA").valueChanges.subscribe(x => {
       this.myForm.get(['controlB']).setValue(x);
     })
}

<div class="form-group" [formGroup]="myForm">
<label>ControlA</label>
<select class="form-control"
        formControlName="controlA">
<option disabled selected value> --Select-- </option>
<option *ngFor="let mode of modes" [ngValue]="mode" >{{mode}}</option>
</select>


<label>ControlB</label>
<select class="form-control"
        formControlName="controlB">
<option disabled selected value> --Select-- </option>
<option *ngFor="let mode of modes" [ngValue]="mode" >{{mode}}</option>
</select>
</div>

Stackblitz

Upvotes: 1

Smit Vora
Smit Vora

Reputation: 470

timeselector.component.ts

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


@Component({
    selector: 'app-timeselector',
    templateUrl: './timeselector.component.html',
    styleUrls: ['./timeselector.component.css']
})
export class TimeselectorComponent {

    modes = ['Year', 'Quarter', 'Sprint'];

    public selectedSource = 'Year';
    private selectedDestination = this.selectedSource;
}

timeselector.component.html

<div class="time-selector">
    <p-overlayPanel class="my-overlay" #op>
        <br />
        <div class="inner-panel">
          <h2>Time selection widget</h2>
          <br>
          <h3>Primary dropdown</h3>
          <select [(ngModel)]="selectedSource" (ngModelChange)="selectedDestination=$event"> name="source">
            <option *ngFor="let mode of modes" [value]="mode" (click)="$event.stopPropagation()">
              {{ mode }}
            </option>
          </select>
          <br><br><br><br>
          <h3>Secondary dropdown</h3>
          <select [(ngModel)]="selectedDestination" name="source">
            <option *ngFor="let mode of modes" [value]="mode" (click)="$event.stopPropagation()">
              Previous {{ mode }}
            </option>
          </select>
        </div>
    </p-overlayPanel>
</div>

<div class="input-field" (click)="op.toggle($event)" style="margin-left: 100px">
    <h4 style="color: white; float: left; margin-left: 10px;">Click here</h4>
</div>

Upvotes: 1

Adrita Sharma
Adrita Sharma

Reputation: 22213

The [(ngModel)] should be different on both the dropdown. For the primary dropdown change, you can set the value for the secondary using (ngModelChange)

Try like this:

<h3>Primary dropdown</h3>

<select [(ngModel)]="primaryMode" name="source" (ngModelChange)="secondaryMode = primaryMode">
     <option *ngFor="let mode of modes" [value]="mode" (click)="$event.stopPropagation()">
          {{ mode }}
     </option>
</select>

<br><br><br><br>

<h3>Secondary dropdown</h3>

<select [(ngModel)]="secondaryMode" name="source">
     <option *ngFor="let mode of modes" [value]="mode" (click)="$event.stopPropagation()">
          Previous {{ mode }}
     </option>
</select>

Working Demo

Upvotes: 1

Related Questions