mwouts / itables

Pandas DataFrames as Interactive DataTables
https://mwouts.github.io/itables/
MIT License
730 stars 54 forks source link

ITables 2.0 - update datatables.net to 1.13.1 and provide support for buttons #121

Closed mwouts closed 3 months ago

mwouts commented 1 year ago

@AllanJard has released a new version of datatables.net==1.13.1 that provides support for the datables plugins in the ESM format.

I will report here on the progress on transitioning itables to that new release of datatables.net.

mwouts commented 1 year ago

My first experiment has been to modify the connected template like this:

<style></style>
<div class="itables">
<table id="table_id"><thead><tr><th>A</th></tr></thead></table>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.1/css/jquery.dataTables.min.css">
</div>
<script type="importmap">
{
        "imports": {
            "datatables.net": "https://cdn.datatables.net/1.13.1/js/jquery.dataTables.mjs",
            "jquery": "https://esm.sh/jquery@3.5.0"
        }
}
</script>
<script type="module">
    // Import jquery and DataTable
    import DataTable from 'datatables.net';

    // Define the table data
    const data = [];

    // Define the dt_args
    let dt_args = {};
    dt_args["data"] = data;

    // [pre-dt-code]
    new DataTable('#table_id', dt_args);
</script>

The template (saved to an html file) does work, but only in very recent versions of the browsers: https://caniuse.com/import-maps

Concretely that means that the latest Firefox on the latest Ubuntu is currently not supported. I am OK with that but that means that I will have to maintain the branch 1.x and 2.x for some time. Also we will have to check out what is the compatibility of import maps with VS Code, PyCharm and Colab.

Later on in the day I will see how I can port the non-connected template, in which one we import from a base64 encoded version of the library.

mwouts commented 1 year ago

I have been able to port the non-connected template as well, in this commit.

I have seen the new version work in

Unfortunately it seems that no other environment is adapted to the import maps (VS Code, PyCharm and Jupyter Notebook do not seem to support that, and I have no idea on how to debug the first two), so I might release the new version as a dev version for a little while.

AllanJard commented 1 year ago

We have an import jQuery from 'jquery'; in the DataTables ES module, which is what causes the difficulty here. Without an import map, the browser has no way to resolve that if the file is just imported directly. And we can't do a conditional import. One option would have been to have DataTables being able to be loaded on its own and then have a function like DataTables.use(jQuery); to make it use a specific version of jQuery (actually - we do have that, but it still has the jQuery import).

The other option is to use a bundler such as Vite to create a single JS file that can then be loaded in.

mwouts commented 1 year ago

Hi @AllanJard , sorry if I sounded negative above, I think import maps are a great approach and I don't see any other way anyway to provide the buttons.

One option would have been to have DataTables being able to be loaded on its own and then have a function like DataTables.use(jQuery); to make it use a specific version of jQuery (actually - we do have that, but it still has the jQuery import).

Yes I saw that, but again this is probably not going to support the extensions?

The other option is to use a bundler such as Vite to create a single JS file that can then be loaded in.

:smile: here we're going way further than what I can actually do in JS/HTML but maybe my brother will be able to follow :laughing:

bryanwhiting commented 1 year ago

would love buttons, if this +1 is any motivation :)

mwouts commented 5 months ago

Hey @AllanJard, some time has passed since we last chatted about this, and I see that import maps now work well in my browser.

I would be curious to see if I can extend the import maps example above and add support for the datatables extensions like e.g. the buttons.

Do you provide a module version for the button extension on https://cdn.datatables.net, like you do for e.g. https://cdn.datatables.net/1.13.8/js/jquery.dataTables.mjs ?

Looking forward to testing this!

AllanJard commented 5 months ago

Yes, all of the DataTables extensions have .mjs files available for them. E.g https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.mjs

Just substitute .mjs for .js.

mwouts commented 5 months ago

Oh excellent! Thank you @AllanJard

mwouts commented 5 months ago

For the records I have seen a partial success with the below - copy, csv and excel buttons work in a simple (connected) example.

Now the things that I am not so sure of:

I am also interested in the bundling approach if that happens to be easier. I have seen rollup work on a simple example, and I take a note of the vite example in this comment

<div class="itables">
<table id="table_id"><thead><tr><th>A</th></tr></thead></table>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.8/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.dataTables.min.css">
</div>
<script type="importmap">
{"imports": 
    {
    "jquery": "https://esm.sh/jquery@3.7.0",
    "jszip": "https://esm.sh/jszip@3.10.1",
    "pdfmake": "https://esm.sh/pdfmake@0.2.9",
    "datatables.net": "https://cdn.datatables.net/1.13.8/js/jquery.dataTables.mjs",
    "datatables.net-buttons": "https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.mjs",
    "datatables.net-buttons-html5": "https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.mjs"
    }
}
</script>
<script type="module">
    import DataTable from 'datatables.net';
    import 'datatables.net-buttons';
    import 'datatables.net-buttons-html5';

    import jszip from 'jszip';
    DataTable.Buttons.jszip( jszip );

    import pdfmake from 'pdfmake';
    // pdfMake.vfs = vts_fonts; // TODO - not sure where to get vts_fonts from?
    DataTable.Buttons.pdfMake(pdfMake);

    // Define the table data
    const data = [[1],[2]];

    // Define the dt_args
    let dt_args = {};
    dt_args["data"] = data;
    dt_args["dom"] =  'Bfrtip';
    dt_args["buttons"] = ['copyHtml5', 'excelHtml5', 'csvHtml5', 'pdfHtml5'];

    // [pre-dt-code]
    new DataTable('#table_id', dt_args);
</script>
AllanJard commented 5 months ago

How should I choose the names for import maps - the names seem to matter because some of the imports rely on specific names in the map

They need to match the npm package name. There is an import map for all DataTables libraries here. That is an old version now - I need to update my build process to include automatic generation of the map. But it might be a useful starting point for you.

I have not find out yet how to get vts_fonts through an import map (and because of that the PDF export does not work)

You'd need to flag that up with the pdfmake folks.

I am also interested in the bundling approach if that happens to be easier.

Yes, it should be a lot more reliable. I've seen very very few people use importmaps. Bundles or a direct browser import are massively more common.

mwouts commented 5 months ago

Yes, it should be a lot more reliable. I've seen very very few people use importmaps. Bundles or a direct browser import are massively more common.

I can tell that! @fwouts do you think you could help me transform this attempt of bundling DataTables and a few of its extensions from a node project into something that actually works (if that makes any sense?):

https://github.com/mwouts/dynamic_import_of_bundled_datatables_extensions

AllanJard commented 5 months ago

There are a bunch of limitations with importmaps in the browser which I've written about here. I think that is what is really hindering their adoption on the client-side. There are some PHP frameworks which are embracing them and it seems to work well, but in the browser, until the specs are sorted, I'm not sure I can fully recommend them.

mwouts commented 5 months ago

Yes agreed! Looking forward to reading your post!

Now I will be giving a try to the alternative, i.e. bundling. The project linked to in my previous comment is about bundling, but as this is completely new to me I will probably need some support there (first problem is that I have not yet found out how to bundle the dependencies...)

AllanJard commented 5 months ago

Rollup, Vite, ESBuild, there are a lot of options, but I'm afraid general bundling is outside the scope of DataTables.

mwouts commented 3 months ago

ITables 2.0 is available! We have packaged DataTables and its extensions using esbuild as recommended by @AllanJard (thank you Allan!) . A few examples are provided in the updated documentation: https://mwouts.github.io/itables/extensions.html

AllanJard commented 3 months ago

Congratulations on the release!