Problem in using DataTable with panel DataFrame

Hi Panel community!
I’m using DataTable with panel to display and manipulate interactive tables and I found the mixte juste AMAZING!
But I have a tiny problem, as you can see in this example: https://panel.holoviz.org/gallery/external/DataTable.html
The head and the content of the columns is skewed to the right, so when the column name becomes larger, it hides the scroll icon and the whole view of the table becomes messy!


Can you please help me to solve this problem?!

1 Like

Hi @Ouma

Welcome to the community :+1:

It would be very helpful if you could provide a minimum code example that can be run and a screenshot where you clearly identify the problem.

Then it should be easier to help out.

Thanks.

1 Like

Thank you!
At first I thought that the broblem is my column name, but now I tested the code example provided in the Panel Gallery and the same problem exists even with tiny column names!
here is the code I tested:

import panel as pn
from bokeh.sampledata.autompg import autompg
css = [‘https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css’]
js = {
‘$’: ‘https://code.jquery.com/jquery-3.4.1.slim.min.js’,
‘DataTable’: ‘https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js
}
pn.extension(css_files=css, js_files=js)
script =
“”"“”"
html = autompg.to_html(classes=[‘example’, ‘panel-df’])
pn.pane.HTML(html+script, sizing_mode=‘stretch_width’).show()

and this was the output:


As you can see, the column name hides the Scroll icons

Hi @Marc any idea how to solve this problem ?

1 Like

Hi @Ouma

Unfortunately not.

I’m sure it can be solved if someone looks deep enough into it.

I wish that Panel had a DataFrame/ Table component that looked and felt better. I have several Issues my self that I would like to see solved one day. I’m sure they will be.



My personal opinion is that table is a core element of Panel and as such should be highly prioritized.
My hope is that the developers who knows the current DataFrame widget (based on SlickGrid) can do something about it.

My hope is also that someone (me? you?) can provide an alternative one instead. Maybe not with bidirectional communication. But at least one that lays out well. For inspiration on creating Panel extensions see https://awesome-panel.readthedocs.io/en/latest/guides/awesome-panel-extensions-guide/index.html. There are lot of amazing tables out there that could be used. See https://jspreadsheets.com/ or https://flatlogic.com/blog/top-19-remarkable-javascript-data-table-libraries-and-plugins/.

If you don’t need bidirectional communication you might be able to find some template for creating a nice looking html table from a pandas dataframe and display it via the HTML pane. But it may be slower as it needs to transfer more data from server to browser. Try to google pandas html table and you might find something like https://mode.com/example-gallery/python_dataframe_styling/. You could also look into using the Plotly Table.

If you find a solution please share in this Discourse post or in some other way as this is a general problem to solve. Thanks.

1 Like

Thank you @Marc for your replay, of course if I find a solution, I’ll share It with you :slight_smile:

after 3 tries, the best option is change the script by

script = """
<script>
if (document.readyState === "complete") {
  $('.example').DataTable({
    "columnDefs": [
        {"className": "dt-left", "targets": "_all"}
      ]
  });
} else {
  $(document).ready(function () {
    $('.example').DataTable({
    "columnDefs": [ {"className": "dt-left", "targets": "_all"}  ]
  });
  })
}
</script>
"""

html = autompg.to_html(classes=['example', 'panel-df'])
pn.pane.HTML(html+script, sizing_mode='stretch_width').show()

as derived from https://datatables.net/manual/styling/classes

This solution works only if you use show or servable. In the notebook it doesn’t work.

For bidirectional communication one thing you can do is create a dummy slider, and you can change the value of the slider in javascript. In the code below you can see that doing click in the table in javascript the text value of python can be changed.

from bokeh.models.widgets import Slider
slider =  Slider(start=0, end=autompg.shape[0], value=0, name='my_slider', visible=False)
text = pn.widgets.TextInput(value='Ready')
# pn.Row(slider)

script = """
<script>
if (document.readyState === "complete") {

   var table = $('.example').DataTable({
                                    "columnDefs": [
                                        {"className": "dt-left", "targets": "_all"}
                                      ]
                                  });

  
  $('.example tbody').on('click', 'tr', function () 
                {
                    var data = table.row( this ).data();
                            
                    var slider = Bokeh.documents[0].get_model_by_name('my_slider');
                    console.log('slider value before:', slider.value);
                    slider.value = Number(data[0]);
                    console.log('slider value after:', slider.value);
                    
                } ) ;
  
  
  
} else {
  $(document).ready(function () {
    $('.example').DataTable({
    "columnDefs": [ {"className": "dt-left", "targets": "_all"}  ]
  });
  })
}
</script>
"""

def dummy_call(attr, old, new):
    text.value = autompg.loc[slider.value]['name']
    return 
    
    
slider.on_change('value', dummy_call)


html = autompg.to_html(classes=['example', 'panel-df'])
table_pane = pn.pane.HTML(html+script, sizing_mode='stretch_width')

pn.Column(slider, text, table_pane).show()

The slider of bokeh (invisible) is need because when you use get_model_by_name and the panel widgets do not have the name property.

If you need to style the table you can use the theme creator

https://datatables.net/manual/styling/theme-creator

and load the resulting css with

pn.extension(css_files=css, js_files=js, raw_css = raw_css)

best regards,
Nestor.

2 Likes

THANK YOU! @nghenzi2019 that’s quite useful, I still have two tiny questions:
==> When I try to generate different DataTables and display them all as a panel object, I faced the problem of DATATABLE reinitialisation, https://datatables.net/manual/tech-notes/3:
CaptureDataTable
Is there any solution to display all my tables at once avoiding this warnings ?

==> When the number of columns exceeded a certain number, the view becomes messy, and I would like to know if we could fix the number of columns to be dsplayed in each page( 1,2,3…) based on selection.
Thank you in advance :slight_smile:

1 Like