Dynamically changing options for dropdown PrimeNg Angular 4

5.6k Views Asked by At

I am a novice to UI development and PrimeNg, probably the answer is right there and I am not able to find it. Anyhoo, I am in a ngFor loop to create multiple levels of dropdowns. For eg, I have 2 rooms Deluxe and Suite. and Deluxe has rates for Breakfast, Breakfast + Lunch, Breakfast + Dinner and Suite only has 2(Breakfast, Breakfast + Dinner) All those are generated by fetching data from DB.

So for the first dropdown, if the user selects Deluxe, the options for the second dropdown should have 3 entries whereas if it selects Suite, the options should be only 2. How can this be achieved?

Template:

<div *ngFor="let room of flatRoomObject">
        <div>
          <span class="label" title="{{room.Room.Code}}" style="width: 500px;font-weight: normal">{{room.Room.Name}}</span>
          <span>
            <p-dropdown [options]="masterRooms" [style]="{'width':'195px'}" [(ngModel)]="room.Room.MasterId"></p-dropdown>
          </span>
        </div>
        <div *ngFor="let rateplan of room.Rateplans">
          <div>
            <span class="label" title="{{rateplan.Code}}" style="width: 500px;margin-left: 30px;font-weight: normal">{{rateplan.Name}}</span>
            <span>
              <p-dropdown [options]="masterRateplans" [style]="{'width':'165px'}" [(ngModel)]="rateplan.MasterId"></p-dropdown>
            </span>
          </div>
        </div>
      </div>

Please note that masterRooms is the list of rooms while masterRateplans are the one I intend to change dynamically depending on room selected on the first dropdown. masterRooms and masterRateplan are fetched from Db in the component.

1

There are 1 best solutions below

2
On

You can achieve this by changing the value of masterRateplans on the change of the first dropdown i.e. rooms dropdown. As masterReteplans is provided as options of the dropdown, changing its value in component on change of rooms dropdown will change the options visible in the rate plan dropdown.

So in the html, use (onChange) to bind a function on the change of the room dropdown for example we name that function changeRatePlan:

<div *ngFor="let room of flatRoomObject">
        <div>
          <span class="label" title="{{room.Room.Code}}" style="width: 500px;font-weight: normal">{{room.Room.Name}}</span>
          <span>
            <p-dropdown [options]="masterRooms" (onChange)="changeRatePlans()" [style]="{'width':'195px'}" [(ngModel)]="room.Room.MasterId"></p-dropdown>
          </span>
        </div>
        <div *ngFor="let rateplan of room.Rateplans">
          <div>
            <span class="label" title="{{rateplan.Code}}" style="width: 500px;margin-left: 30px;font-weight: normal">{{rateplan.Name}}</span>
            <span>
              <p-dropdown [options]="masterRateplans" [style]="{'width':'165px'}" [(ngModel)]="rateplan.MasterId"></p-dropdown>
            </span>
          </div>
        </div>
      </div>

Then in your logic, implement changeRatePlan function to change the value of masterRateplans. Something like the following:

public roomTypes:any={
    "Deluxe": [{
            label: 'Breakfast',
            value: 'Breakfast'
        },
        {
            label: 'Breakfast and Lunch',
            value: 'Breakfast and Lunch'
        },
        {
            label: 'Breakfast and Dinner',
            value: 'Breakfast and Dinner'
        }
    ],
    "Suite": [{
            label: 'Breakfast',
            value: 'Breakfast'
        },
        {
            label: 'Breakfast and Dinner',
            value: 'Breakfast and Dinner'
        }
    ]
}

changeRatePlan(){
    //for example if MasterId 1 is for deluxe room
    if(this.room.Room.MasterId==1)
    {
        this.masterRateplans=this.roomTypes.Deluxe;
    }
    //for suite
    else if(this.room.Room.MasterId==2)
    {
       this.masterRateplans=this.roomTypes.Suite;
    }
}

Please note the logic above is to give you an idea of how can you implement the function. Your actual implementation might be different for example you may have already stored the room types in a variable while i declared a new variable for your understanding. Hope this helps.