Step-by-step guide on incorporating edit, update, and discard functionalities within an Angular Material table component (mat-table)

I am currently working on implementing edit, update, and discard functions in an angular material table. While I have been able to successfully edit and update the table row wise, I am struggling with how to discard table rows.

If you would like to see what I have done so far, please click on this StackBlitz link to the table. Any help on how to implement the discard function would be greatly appreciated. I am particularly struggling with keeping the initial values of data cells intact. Even though I tried to create a copy of the original data to move back to the table when the discard button is clicked, due to 2-way data binding it keeps updating the original data directly (which is the company details array received from the backend). It's quite puzzling to me how this is happening and affecting the original data. Your assistance on this matter is urgently needed. Thank you in advance!

Answer №1

To manage form field data efficiently, consider switching the ngModel to a temporary copy that can be discarded or saved based on user actions. If the user chooses to discard, simply remove the working copy and revert to the original data. However, if they wish to save, use Object.assign to apply the changes to the table data.

For more information, visit: https://stackblitz.com/edit/angular-material-starter-njrnu9?file=app/app.component.ts

This approach may not be flawless, but it could offer helpful insights for your needs.

Answer №2

When making edits, always remember to create a copy of the element. You have two options:

1.- Use [ngModel] with the copy, and update the value accordingly

2.- Use [ngModel] with the original element, and cancel by assigning the copied value back

To create a copy, make sure to use the spread operator to avoid assigning the same object to multiple variables.

this.oldValue={...element}

If you prefer editing one row at a time, consider using an unique variable like editIndex instead of keeping track in an array whether a row is in edit mode or not.

  editIndex:number=-1;
  editCompanyDetails(details,i) {
    this.editIndex=i;
  }

In this approach, I choose to edit the "copy" by declaring a variable newValue.

  newValue:any;
  editCompanyDetails(details,i) {
    this.editIndex=i;
    this.newValue={...details}
  }

Take note that the mat-form field cannot be used both in edit mode and read-only mode simultaneously. Therefore, separate form fields are needed for element and newValue.

      <!-- Separated form fields for element and newValue -->

The update and cancel functions should look like this:

  updateCompanyDetails(i){
    this.dataSourceCompanyDetails.data[i]={...this.newValue}
    this.editIndex=-1;
  }

  discardCompanyDetails(){
    this.editIndex=-1;
  }

You can refer to this forked stackbliz for implementation details.

A check has been added in the edit function to prompt if changes will be lost when editing another field while already editing one (not in stackblitz).

  editCompanyDetails(details,i) {
    if (this.editIndex!=i && this.editIndex!=-1)
    {
       const data=dataSourceCompanyDetails.data[this.editIndex]
       if (data.status!=this.newValue.status || data.companyName!=this.newValue.companyName){
         ..prompt about losing changes..
       }
    }
    this.editIndex=i;
    this.newValue={...details}
  }

Updated: Another approach involves declaring a variable oldValue, accessing the table using ViewChild, and ensuring to call renderRows when cancelling the edit.

@ViewChild('table') table:MatTable<any>
oldValue:any;

Function updates as follows:

  editCompanyDetails(details,i) {
    this.editIndex=i;
    this.oldValue={...details}
  }

  updateCompanyDetails(){
    this.editIndex=-1;
  }

  discardCompanyDetails(i){
    this.dataSourceCompanyDetails.data[i]={...this.oldValue}
    this.editIndex=-1;
    this.table.renderRows()
  }

Remember to change [NgModel] to [ngModel] for consistency. Check out the updated implementation in this new stackblitz.

Answer №3

If you're looking to effectively implement discard functionality, there's a better approach than utilizing 2-way data binding. You can opt for reactive forms and create form arrays instead. Here's a solution I recommend checking out: Discard Functionality in Table

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

none of the statements within the JavaScript function are being executed

Here is the code for a function called EVOLVE1: function EVOLVE1() { if(ATP >= evolveCost) { display('Your cell now has the ability to divide.'); display('Each new cell provides more ATP per respiration.'); ATP = ATP ...

What is the best way to pass the JWT token to the subsequent page once a user has successfully logged in on Next.js?

Introduction I am currently working on a login application using Nextjs for the frontend and Spring Boot for the backend. Issue The problem I am facing is that after successfully logging in from the frontend, which calls the /authenticate login API devel ...

What is the best method to consistently convert a deeply nested object into a tabular format that can be easily reversed

Imagine having a deeply nested object with an unknown structure until runtime, like: { "row-0" : { "rec-0" : { "date" : 20220121, "tags" : [ "val-0" ] }, ...

Displaying a project in the same location using jQuery

Struggling with jQuery and positioning hidden items that need to be shown? I have two white boxes - the left one is the Client Box (with different names) and the right one is the Project Box (with different projects). My goal is to show the projects of a c ...

Utilizing streams for file input and output operations in programming

This unique piece of code allows for real-time interaction with a file. By typing into the console, the text is saved to the file and simultaneously displayed from it. I verified this by manually checking the file myself after inputting text into the cons ...

Table with expansive width housed in a div container but the div container fails to

How can I make a parent div expand when the child table exceeds the page width? What is the most effective CSS approach to achieve this? ...

The background color of the CSS div tag does not cover the entire axis

I'm facing a dilemma in my CSS design that's got me stuck. This issue also seems to be present in this forum: Whenever I zoom in on the page, I noticed that the header background doesn't fully extend across the screen horizontally. Here&apo ...

What is the correct method for adjusting the height properties of an element?

I'm trying to adjust the height of my div using the code below var heightMainDiv = window.innerHeight - 50; var myDiv = $("#main_content")[0]; myDiv.clientHeight = heightMainDiv; myDiv.scrollHeight = heightMainDiv; However, the values of clientHeigh ...

What is the best way to implement a nested lookup in MongoDB within a field?

Within my database, I have a collection named Randomhospital. Inside this collection, there is a field named hospital structured as follows: { "id": "GuDMUPb9gq", "Hospital Name": "UPHI", "Hospital City&qu ...

Understanding and processing HTML strings in typescript

I am currently utilizing TypeScript. Within my code, there is an object named "Reason" where all variables are defined as strings: value, display, dataType, and label. Reason = { value: '<ul><li>list item 1</li><li&g ...

Tips for placing images on top of each other without overlapping other sections using 'position: absolute' in HTML and CSS

Is there a way to position one image on top of another in a responsive manner? I tried using position: absolute and z-index, but the result is not responsive. When the screen size changes, the image ends up on top or behind another section instead of expan ...

Toggle the visibility of 2 Form Fields by checking the Checkbox

Hi, I am trying to display two form fields when a checkbox is selected. These fields are required, so they should only be displayed when the checkbox is checked and should be mandatory. However, I am facing issues with hiding the fields when the checkbox i ...

Delayed hover dropdown navigation menu powered by Bootstrap

I am experimenting with creating a bootstrap dropdown menu that opens and closes on hover, but only after a 250ms delay for desktop devices. Custom JavaScript: $(document).ready(function() { if ($(window).width() > 767) { $(".dropdown-toggl ...

Using Typescript to remove an element from an array inside another array

I've encountered an issue while trying to remove a specific item from a nested array of items within another array. Below is the code snippet: removeFromOldFeatureGroup() { for( let i= this.featureGroups.length-1; i>=0; i--) { if( this.featureGr ...

What is the best way to ensure that the question text will wrap onto a new line if it becomes too lengthy

I am currently working on developing ASP.NET MVC applications. However, I am facing a design issue with the HTML, CSS, and Bootstrap elements on one of my pages. The problem arises when Question 8 exceeds the border and does not wrap to a new line as inte ...

Developing single-page application frontends without utilizing node or npm

As a backend java developer with experience in spring boot, I am now exploring the world of single page applications. One aspect that appeals to me about SPA frameworks, particularly Vue, is things like model-binding and the use of components and template ...

Neighbor wrapping causing Flex to shrink

Is there a way to make the element shrink when the flex container below grows due to flex-wrapping? Currently, the new space is created below the container instead of shrinking the one above. The flex-grow and flex-shrink properties do not seem to work as ...

Is TypeScript's nullish coalescing operator (??) supported by more browsers compared to JavaScript's equivalent?

When it comes to the nullish coalescing operator (??) in JavaScript, browser support is limited to newer browsers such as Chrome 80, Edge 80, and Firefox 72. Since TypeScript gets converted to JavaScript, do nullish coalescing operators also undergo some ...

Displaying components in Vue 2 using data from an ajax call

How can components retrieved from an ajax response be rendered? For instance, suppose I have registered a component called "Test" and within the ajax response I encounter: <p>dummy paragraph</p> <test></test> <!-- vue component ...

Disable browser suggestions in Material UI's Autocomplete component

Encountering an issue with Material-ui Autocomplete: import Autocomplete from "@material-ui/lab/Autocomplete"; Currently using it in: <Autocomplete id="checkboxes-tags-demo" autoComplete={false} options={sta ...