1

Brief context: I have a page with n number of rows using for:each={rows} for:item="row". Each row has its own checkbox. There is a filtering feature that (by rerendering the with a getter) hides/shows these rows from the DOM based on the entered criteria.

The issue is that the state of the checkbox is not "remembered" after being filtered out.

Example: Default for all checkboxes is unchecked > I check one checkbox ON > enter a criteria to filter out this checkbox from the page > remove the filter > my checkbox shows again and returns to default state, OFF.

Each row has the appropriate boolean via row.isChecked for whether or not it should be checked stored in my JS. Is there something analogous to the following?

HTML: <lightning-input type="toggle" checked={row.isChecked}></lightning-input>

Because, unfortunately in HTML, the presence/absence of the 'checked' attribute controls the state.

I haven't found a way to effectively use the setAttribute() and removeAttribute() methods.

EDIT: I can NOT use querySelectors for this.

1

For Boolean values, the attribute will behave as present when true, and not-present when false. There's no need to set/unset the attribute. Here's a working Playground example (copy-paste into a new component to test):

<template>
    <lightning-input label="Filter" onchange={filter}>
    </lightning-input>
    <table>
        <thead>
            <th></th>
            <th>Name</th>
        </thead>
        <tbody>
            <tr key={row.id} for:each={rows} for:item="row">
                <td>
                    <lightning-input label="Selected" variant="label-hidden" type="toggle" checked={row.checked} onchange={update} data-row-id={row.id}>
                    </lightning-input>
                </td>
                <td>
                    {row.name}
                </td>
            </tr>
        </tbody>
    </table>
</template>

import { LightningElement } from 'lwc';

export default class App extends LightningElement {

    data = [
        { id: '1', name: 'Mickey Mouse', checked: false },
        { id: '2', name: 'Donald Duck', checked: false },
        { id: '3', name: 'Goofy Goof', checked: false },
        { id: '4', name: 'Pluto', checked: false }
    ];
    rows = [...this.data];
    filter(event) {
        if(event.target.value) {
            const p = new RegExp(event.target.value,'i');
            this.rows = [...this.data].filter(item => p.test(item.name));
        } else {
            this.rows = [...this.data];
        }
    }
    update(event) {
        this.data.find(item => item.id === event.target.dataset.rowId).checked = event.target.checked;
        this.rows.find(item => item.id === event.target.dataset.rowId).checked = event.target.checked;
        this.rows = [...this.rows];
    }
}

And here's a similar webcomponents demo you can play with.

2
  • This works for me. Thank you for this excellent example @sfdcfox. If I had 15+ rep I would upvote it. – JMRiss Oct 8 '20 at 17:03
  • @JMRiss If you want to, you can click the checkmark next to the answer. This will give me +15, you +2 points, as well as letting people know this answer solved your problem. – sfdcfox Oct 8 '20 at 21:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.