RiseNet
RiseNet

Reputation: 13

Init dataTable Jquery in Svelte

I would like init a Jquery dataTable in svelte. My first solution was :

I create in my html page a script function with Jquery dataTable

<script>
function initTable() {
    if( $('#datatable').length ) {
        $('#datatable').dataTable({
            sDom: "<'row'<'col-sm-6'l><'col-sm-6'f>r>t<'row'<'col-sm-6'i><'col-sm-6'p>>",
            "order": [[ 1, "desc" ],[0,"asc"]],
        });
    }
}</script>

And in my component:

onMount(initTable)

It work. However now, i would like add data in my table. So i use {#await} {:then data} {/await}

But, my table is not initiat. If I use in my consol the function initTable, my table become a datatable

Sorry for my english if you don't understand tell me, i will try to correct my post.

Upvotes: 0

Views: 1761

Answers (2)

rixo
rixo

Reputation: 25001

Once you've run $('#datatable').dataTable(...), the DataTable instance is created. At this point it will take over the DOM element, and won't reread data from the DOM if it later changes (which is probably what you're doing with your {#await ...}).

So you've mainly got 2 approaches here.

Either you init your DataTable instance ($(el).dataTable(...)) after the DOM has been updated with the data (by the #await). In this case, your table will remain unstyled while the data is loaded...

Something like this:

    const dataPromise = load()
    
    onMount(() => {
        // NOTE waiting for the tick ensures the DOM will have been
        // updated by Svelte first
        dataPromise.then(tick).then(() => {
            table = jQuery(el).DataTable()
        })
    })

Or you init you DataTable immediately, and use DataTable's JS API to load your data once they are available. I think this approach is more suited to usage in Svelte. Then you'd get something like this:

    let el // table element
    let table // table object (API)
    
    onMount(() => {
        // init the table immediately
        table = jQuery(el).DataTable()
        
        // load data & add them to the table with JS API
        load().then(rows => {
            table.rows.add(rows).draw()
        })
    })

These 2 examples can be seen live in this REPL.

Upvotes: 1

Andreas Dolk
Andreas Dolk

Reputation: 114787

From my experience with other UI frameworks and where I have to initialized components on the screen - it sometimes helps when we add tick() before the initialization, like so:

   import {onMount, tick} from 'svelte';

   // ...

   onMount(async () => {
      await tick():

      initTable();
   }

It helped me with initializing materializecss widgets (select boxes, input fields, toasts, tooltips, etc) but I didn't understand yet, why it needed the tick and if there was an alternative. It just solved my problems :)

Upvotes: 1

Related Questions