[SalesForce] LWC create input fields under LWC iteration

I am new to LWC. I have to create multiple input fields for different rows. Let say, I have selected 3 records from the previous page and for all those 3 records I need to create the input field and once I fill these fields need to create records. Please check my code below.

<lightning-record-edit-form object-api-name="OpportunityLineItem">
    <lightning-messages></lightning-messages>
    <template for:each={selectedCons} for:item="oli">
        <div key={oli.Id} >
            {oli.Name} &nbsp; {index} 
            <lightning-input label="Quantity" type="Number" value={} placeholder="Quantity" onchange={QuantityChange}></lightning-input>
            <div onclick={addRecord}>
                <lightning-icon icon-name="utility:add" size="small"></lightning-icon>
            </div>
        </div>
    </template>
    <lightning-button variant="brand" label="create account" title="create account" onclick={handleCreateAccount}
    class="slds-m-left_x-small"></lightning-button>
    <!-- <lightning-button
        class="slds-m-top_small"
        type="submit"
        label="Create new">
    </lightning-button> -->
</lightning-record-edit-form>

QuantityChange(event){
    this.Quantity = event.target.value;
    console.log('Quantity is -- ', this.Quantity);
}

Here 'selectedCons' is list of records which I have selected I could see 3 different input Quantity fields. Once changing the quantity I can see only 1 quantity in console log which was updated last but I can not find the other 2.
How could I get all these values in an array and push it to the controller?
Please Help!

Best Answer

There are few problems in your code

  • You are referring to {index} in the HTML, but you have not defined that like I have done in the below code.
  • you are not assigning the value of the field to the input.
  • you are not updating the value of the element at a particular index in the list.
  • The last one is not a problem but it's not proper as per naming conventions. Looks like you are iterating on the list of oil but your variable name is selectedCons, I think it should be selectedOlis.

Why your code does not work?

To be able to update the field dynamically from the list of inputs, you need to pass the index of the array and the field to be updated to the onchange function. You need to write a generic method to update values. Make these changes to the input fields. Both of these you can pass from HTML as data attributes.

HTML code

<template for:each={selectedOlis} for:item="oli" for:index="index">
    <div key={oli.Id}>
        {oli.Name} &nbsp; {index}
        <lightning-input data-index={index} data-field-api-name="Quantity" label="Quantity" type="Number" value={oli.Quantity}
            placeholder="Quantity" onchange={handleListInputChange}>
        </lightning-input>
        <div onclick={addRecord}>
            <lightning-icon icon-name="utility:add" size="small"></lightning-icon>
        </div>
    </div>

JS function

handleTableInputChange(event) {
    // clone the array
    let newArray = [...this.selectedOlis];

    // get the row to be updated and update the field value
    let updatedRow = {...newArray[event.target.dataset.index], [event.target.dataset.fieldApiName]: event.detail.value};

    // replace the updated item in the array.
    newArray[event.target.dataset.index] = updatedRow;

    // update the actual array property
    this.selectedOlis = newArray;
}

Please note that you can use the same function for all of the inputs and it will work fine. You just need to make sure that you put the correct data-field-api-name and data-index in the HTML markup. Let me know if you face any problem!

Related Topic