fiduswriter / simple-datatables

DataTables but in TypeScript transpiled to Vanilla JS
Other
1.31k stars 231 forks source link

Preserve HTML cell attributes in rendered table #346

Closed SandroHc closed 6 months ago

SandroHc commented 6 months ago

Preserves attributes from the HTML table headers (<th>) or cells (<td>) in the rendered datatable.

See the following example for a practical use case. Note the attributes in the <th> and <td> elements.

<table id="example-table">
    <thead>
        <tr>
            <th class="name">Name</th> <!-- header with custom class -->
            <th>City</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td style="background-color: yellow;">Unity Pugh</td> <!-- cell with custom colour -->
            <td>Curicó</td>
        </tr>
        <tr>
            <td>Theodore Duran</td>
            <td>Dhanbad</td>
        </tr>
    </tbody>
</table>

<script>
    const dt = new DataTable("example-table");
</script>
johanneswilm commented 6 months ago

@SandroHc This is the largest of your changes and so I want to make sure I fully understand what is going on before I merge it. I have been telling people for some time now that they should just create new data columns if they have more data points instead of adding attributes to individual cells. Now with this they can go back to what they used to do.

Question - it looks like adding attributed to a cell is only supported if you start out with a dom structure, not if you start out with your data as objects and arrays. So for exam ple in readDataCell there is nothing about attributes. Is that on purpose? Would it not be more consistent if there also was a way to add attributes to cells when not reading dom nodes - either at initiation or when adding additional data later on?

I'll continue studying your PR...

SandroHc commented 6 months ago

I may have a niche use case. I want to transform lots of "dumb" tables (that may have custom styling either on a row or a cell) and convert them into rich datatables with the bare minimum JavaScript necessary. Something like this:

<table>
    <thead>
        <tr>
            <th style="color: red;">Header 1</th>
            <th>Header 2</th>
        </tr>
    </thead>
    <tbody>
        <tr class="fancy-row">
            <td style="color: red;">Value 1</td>
            <td>Value 1</td>
        </tr>
    </tbody>
</table>

<script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest"></script>
<script>
    document.querySelectorAll('table').forEach(table => new simpleDatatables.DataTable(table));
</script>

From what I read, I thought read_data.readDataCell() already did this if the cell type was html. Now I see that the cell contents are simply coerced into a string. It should be possible to adapt read_data.readDataCell() to parse the HTML if that is something you'd want.

I can put these changes behind a "preserveDomAttributes" option. Something opt-in for exotic use-cases like mine.

johanneswilm commented 6 months ago

From what I read, I thought read_data.readDataCell() already did this if the cell type was html. Now I see that the cell contents are simply coerced into a string. It should be possible to adapt read_data.readDataCell() to parse the HTML if that is something you'd want.

I can put these changes behind a "preserveDomAttributes" option. Something opt-in for exotic use-cases like mine.

No that's fine. If the attributes are there already and one reads from the dom to initialize the table, then I think it's reasonable if we can keep the attributes of the cell. The only reason I didn't do that so far is that it takes time to program - time that you now have invested already. It seems like there are quite a few users who use it like that.

I was just wondering if one initiates from just JSON. I have added a demo 25 for that and just did need to add one minor detail to make it work. I have not tested whether it is also possible to add cells with attributes after initialization.

Thanks for all this work @SandroHc ! I guess we should make a release. Let me know if you want to include other things before I create a release.