0

Right now this is my implementation for primeng dropdown -

cust.component.html -

<p-dropdown #dd1 [options]="custList" [ngModel]="selectedCust" placeholder="Select Account Id"
              [style]="{'width':'200px'}" name="selectDropDown" optionLabel="userName"
              (onChange)="dd1.value = changeCust($event.value)"></p-dropdown>

cust.component.ts -

private currentVal:Customer;
..
..
changeDEA(cust: Customer) {
    var cfg = confirm("This action will stop the file upload. Do you still want to continue? ");
    if(cfg){
      this.currentVal = cust;
      // Proceed with normal change event
    }else{
      console.log("user cancelled skip..");
      this.selectedCust = this.currentVal;
      // Should revert back to original value
      return this.selectedCust;
    }

Problem is that the view value shown in the screen is not being reverted to original value.

Expected Result -

Dropdown changes from Value A to Value B.
User confirmation - Select "Cancel".
Page should still show the old value i.e Value A.

Actual result -

Dropdown changes from Value A to Value B.
User confirmation - Select "Cancel".
Page should is showing new value B. (without primeng, its showing blank value - https://stackblitz.com/edit/angular-dropwdown-confirmation-issue)

Adding GIF -

enter image description here

Came across this code which works fine with native angular but fails when options are populated dyamically with *ngFor - https://stackblitz.com/edit/angular-dropwdown-confirmation-issue

FYI, tried various github posts but none of them found useful.

Angular Version - "@angular/core": "^5.2.0"
PrimeNG - "primeng": "^5.2.4"

SaratBhaswanth
  • 340
  • 7
  • 18

2 Answers2

1

Actually your model is working correctly. Your problem is selected index of dropdown. So u also need to change it. Demo

In html use (change) event

<select #dd1 id="pageSize" [(ngModel)]="myValue" (change)="onChange($event)"  

  placeholder="Select Account Id"> 
              <option *ngFor="let d of custList" [ngValue]="d.userName" >{{d.userName}}</option>
  </select> 

in component.ts change event target select index too

onChange(event) {
    const response = window.confirm("Are you sure to want change the value?");
    if (response) {

      this.oldValue = this.myValue;
    }
    else {
      this.myValue = this.oldValue;
      event.target.selectedIndex=this.custList.findIndex(x=>x.userName==this.oldValue)
    }
  }
mr. pc_coder
  • 16,412
  • 3
  • 32
  • 54
1

Just one more thing - here comes an implementation for a PrimeNG dropdown with a PrimeNG confirmation dialog and proper PrimeNG select items (that are actually localised enums). I had a very hard time trying to find a solution for this...

Angular version is 15.0.4, PrimeNG version is 15.0.0 (but it also worked with Angular version 14.2.12 and PrimeNG version 14.2.2).

The two main problems are:

  1. To get the currently selected item from the dropdown before the change happens (unfortunately, the currently selected item is not available in any event). This can be solved by using a @ViewChild on the dropdown and retrieving the value at run-time by means of onShow().

  2. To restore the last selected item if the user cancels the change in the confirmation dialog (using a SelectItem explicitely will lead to strange errors). This can be solved by not typing or initialising selectedInterval and lastInterval as a SelectItem and only using the value field.

dropdown-test.component.html

<p-confirmDialog
    [baseZIndex]="10000"
    [dismissableMask]="true"
    defaultFocus="reject"
    rejectButtonStyleClass="p-button-text"
    rejectLabel="No"
    acceptButtonStyleClass="p-button-text"
    acceptLabel="Yes">
</p-confirmDialog>
<p-toolbar>
    <p-dropdown
        #dropdownInterval
        [options]="intervalOptions"
        [(ngModel)]="selectedInterval"
        (onShow)="onShow()"
        (onChange)="onChange($event)">
    </p-dropdown>
</p-toolbar>

dropdown-test.component.ts

import {Component, OnInit, ViewChild} from '@angular/core';
import {Dropdown} from 'primeng/dropdown';
import {ConfirmationService, MessageService, SelectItem} from 'primeng/api';

@Component({
selector: 'app-dropdown-test',
templateUrl: './dropdown-test.component.html',
styleUrls: ['./dropdown-test.component.css']
})
export class DropdownTestComponent implements OnInit {

    @ViewChild('dropdownInterval') dropdownInterval: Dropdown;

    intervalOptions: SelectItem[] = [];

    selectedInterval: any; // Important NOT to type or initialise as SelectItem!

    lastInterval: any; // Important NOT to type or initialise as SelectItem!

    constructor(
      private confirmationService: ConfirmationService,
      private messageService: MessageService
    ) {
    }

    ngOnInit(): void {
        this.intervalOptions = this.getSelectItemsEn();
        this.selectedInterval = this.getSelectItemEnByUniqueName('MONTHLY');
    }

    onShow() {
        this.lastInterval = this.dropdownInterval.value; // Get the current value from the dropdown before the change takes place!
    }

    onChange(event) {
        if (this.lastInterval) { // Ignore the initial change in ngOnInit!
          this.confirmationService.confirm({
            header: 'Confirmation',
            icon: 'pi pi-question-circle',
            message: 'Do you want to change the selected item in the dropdown?',
            accept: () => {
               // TODO: Continue...
            }, reject: () => {
              this.lastInterval = this.selectedInterval;
            }
          });
        }
    }

    getSelectItemsEn(): SelectItem[] {
        const intervals: SelectItem[] = [];
        intervals.push({label: 'Monthly', value: 'MONTHLY'});
        intervals.push({label: 'Quarterly', value: 'QUARTERLY'});
        intervals.push({label: 'Yearly', value: 'YEARLY'});
        return intervals;
    }

    getSelectItemEnByUniqueName(uniqueName: any): SelectItem {
        if (uniqueName === 'MONTHLY') {
          return {label: 'Monthly', value: 'MONTHLY'};
        } else if (uniqueName === 'QUARTERLY') {
          return {label: 'Quarterly', value: 'QUARTERLY'};
        } else {
          return {label: 'Yearly', value: 'YEARLY'};
        }
    }

}
Jacky
  • 11
  • 2