Icon for the Lightning Components topic

How to add or remove rows dynamically [LWC]

In this tutorial, I will show you how to add or remove rows dynamically using Lightning Web Components. In the GIF below you can see the final result.

How to add or remove rows dynamically in Lightning Components

lwcDynamicRecordRowsCreation.html

<template>

    <div class="slds-card" style="font-family: 'Open Sans', sans-serif">

        <!-- Header -->
        <header class="slds-card__header slds-media slds-media_center">
            <div class="slds-media__figure">
                <lightning-icon icon-name="standard:account" size="small"></lightning-icon>
            </div>
            <div class="slds-media__body slds-card__header-title slds-text-title_bold" style="font-size: 14px">
                Account Creation
            </div>
        </header>

        <!-- Table -->
        <table class="slds-table slds-table_bordered slds-no-row-hover slds-table_cell-buffer" role="grid">
            <thead>
            <tr>
                <th scope="col" height="22" style="width: 3rem">Nr.</th>
                <th scope="col" height="22">Name</th>
                <th scope="col" height="22">Website</th>
                <th scope="col" height="22">Phone</th>
                <th scope="col" height="22" style="width: 3rem"></th>
            </tr>
            </thead>
            <tbody>
            <template for:each={listOfAccounts} for:item="rec">
                <tr key={rec} class="slds-hint-parent">
                    <td style="font-weight: bold">
                        <lightning-formatted-number value={rec.index}></lightning-formatted-number>.
                    </td>

                    <td>
                        <lightning-input type="text" variant="label-hidden" label="" data-id={rec.index} name="Name" value={rec.Name} onchange={handleInputChange}></lightning-input>
                    </td>

                    <td>
                        <lightning-input type="text" variant="label-hidden" label="" data-id={rec.index} name="Website" value={rec.Website} onchange={handleInputChange}></lightning-input>
                    </td>

                    <td>
                        <lightning-input type="text" variant="label-hidden" label="" data-id={rec.index} name="Phone" value={rec.Phone} onchange={handleInputChange}></lightning-input>
                    </td>

                    <td>
                        <lightning-button-icon icon-name="utility:delete" alternative-text="Remove" title="Remove" name={rec.index} onclick={removeRow}></lightning-button-icon>
                    </td>
                </tr>
            </template>
            </tbody>
        </table>
        <div class="slds-p-left_small slds-p-vertical_small">
            <lightning-button class="slds-p-right_small" variant="destructive" label="delete all rows" title="delete all rows" icon-name="utility:recycle_bin_full" onclick={removeAllRows}></lightning-button>
            <lightning-button variant="neutral" label="add additional row" title="add additional row" icon-name="utility:add" onclick={addNewRow}></lightning-button>
        </div>

        <!-- Footer -->
        <footer class="slds-modal__footer" style="padding: 0.50rem 1rem;">
            <lightning-button icon-name="utility:save" variant="brand" label="Create Accounts" title="Create Accounts" onclick={createAccounts}></lightning-button>
        </footer>
    </div>

</template>

lwcDynamicRecordRowsCreation.js

import {LightningElement, track} from 'lwc';

//APEX-Methods
import insertAccounts from '@salesforce/apex/SfWiki_Handler.insertAccounts'
import {ShowToastEvent} from "lightning/platformShowToastEvent";

export default class LwcDynamicRecordRowsCreation extends LightningElement {

    @track listOfAccounts;

    connectedCallback() {
        this.initData();
    }

    initData() {
        let listOfAccounts = [];
        this.createRow(listOfAccounts);
        this.listOfAccounts = listOfAccounts;
    }

    createRow(listOfAccounts) {
        let accountObject = {};
        if(listOfAccounts.length > 0) {
            accountObject.index = listOfAccounts[listOfAccounts.length - 1].index + 1;
        } else {
            accountObject.index = 1;
        }
        accountObject.Name = null;
        accountObject.Website = null;
        accountObject.Phone = null;
        listOfAccounts.push(accountObject);
    }

    /**
     * Adds a new row
     */
    addNewRow() {
        this.createRow(this.listOfAccounts);
    }

    /**
     * Removes the selected row
     */
    removeRow(event) {
        let toBeDeletedRowIndex = event.target.name;

        let listOfAccounts = [];
        for(let i = 0; i < this.listOfAccounts.length; i++) {
            let tempRecord = Object.assign({}, this.listOfAccounts[i]); //cloning object
            if(tempRecord.index !== toBeDeletedRowIndex) {
                listOfAccounts.push(tempRecord);
            }
        }

        for(let i = 0; i < listOfAccounts.length; i++) {
            listOfAccounts[i].index = i + 1;
        }

        this.listOfAccounts = listOfAccounts;
    }

    /**
     * Removes all rows
     */
    removeAllRows() {
        let listOfAccounts = [];
        this.createRow(listOfAccounts);
        this.listOfAccounts = listOfAccounts;
    }

    handleInputChange(event) {
        let index = event.target.dataset.id;
        let fieldName = event.target.name;
        let value = event.target.value;

        for(let i = 0; i < this.listOfAccounts.length; i++) {
            if(this.listOfAccounts[i].index === parseInt(index)) {
                this.listOfAccounts[i][fieldName] = value;
            }
        }
    }

    createAccounts() {
        insertAccounts({
            jsonOfListOfAccounts: JSON.stringify(this.listOfAccounts)
        })
            .then(data => {
                this.initData();
                let event = new ShowToastEvent({
                    message: "Accounts successfully created!",
                    variant: "success",
                    duration: 2000
                });
                this.dispatchEvent(event);
            })
            .catch(error => {
                console.log(error);
            });
    }

}

SfWiki_Handler.cls

public without sharing class SfWiki_Handler {

    @AuraEnabled
    public static void insertAccounts(String jsonOfListOfAccounts) {
        List<Account> listOfAccounts = (List<Account>) JSON.deserialize(jsonOfListOfAccounts, List<Account>.class);
        insert listOfAccounts;
    }

}

That’s it!

I hope you have enjoyed learning “How to add or remove rows dynamically [LWC]”. Please share your thoughts in the comments below. If you find value in this type of post, please subscribe because we have tons of tutorials in progress to be posted!

If you prefer to see the result with Lightning Aura Components, here’s the link to it: How to add or remove rows dynamically [Aura].

How to create a reusable field search Lightning Component using Lightning Aura Components

How to create a reusable field search Lightning Component [Aura]

In this tutorial, I will show you how to create a reusable field search Lightning Component in Lightning Aura Components.

How to create a reusable field search Lightning Component using Lightning Web Components

How to create a reusable field search Lightning Component [LWC]

In this tutorial, I will show you how to create a reusable field search Lightning Component in Lightning Web Components.

How to create a reusable Lookup Lightning Component

How to create a reusable Lookup Lightning Component [Aura]

In this tutorial, I will show you how to create a reusable Lookup Lightning Component in Lightning Aura Components.

How to create a reusable Lookup Lightning Component

How to create a reusable Lookup Lightning Component [LWC]

In this tutorial, I will show you how to create a reusable Lookup Lightning Component in Lightning Web Components.

How to remove Lightning App Page Header

How to remove Lightning App Page Header [Aura]

In this tutorial, I will show you how to remove Lightning App Page Header in Lightning Aura Components.

Leave a comment!

0 0 votes
Article Rating
guest
0 Comments
Inline Feedbacks
View all comments
Hamid Abassi

Hamid Abassi

SfWiki Founder

I am a Salesforce Developer from Hamburg who wants to help the Salesforce Community around the world with my tutorials. Feel free to explore my website and hopefully learn something new.