Rails 7 with esbuild - how to install datatables?

Rails 7 with esbuild - how to install datatables?

VorkoVorko Posts: 12Questions: 2Answers: 0
edited January 2022 in DataTables

I am trying to add datatables-bs5 to my Ruby on Rails 7 project. I have installed it using npm.

In application.js

import * as bootstrap from "bootstrap"
import DataTable from "datatables.net-bs5"

In index.html.erb (from https://datatables.net/examples/non_jquery/init.html)

document.addEventListener('DOMContentLoaded', function () {
let table = new DataTable('#example');
});

But every time I get the following error message

Uncaught ReferenceError: DataTable is not defined
at HTMLDocument.<anonymous> ((index):50:17)

Knowing that the javascript seems properly loaded and that I don't get any error message in the rails console.

Anyone has an idea what could be wrong?

This question has an accepted answers - jump to answer

Answers

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    This thread should help - it's for Rails 6 but the same principles would apply,

    Colin

  • VorkoVorko Posts: 12Questions: 2Answers: 0

    Sadly no, these works with webpacker which is not used within Rails anymore. The new standard is esbuild.

  • allanallan Posts: 61,439Questions: 1Answers: 10,053 Site admin

    I haven't used Rails 7 I'm afraid. Are you able to set up a mini repo that I can run a build command and see this error please? I'll hopefully be able to resolve this issue with that.

    Thanks,
    Allan

  • VorkoVorko Posts: 12Questions: 2Answers: 0
  • VorkoVorko Posts: 12Questions: 2Answers: 0

    For information, I kept playing with it. The key element is

    import DataTable from "datatables.net-bs5"
    window.DataTable = DataTable

    It makes the DataTable function available in the index.html.erb (this is the value of DataTable)

    ƒ (root, $) {
                if (!root) {
                  root = window;
                }
                if (!$ || !$.fn.dataTable) {
                  $ = require_jquery_dataTables()(root, $).$;
                }
          …
    

    BUT, it just doesnt do anything there. Does it mean I need to make other functions visible to the frontend? $? jQuery?

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736
    edited January 2022

    If you are asking if jQuery is a requirement for Datatables, the answer is yes you will need to include jquery.js before any of the datatables .js libraries. Sorry I'm not familiar with Rails 7 either so don't know specifically what you need to do.

    Kevin

  • VorkoVorko Posts: 12Questions: 2Answers: 0

    Actually, jQuery is already loaded and accessible to the view ($ function works).

    In Rails 7, you need to say which Javascript functions should be accessible to the view. If you want to use jQuery, you need to declare jQuery, $ accessible.
    Then if you want to use jQueryUI, you need to load it and declare which functions (e.g. dialog?) should be available

    For DataTables, making just DataTable available does nothing. So I wonder if I need to expose other functions.

  • VorkoVorko Posts: 12Questions: 2Answers: 0

    Latest version https://github.com/Vorkosigan76/rails7-datatables2 here with no error message... but not working

  • allanallan Posts: 61,439Questions: 1Answers: 10,053 Site admin

    Many thanks for the repo. There are a couple of types which are causing most of the issues.

    import DataTable from "datatables.net-bs5"
    
    window.DataTable = DataTable();
    

    Is what you want to use (note that your window assignment line uses a lowercase t for both of the variables referenced there - which caused the variable used in your index file to be undefined!).

    Note also that the imported value is a function, which you can optionally pass a jQuery and window instance into (should you be loading jQuery elsewhere).

    Finally, in your index file, the HTML for the table is invalid. You had head and body elements inside the table - they should be thead and tbody:

    <table id="example">
      <thead>
        <tr>
          <th>Lastname</th>
          <th>Firstname</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Messiani</td>
          <td>Cristiano</td>
        </tr>
        <tr>
          <td>Rolando</td>
          <td>Esteban</td>
        </tr>
        <tr>
          <td>Traoré</td>
          <td>Adam</td>
        </tr>
      </tbody>
    </table>
    

    With those changes, it loads the file and DataTables successfully.

    Allan

  • VorkoVorko Posts: 12Questions: 2Answers: 0

    Hi Allan, thank you so much, it's working.

    I feel very stupid about the head/thead... I was too focused on the rest that I didn't realize it.

    I'm surprised about the parenthesis after DataTable()... $ or jQuery are also functions but they dont use them.

  • VorkoVorko Posts: 12Questions: 2Answers: 0

    For info I have updated the repository.

  • allanallan Posts: 61,439Questions: 1Answers: 10,053 Site admin
    Answer ✓

    I'm surprised about the parenthesis after DataTable()... $ or jQuery are also functions but they dont use them.

    Yes, we could drop them, and perhaps in future we can make them optional, but with them it presents extra options for controlling what version of jQuery you are using, and support for virtual documents (headless browsers for example). A little more information about that is available in the npm docs. I'll get them updated for ES6 module support.

    Allan

  • aparreno12aparreno12 Posts: 4Questions: 0Answers: 0

    I'm trying to add buttons to the table in the repository but I don't get it. Buttons are not showed.
    I have imported in datatables-bs5.js:

    import DataTable from "datatables.net-bs5"
    import "datatables.net-buttons-bs5"
    window.DataTable = DataTable(); 
    

    and I have added to index.html.erb:

    document.addEventListener('DOMContentLoaded', function () {
        let table = new DataTable('#example',{
                dom: 'Bflrtip',
                buttons: ['copy']
        })
      });
    

    Any idea what's happening? Maybe I'm not importing datatables.net-buttons-bs5 in the right way?

    Alfredo

  • allanallan Posts: 61,439Questions: 1Answers: 10,053 Site admin

    Try:

    import DataTable from "datatables.net-bs5"
    import Buttons from "datatables.net-buttons-bs5"
    
    window.DataTable = DataTable(); 
    Buttons();
    

    Allan

Sign In or Register to comment.