1

I have a requirement to create a component that is essentially 2 tables, parent/child. The parent table is Subscriptions, and the child table is Subscription Products that are related to that subscription. both tables have different headers, the parent table has radio buttons, and the child has checkboxes. the user selects one of the specific subscriptions, the child table displays, then user checks the child products they want to act on.

Right now I am pulling the data in a single query/backend method, and building one of the objects for displaying the parent table on the front end.

my problem is two fold but mostly layout wise. I have created the relationship between subscription and products, but when I try nesting both tables with a for:each directive I can't seem to align them, the child table goes into the first column of the parent table. It also renders under each subscription row, and I only want it to render on the selected parent row it is related to.

I have also tried with lightning-layout, which seems like it will get me the same visuals as a table but I'm still struggling a bit with the nesting. I know I can also make some rows a child component, but the issue is still i need to conditionally render within each specific row, so its really a 3rd layer of conditional rendering almost.

I can share code but I guess this is more of an architecture question. I have "subscriptions" and "subscription products" in an object, so they are available to easily iterate over, and I have the event handling built for each table. So really just looking for if this is possible and suggestions on the approach for the conditional rendering?

enter image description here

3
  • I would try a single unnested standard table for this - but just make sure you use the correct colspan and rowspan values to get it looking right. If you make a separate component for this, it will solve a lot of probs, but lining up the headers will be tricky. May 18 at 19:02
  • ah, +1 on the colspan, drew a blank on that and it helped with the layout part of this a lot! May 18 at 20:11
  • Don't forget rowspan - that will help with the first bit with the radio button May 18 at 20:13
0

Here's what worked for me. I'm pretty green so there's probably a cleaner way, I created a child component with the products:

<template>
    <table>
        <thead>
            <th></th>
            <th>Product Name</th>
            <th>Start Date</th>
            <th>Term Length</th>
            <th>Seats</th>
            <th>Expiring</th>
        </thead>
        <tbody>
        <template for:each={selectedSubProds} for:item="product">
            <tr key={product.srpId}> 
                <td class="checkbox-cell">
                <input type="checkbox" data-key={product.srpId} name="selectedproduct" value={product.srpId} checked={checked} onchange={handleProdChange}/></td>
                <td>{product.name}</td>
                <td><lightning-formatted-date-time value={product.startDate} year="numeric" month="numeric" day="numeric" ></lightning-formatted-date-time></td>
                <td>{product.termLength}</td>
                <td>{product.seats}</td>
                <td><lightning-formatted-date-time value={product.expirationDate} year="numeric" month="numeric" day="numeric"></lightning-formatted-date-time></td>
            </tr>
        </template>
        </tbody>
    </table>

then I put it in the parent

<template for:each={subscriptionsTable} for:item="sub">
    <tr key={sub.id} data-key={sub.id} data-name="subs">
        <td class="radio-cell">
            <input type="radio" data-key={sub.id} name="subscription" value={sub.id} onchange={handleSubChange}/>
        </td>
        <td colspan="2">{sub.name}</td>
        <td><lightning-formatted-date-time value={sub.customerAcceptanceDate} year="numeric" month="numeric" day="numeric" time-zone="UTC"></lightning-formatted-date-time></td>
        <td colspan="4">{sub.mrr}</td>
    </tr>
    <tr data-name="child-table" data-key={sub.id} key={sub.id}>
        <td colspan="5">
            <c-subscription-products
                data-active-key={sub.id} 
                key={sub.id}
                onselected={handleProdChange}
            >
            </c-subscription-products>
        </td>
    /tr>   
</template>      

then i called the function to select the child products from the parent to the child component, matching the rowId, and also edited display properties in a foreach loop

handleSubChange(event) {
    //handle subscription level row selection
    this.selectedSubscription = event.target.dataset.key;
     
    const childRows = this.template.querySelectorAll('tr[data-name="child-table"]');
    console.log(childRows);
    console.log(this.selectedSubscription);
        childRows.forEach(row => {
            console.log(row.dataset.key);
        if(row.dataset.key === this.selectedSubscription) {
            row.style.display = "table-row";
        }
        else {
            row.style.display = "none";
        }
    }); 

    this.template.querySelector("c-subscription-products[data-active-key='" + this.selectedSubscription + "']").handleProductSelect(this.productsTable, this.selectedSubscription);

}

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.