notebook: Loading of jQuery plugins doesn't work

I’m not 100% sure this is a jupyter problem, but I’m not sure where else the problem could lie at this point.

Basically, what I’m trying to do is similar to what is demonstrated in http://blog.dornea.nu/2014/08/28/using-jquery-datatables-with-ipython/ - use the jQuery dataTables plugin in the output area of a jupyter notebook. But it seems something is preventing this. If I execute the snippet below in a notebook, it just gives me the error “Javascript error adding output! TypeError: $(…).dataTable is not a function”, implying that the plugin didn’t get loaded at all. Any clue why? And is this something jupyter needs to fix, or my fault somehow?

htmlstr="""
<html>
 <head>
  <meta charset="utf-8"/>
  <meta content="text/html;charset=UTF-8" http-equiv="Content-type"/>
  <style>
body {font-family: sans-serif;}
table.dataTable {width: auto !important; margin: 0 !important;}
.dataTables_filter, .dataTables_paginate {float: left !important; margin-left:1em}
  </style>
  <link href="https://cdn.datatables.net/1.10.9/css/jquery.dataTables.min.css" rel="stylesheet" type="text/css"/>
  <script src="https://code.jquery.com/jquery-1.11.3.min.js">
  </script>
  <script src="https://cdn.datatables.net/1.10.9/js/jquery.dataTables.min.js">
  </script>
 </head>
 <body>
  <script>
$(document).ready(function() {
    $('#table4611777680').dataTable({
     "iDisplayLength": 50,
     "aLengthMenu": [[10, 25, 50, 100, 500, 1000, -1], [10, 25, 50, 100, 500, 1000, 'All']],
     "pagingType": "full_numbers"
    });
} );  </script>
  <table class="display compact" id="table4611777680">
   <thead>
    <tr>
     <th>bamboozle</th>
     <th>blar</th>
     <th>arg</th>
    </tr>
   </thead>
   <tr>
    <td>-0.296500878335</td>
    <td>0.558590155217</td>
    <td>3.41077247963</td>
   </tr>
   <tr>
    <td>-0.0816887173044</td>
    <td>-0.910788317626</td>
    <td>-0.150751552173</td>
   </tr>
   <tr>
    <td>-0.475116473413</td>
    <td>0.609925432964</td>
    <td>0.0183048076455</td>
   </tr>
   <tr>
    <td>-0.602423106792</td>
    <td>-0.874504516338</td>
    <td>1.4478604823</td>
   </tr>
  </table>
 </body>
</html>
"""
display.display(display.HTML(htmlstr))

About this issue

  • Original URL
  • State: open
  • Created 9 years ago
  • Comments: 16 (11 by maintainers)

Commits related to this issue

Most upvoted comments

I tried for a long time to get this to be clean, but didn’t come up with anything useful.

If the module were requirable, you should be able to do:

require(['dataTable-url'], function ($) {
    $("#mytable").dataTable()
}

However, since that doesn’t work, you have to load the extension with a script tag, and you get a race for whether the plugin has been loaded. The only way I’ve managed to deal with that is by checking if .dataTable is defined, and rescheduling the call if not (essentially polling for the plugin to be loaded).

# DataTable class modified from 
# http://blog.dornea.nu/2014/08/28/using-jquery-datatables-with-ipython/

import uuid
from IPython.display import HTML

def DataTable(df):
    """Display a pandas.DataFrame as jQuery DataTables"""
    # Generate random container name
    id_container = uuid.uuid1()
    output = """
<div id="datatable-container-{id_container}">
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/u/dt/dt-1.10.12/datatables.min.css"/>
  <script type="text/javascript" src="https://cdn.datatables.net/u/dt/dt-1.10.12/datatables.min.js"></script>
  <script type="text/javascript">
    (function () {{
      var dt = 100;
      function tablify() {{
        if ( $().dataTable === undefined ) {{
          console.log("no dataTable");
          dt = dt * 1.5; // slow-down checks for datatable as time goes on;
          setTimeout(tablify, dt);
          return;
        }}
      $('#datatable-container-{id_container} table.datatable').dataTable();
      }}
      $(document).ready(tablify)
      // tablify();
    }})();
  </script>
  <!-- Insert table below -->
  {table}
</div>
    """.format(
        id_container=id_container,
        table=df.to_html(index=False, classes="datatable dataframe"))
    return HTML(output)

Bizarrely, that only works in the notebook, and the plugin is never loaded on nbviewer, which makes absolutely zero sense to me, because I can prove the javascript is loaded, it just doesn’t register the plugin with jQuery for some reason that I don’t understand.