1

Can someone help me how to make this work please. Wanted to disable the button based on the following criteria //Diabled criteria - MUST be disbaled for all rows except for last row. //Background - we have an ADD button, which once clicked will create an empty row with blank values allowing the user to either manually input or click on "Clone Prev Row values" button to copy previous rows values on to new row.

<template for:each={actualHoursItems} for:item="record" for:index="index">
   <tr key={record} data-id={index}>
      <td role="gridcell" width="15">
         <lightning-input type="text" data-index={index} name="totalHours"
            value={record.totalHours} onchange={handleActualHoursUpdate} disabled></lightning-input>
      </td>
      <td role="gridcell" width="15">
            <lightning-button data-index={index} variant="base" label="Clone Prev Row values" disabled={isDisabled}
            onclick={handleActualHoursClonePrev} ></lightning-button>
      </td>
   </tr>
</template>

However, this disabled={index === 0 || actualHoursItems.length != index+1 ? true : false} is throwing following error & I'm not sure how to resolve it. FYI I wanted to make it work this way with in html instead of using js and passing something like "isdisabled" value. Invalid HTML syntax: unexpected-equals-sign-before-attribute-name Invalid HTML syntax: unexpected-character-in-unquoted-attribute-value enter image description here

2 Answers 2

1

For disabling a particular button from the list of objects , you need to add a boolean property to each object of the iteration array.

e.g. Let's consider actualHoursItems as below :

actualHoursItems = [{
        Id: 1,
        Name: "abc",
        totalHours: 2
    },
    {
        Id: 2,
        Name: "pqr",
        totalHours: 3
    },
    {
        Id: 3,
        Name: "xyz",
        totalHours: 4
    }
];

Now , for adding the disabled property to every object in array use object spread operator along with JS map function as below :

//Declare an empty array for the modified output. 
@track modifiedActualHoursItems = [];

//Modify it in wired/renderedCallback or wherever you are setting actualHoursItems as below:

    this.modifiedActualHoursItems = this.actualHoursItems.map((obj, index, array) => ({
        ...obj,
        isDisabled: index !== array.length - 1 //Add your desired condition here
    }));

In the HTML , use the modifiedActualHoursItems array and isDisabled property as below :

<template for:each={modifiedActualHoursItems} for:item="record" for:index="index">
    <tr key={record.Id} data-id={index}>
      <td role="gridcell" width="15">
        <lightning-input type="text" data-index={index} name="totalHours"
           value={record.totalHours} onchange={handleActualHoursUpdate} disabled></lightning-input>
     </td>
     <td role="gridcell" width="15">
           <lightning-button data-index={index} variant="base" label="Clone Prev Row values" disabled={record.isDisabled}
           onclick={handleActualHoursClonePrev} ></lightning-button>
     </td>
    </tr>
  </template>

Notice that now lightning-button has disabled attribute which refers to the individual object property as record.isDisabled

Next question would be - How to update the isDisabled attribute when rows are added dynamically by Add button ?

On click of add new row , we just set the isDisabled property to true for the last object in the array and make it false for the newly added object.(Since we are adding it at the end.)

The add button click handler would look like :

handleClick() {
    const arrayLength = this.modifiedActualHoursItems.length;
    //Set the isDisabled property to true for the last object
    this.modifiedActualHoursItems[arrayLength - 1].isDisabled = true;

    // Since we are adding the new row at the end , set isDisabled to false for new object
    const newObj = {
        Id: this.modifiedActualHoursItems.length,
        Name: "wer",
        totalHours: 5,
        isDisabled: false
    };
    this.modifiedActualHoursItems.push(newObj);
}
2
  • Looks like I have to take this approach @Rohit. Will let you know how it goes. Thank you & appreciate your help!
    – SMorse
    Mar 22 at 4:21
  • Welcome @SMorse . I was following this question to check if there is any alternative. The issue with passing index from html to JS is that lightning-button is in iteration and you would need to repetitively query the element which is comparatively worse.
    – Rohit
    Mar 22 at 4:25
0

In LWC you can not add conditions like this, you need to create a JS variable and do the calculation over there.

get isDisabled(){
  return this.index === 0 || this.actualHoursItems.length != this.index+1 ? true: 
  false;
}
<lightning-button data-index={index} variant="base" label="Clone Prev Row values" disabled={isDisabled}
            onclick={handleActualHoursClonePrev} ></lightning-button>
4
  • for some reason the isDisabled() isn't working and it is enabling "clone prev" at all rows. Any thoughts?
    – SMorse
    Mar 21 at 0:10
  • @SMorse what do you mean it's not working? is your logic wrong? or is it not getting a value from the isDisabled getter? it sounds like it's working perfectly, but your logic is wrong.
    – Nick C
    Mar 21 at 1:40
  • @SMorse, can you share the updated code Mar 21 at 5:43
  • Updated my html disabled attribute above. Noticed that this.index is "undefined" in this case which is a desired ask by js, thus it is enabling at all rows. How do I pass row specific index from html to isDisabled() [something similar to Disabled = {isDisabled(index)}] so that it can compute accurately by row specific data-index value?
    – SMorse
    Mar 21 at 14:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .