7

I have a <select> which the user can change. Initially it has a value and when the user changes it I must prompt her "are you sure"? and in case the answer is NO then change back the <select>'s selected value to the previous one. The <select> is bound to a collection of objects, not values.

The best I could come up with so far is this:

  • in the html
<select [ngModel]="selectedObj" (ngModelChange)="onSelectedObjChanged($event)">
    <option *ngFor="let obj of availableObjs" [ngValue]="obj">{{whatever}}<option>
</select>
  • in the code
onSelectedObjChanged(obj) {
  if (prompt answer is no) {
     let currentlySelectedObj = this.selectedObj;
     this.selectedObj = null;
     this.changeDetectorRef.detectChanges();
     this.selectedObj = currentlySelectedObj;
     this.changeDetectorRef.detectChanges();
  }
}

This works, but is ugly. Why do I do it:

  • there seems to be no way to cancel the selection changed event in the DOM
  • when onSelectedObjChanged is called and the answer is "no", I need to somehow let angular know it has to refresh the binding target, i.e. the <select>...
  • ...however I can't simply set this.selectedObj = this.selectedObj as the value doesn't change and there no change detected by angular; that's why I set it to null and back...
  • ...however even that is not enough, I need to invoke changeDetectorRef.detectChanges() to notify angular of it

I'm sure there is a better and easier way to do this, it would be great if you could share some ideas.

Thanks!

developer033
  • 24,267
  • 8
  • 82
  • 108
adrian h.
  • 2,996
  • 3
  • 18
  • 24
  • `ngModel` shouldn't be written this way => `[(ngModel)]`? – developer033 Jul 21 '16 at 20:34
  • It can, but then you're not notified of when the value changes so that you can prompt the user. `[(ngModel)]` expands to `[ngModel]=x (ngModelChange)=y` – adrian h. Jul 22 '16 at 05:20
  • Possible duplicate of [Angular2 Dropdown revert to previously selected option](https://stackoverflow.com/questions/46357952/angular2-dropdown-revert-to-previously-selected-option) – jsalvata Apr 18 '18 at 13:32

3 Answers3

11

Here's how I did it:

HTML:

<select [(ngModel)]="option"
        #selectModel="ngModel"
        (ngModelChange)="optionChanged($event)">
    <option [ngValue]="null">PlaceHolder</option>
    <option *ngFor="let o of options" [ngValue]="o">...</option>
</select>

Component:

@ViewChild('selectModel') private selectModel: NgModel;

optionChanged($event) {
    //logic
    this.selectModel.reset(null);
}
RVandersteen
  • 2,067
  • 2
  • 25
  • 46
0

I use $event.target.value instead of $event. I send this.selectedObj = $event.target.value; and if failed change this.selectedObj = previousObject I don't need any change detection.

Julie David
  • 41
  • 3
  • 6
  • I suspect you are using plain values and not a list o bound objects? Also, where do you keep `previousObject`? – adrian h. Jul 22 '16 at 05:21
  • I am using `` where actionList is a string Array. I set a default this.selectedObject = this.previousObject from actionList and if the myAction() function returns false, I set this.selectedObject to that again. – Julie David Jul 22 '16 at 06:54
-1

try this.selectedObj = obj.target.value; and than perform your condition.