[SalesForce] lightning-input validation inside loop

I am new to lightning web component. I was trying to create a table where i take input of new records. I am putting one field for now, for simplicity.

<template for:each={allrecords} for:item='record' for:index="index">
                <tr key={item}>
                    <th scope="row" data-label="Remove">
                        <div class="slds-truncate" title="Remove" id={item} data-item={item} onclick={handleRemoveClick}>
                            <lightning-button-icon
                                icon-name="action:remove"
                                variant="border-filled"
                                data-item={item}
                                alternative-text="Remove">
                            </lightning-button-icon>
                            {index}
                        </div>
                    </th>
                    <td data-label="Account Name">
                        <div class="slds-truncate" title="Serial Number">
                            <lightning-input type="text" style="width:200px;" value={record.Serial_Number__c} onfocusout={serialNumberOut} required></lightning-input>
                        </div>
                    </td>
                </tr>
            </template>
<lightning-button label="Add New Row" variant="brand" onclick={addNewRow}></lightning-button>
<lightning-button label="Submit" variant="brand" onclick={submit}></lightning-button>

import { LightningElement, track } from 'lwc';
export default class PackageReportingForDealers extends LightningElement {
    @track allrecords = [];

    addNewRow(event){
        debugger;
        console.log(event);
        let newRow = {Serial_Number__c : ""};
        this.allrecords.push(newRow);
    }
    handleRemoveClick(event){
        alert('@@'+event.target.dataset.item);

    }
    serialNumberOut(event){
        console.log(event);
    }
    submit(event) {
       console.log(event);
    }

}

Here i have few questions..

  1. Why i can't use key={index}, in first . If these records are new, i can't use id. So i was thinking of using Index. And based on this, i will remove too.
    what would be best approach to do this?

  2. How can i validate and stop submission if fields are empty. There could be many rows and i have to perform validation and show error on all the records.
    How can i do this. Any code sample or resource for this ?

  3. handleRemoveClick –> here i am getting event.currentTarget and event.target
    as empty. I have used event.currentTarget.id, but in this case its coming empty.

Best Answer

Why i can't use key={index}, in first . If these records are new, i can't use id. So i was thinking of using Index. And based on this, i will remove too. what would be best approach to do this?

According to documentation IMPORTANT Every item in a list must have a key. When a list changes, the framework uses the key to identify each item so that it can rerender only the item that changed. The key must be a string or a number, it can't be an object. You can’t use index as a value for key. Assign unique keys to an incoming data set. To add new items to a data set, use a private property to track and generate keys. Use Id of record. When records are not there, it will not even go inside iteration - so no problem

How can i validate and stop submission if fields are empty. There could be many rows and i have to perform validation and show error on all the records. How can i do this. Any code sample or resource for this ?

You can use this.template.querySelector('lightning-input').checkValidity(). This will return if its valid or not based on whether you defined it as required, min, max etc. For identifying all inputs use querySelectorAll and forEach. Refer https://salesforcesas.home.blog/2019/07/16/lwc-selectors-identification-of-elements/

handleRemoveClick --> here i am getting event.currentTarget and event.target as empty. I have used event.currentTarget.id, but in this case its coming empty.

what is item in data-item={item}. You are using for:item='record' so it should be something like record.Name, record.Id, record.myfields__c etc