Retain the Previously Selected Option in Angular 2 Dropdown

Looking for assistance with implementing a simple HTML select dropdown in Angular2 (TS) using the code below:

<select id="pageSize" (change)="onPageSizeChanged($event, pagination.pageSize)">
  <option value="10">10</option>
  <option value="20">20</option>
  <option value="50">50</option>
</select>

The variable pagination.pageSize stores the previously selected value. When this changes, I want to prompt the user with a dialog box and wait for their response. If they click cancel, I need to revert back to the previous selection.

onPageSizeChanged(event, oldValue) {
  const response = window.confirm("Are you sure you want change the page size? Your edits will be lost?");
  if (response) {
    //... some code ...
  } else {
    //... here I want to revert the selection to previously selected option
  }
}

I have tried various approaches but haven't had any success yet.

Please assist, as I am struggling with what should be a straightforward task. Perhaps I am missing something obvious.


Attempted Solution #1 - Not Working (Plunk - https://embed.plnkr.co/ILi12O/)

<select id="pageSize" [ngModel]="pageSize" (ngModelChange)="onPageSizeChanged($event, pagination.pageSize)"> 
  <option value="10">10</option> 
  <option value="20">20</option> 
  <option value="50">50</option> 
</select> 

onPageSizeChanged(event, oldValue) { 
  const response = window.confirm("Are you sure you want change the page size? Your edits will be lost?"); 
  if (response) { //go ahead so something } 
  else { this.pageSize = oldValue; }  
} 

Answer №1

To monitor model changes, include ngModelChange. Confirm the change in the dialog for the next step or revert to the previous value. Using a local template variable (#select) can simplify tracking. I have updated your code based on your plunker:

HTML:

 <select #select id="pageSize" [ngModel]="pageSize" (ngModelChange)="select.value = onPageSizeChanged($event)"> 

TypeScript:

   onPageSizeChanged(event) { 
   const response = window.confirm("Are you sure you want change the page size? Your edits will be lost?"); 
    console.log(this.pagination.pageSize)
    if (response) { 
      this.pageSize = event;
      this.pagination.pageSize = event;
    }
    else{
      this.pageSize = this.pagination.pageSize;
    }
    return this.pagination.pageSize;
  } 

demo

Answer №2

https://example.com/code-sample

A helpful tip for your component.html file...

Try implementing a template reference variable #pageSize on your select element

and on (change), assign the value of that variable (pageSize.value) to your onChangeSize method which we'll define shortly. Pass the pageSize.value to this onChangeSize method like this: (change) = "pageSize.value = onChangeSize(pageSize.value)

this will result in...

<select id="pageSize" #pageSize 
(change)="pageSize.value = onChangeSize(pageSize.value)">
  <option value="10">10</option>
  <option value="20">20</option>
  <option value="50">50</option>
</select>    

In your component.ts file, create a method that takes the value & after user confirmation, either return the input or default value.

export class MathComponent implements OnInit {
  defaultInput: number = 10;
  userInput: number = this.defaultInput;

  constructor() { }

  ngOnInit() {
  }

  onChangeSize(pageSize: HTMLSelectElement) {
    const response = window.confirm("Are you sure you want change the page size? Your edits will be lost?");
    if (response) {
      return pageSize;
    } else {
      return this.defaultInput;
    }
  }
}

https://example.com/code-sample

Answer №3

When dealing with Select controls that have asynchronous code in the (ngModelChange) method (such as async/await, Promise, rxjs Observable), an alternative solution can be used for Angular 6 and below.

      <select
        id="{{ user.emailAddress }}"
        class="form-control role-select"
        aria-label="Dropdown"
        [disabled]="busy"
        [(ngModel)]="user.role"
        (ngModelChange)="editUserRole(user)"
      >
        <option *ngFor="let role of (roles | async)" [value]="role">
          {{ role }}
        </option>
      </select>

In the controller:

public async editUserRole(user: IUser) {
    if (user.role === SubscriptionUserRole.DATA_DEFAULT && !this._hasAtLeastOneOtherAdmin(user)) {
      // To workaround the delay in updating HTML elements pre Angular V6, a setTimeout is utilized.
      // This may no longer be necessary in Angular V6.
      // zone.js and ngZone handle async operations for UI updates, avoiding the need for app.tick.
      setTimeout(() => {
        user.role = SubscriptionUserRole.DATA_ADMIN;
      }, 0);
      this.errorMessage = 'At least one user should be DataAdmin';
      return;
    }
    // Proceed with change operation such as database update here.
}

In certain cases, the delayed update could potentially cause issues.

The delay might become obsolete in Angular 6+ as FormControl now gets updated before ngModelChangeCall.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Defining a property of an object within a Vue Class

If I were to write it in JavaScript version: export default { data() { return { users: {} } } } However, when using a class style component with vue-property-decorator: @Component export default class Login extends Vue { public title ...

Tips for creating a Vuex mutation without using asynchronous promises

I have a project underway that involves building an app using Vue.js, Vuex, and Firebase to update data from Firestore database to the state in mutations. Even though mutations are synchronous and promises (.then) are asynchronous, my current implementat ...

Simulate a complete class with its constructor, instance methods, and static functions

I have been searching for a comprehensive example that demonstrates how to properly mock all three elements (ClassA constructor, ClassA.func1 instance function, and ClassA.func2 static function) in my TypeScript project. In the code under test, I need to v ...

Combine two sets of JavaScript objects based on their positions using Underscore.js

Data Set 1: {id: "01", name: "John Doe", age: "25", city: "New York", country: "USA"} Data Set 2: [{key:'id', value:'01'},{key:'name', value:'John Doe'},{key:'age', value:'25'},{key:'city& ...

Receiving warnings during npm installation and encountering difficulties with fixing issues using npm audit fix

Currently, I am working on developing an Angular application with a .NET Core Web API integration. Upon cloning the repository, I attempted to execute 'npm install' for the Angular application, but encountered an unexpected error: npm install n ...

Laravel has not been properly initialized

Recently, I've been exploring Laravel 5.3 and vue.js and I'm trying to make a GET request to fetch some user data from my database. I'm utilizing components in this project. Here is a snippet from my app.js file: require('./bootstrap ...

A simple guide on passing a variable from Node.js to the view

Currently, I am delving into the world of Node.js and encountering a hurdle in sending a variable from app.js to index.html without relying on Jade or any other template engine. Below is my implementation in app.js: var express = require("express"); var ...

Issues with rotating the camera in three.js are causing functionality problems

I have been working on a code snippet to rotate my camera around the x-axis within a three.js environment: var cameraOrginX = 0, cameraOrginY = 0, cameraOrginZ = 0; var cameraEndX = 0, cameraEndY = 0, cameraEndZ = 1000; var angle = 0; function initialize ...

Removing Multiple Object Properties in React: A Step-by-Step Guide

Is there a way in React to remove multiple object properties with just one line of code? I am familiar with the delete command: delete obj.property, but I have multiple object properties that need to be deleted and it would be more convenient to do this i ...

What is the best way to adjust the camera position in three.js while keeping it from rotating?

I've been working on an interface using three.js and the CSS3DObject rendering tool. To control movement, I've disabled rotation by setting the orbit to 0, allowing only panning and zooming. Just a heads up - I'm also utilizing Orbit Contro ...

Fetching data from MongoDB, loading over 3000 entries and implementing pagination

I'm facing a challenge where I need to display more than 3000 results in an HTML table by fetching MachineID, Username, and Data from my MongoDB. However, I am encountering difficulties when trying to render this data using datatables. The MachineID ...

What is the best way to ensure the header and sidebar stay fixed while allowing the rest of the page content to flow in

I am working on a website where I want the header and sidebar to remain fixed while the other pages open in the remaining space. How can I make the sidebar dynamic? Here is an example of what I am trying to achieve: https://i.sstatic.net/MBFesWfp.png How ...

Module '@tanstack/react-table' cannot be located even though it has been successfully installed

Currently, I am tackling a TypeScript React project and encountering an issue while attempting to import ColumnDef from @tanstack/react-table in my columns.tsx file. import { ColumnDef } from "@tanstack/react-table"; export type Payment = { id ...

Tips for retrieving a value from a callback function?

How do I return a value from a callback function? The following code snippet is what I have: function storeData(data) { const id = "5f354b7470e79f7e5b6feb25"; const body = { name: "john doe" }; bucket.insert(id, body, (error, r ...

How can the datetime value of the Apex Charts datapoint be shown in the tooltip?

I'm struggling to find the proper location within the w.globals object to display the x-axis value, which is a datetime, in the tooltip of the datapoint. var chartOptions = { ... xaxis: { type: "datetime" }, tooltip: { x: { format: " ...

I'm puzzled as to why the banner text for my three images in the slider is only displaying on one of the images, all crammed together

Currently, I am working on an ecommerce project with Next.js. One of the challenges I faced was while setting up my banner page that includes a react-slick slider for images. Initially, when I added just one image, I noticed multiple renderings of it, but ...

How can data be transferred between controllers in Angular 2 without using URL parameters or the $state.go() function?

I've encountered an issue where I need to pass a parameter from one controller to another without it being visible in the URL. I attempted to do so with the following code: this.router.navigate(['/collections/'+this.name], {id: this.id}); ...

Generate a blank image using the canvas.toDataURL() method

I've been attempting to take a screenshot of this game, but every time I try, the result is just a blank image. var data = document.getElementsByTagName("canvas")[0].toDataURL('image/png'); var out = document.createElement('im ...

Compiling errors arise due to TypeScript 2.4 Generic Inference

Experiencing issues with existing TypeScript code breaking due to changes in generic inference. For instance: interface Task { num: number; } interface MyTask extends Task { description: string; } interface Job {} type Executor<J> = <T ...

Compatibility with IE9: Using jQuery to send an AJAX POST request

I'm currently facing an issue with making a POST request from my website to a server that is not on the same domain. The functionality is working seamlessly on Chrome, Firefox, and IE10+, but I need to ensure it works on IE9 as well. Below is the cod ...