2

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. Commented May 18, 2021 at 19:02
  • ah, +1 on the colspan, drew a blank on that and it helped with the layout part of this a lot! Commented May 18, 2021 at 20:11
  • Don't forget rowspan - that will help with the first bit with the radio button Commented May 18, 2021 at 20:13

1 Answer 1

2

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);

}
3
  • How did you solve this problem. I have a similar use case
    – SFUser
    Commented Jun 15 at 19:03
  • How did you solve this problem. I have a similar use case
    – SFUser
    Commented Jun 15 at 19:03
  • Thanks for response, is it possible to provide a git repo or a blog that helps with the overview
    – SFUser
    Commented Jun 18 at 13:03

You must log in to answer this question.

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