Skip to content

robertStrunk/Dynamic-Table-Row-Limitation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 

Repository files navigation

This document highlights a major limitation faced when creating dynamic table rows in LWC.

By dynamic table rows, I am referring to a scenario where you are iterating over a collection with the intent of creating a <tr> for every item in the collection.

Before we talk dynamic table rows, let's first establish a baseline understanding of a critical best practice when working with iterations in LWC.

It is considered a best practice to use child components when iterating collections in LWC markup. For example:

<!-- Best Practice -->
<template for:each={collection} for:item="element">
    <c-child-component
        key={element.Id}
        item={element}>
    </c-child-component>
</template>

is the correct approach compared to:

<!-- ANTI PATTERN -->
<template for:each={collection} for:item="element">
    <div key={element.Id}>
        <p>{element.title}</p>
        <p>{element.body}</p>
    </div>
</template>

A problem arises, however, when you are dealing with html tables. For example:

<table>
    <thead>
        <th>Column 1</th>
        <th>Column 2</th>
    </thead>
    <tbody>
        <template for:each={collection} for:item="element">
            <c-child-component
                key={element.Id}
                item={element}>
            </c-child-component>
        </template>
    </tbody>
</table>

Even though the above is following best practices, the output is not well-formed HTML and does not get handled by the browser properly.

<!-- Resulting HTML -->
<table>
    <thead>
        <th>Column 1</th>
        <th>Column 2</th>
    </thead>
    <tbody>
        <c-child-component>
            <tr>
                <td>some_text_here</td>
                <td>some_text_here</td>
            </tr>
        </c-child-component>
        <c-child-component>
            <tr>
                <td>some_text_here</td>
                <td>some_text_here</td>
            </tr>
        </c-child-component>
    </tbody>
</table>

Notice the <c-child-component> elements are the children of the tbody element. That is not part of the html table specification and thus is not handled by the browser in the way we expect (no matter how bad we really want it to 😆).

The cause is related to how the LWC engine performs rendering and is outside the scope of this topic.

For basic use cases, this is an easy problem to solve. All you need to do is modify the HTMLElement.style.display property to be table-row as shown below:

/* childComponent.css */
:host {
    display: table-row;
}

The above css rule notifies the browser to treat the <c-child-component> elements as standard <tr> elements.

That solution, however, does not work for recursive scenarios. For more info on that, please refer to my stack exchange post.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published