Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataTables of Bootstrap4 with WebPack is not integrated in Rails 6?

Currently, I am working on HR-System where I am handling the Attendance module. I want to show the table using the Bootstrap4 DataTables. I have tried all of the links of StackOverflow but none of the solutions work for me.

I am Facing the following error in this code:

application.js:1 Uncaught Error: Cannot find module 'jquery' at webpackMissingModule (application.js:1)

attendances:131 Uncaught ReferenceError: $ is not defined at attendances:131

$(…)DataTable is not a function

packages.json:

    {
    "name": "inhouse_activities",
    "private": true,
    "dependencies": {
        "@fortawesome/fontawesome-free": "^5.15.0",
        "@nathanvda/cocoon": "^1.2.14",
        "@rails/actioncable": "^6.0.0",
        "@rails/activestorage": "^6.0.0",
        "@rails/ujs": "^6.0.0",
        "@rails/webpacker": "4.3.0",
        "bootstrap": "^4.5.2",
        "coffee-loader": "^1.0.0",
        "coffeescript": "1.12.7",
        "datatables.net": "^1.10.22",
        "datatables.net-bs4": "^1.10.22",
        "imports-loader": "^1.2.0",
        "jquery": "^3.5.1",
        "popper.js": "^1.16.1",
        "toastr": "^2.1.4",
        "turbolinks": "^5.2.0"
    },
    "version": "0.1.0",
    "devDependencies": {
        "webpack-dev-server": "^3.11.0"
    }
}

config/webpack/loaders/datatable.js:

module.exports = {
    test: /datatables\.net.*/,
    use: [{
      loader: 'imports-loader?define=>false'
    }]
  }

config/webpack/environment.js:

const { environment } = require("@rails/webpacker");
const coffee = require("./loaders/coffee");

const webpack = require("webpack");
const datatable =  require('./loaders/datatable')

environment.plugins.prepend(
    "Provide",
    new webpack.ProvidePlugin({
        $: "jquery/src/jquery",
        jQuery: "jquery/src/jquery",
        Popper: ["popper.js", "default"]
    })
);

environment.loaders.append('expose', {
    test: require.resolve('jquery'),
    use: [{
      loader: 'expose-loader',
      options: '$'
    }]
  })

environment.loaders.prepend("coffee", coffee);
environment.loaders.prepend('coffee', datatable);

module.exports = environment;

views/attendances/_table.html.erb:

<div class="container">
    <table id="example" class="table table-striped table-bordered" style="width: 1000px;">
        <thead>
            <th>Name</th>
            <th>Position</th>
            <th>Office</th>
            <th>Age</th>
            <th>Start date</th>
            <th>Salary</th>
        </thead>
        <tbody>
            <tr>
                <td>Tiger Nixon</td>
                <td>System Architect</td>
                <td>Edinburgh</td>
                <td>61</td>
                <td>2011/04/25</td>
                <td>$320,800</td>
            </tr>
            <tr>
                <td>Garrett Winters</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
            <tr>
                <td> Paul Byrd</td>
                <td> Chief Financial Officer (CFO)</td>
                <td> New York</td>
                <td>64</td>
                <td> 2010/06/09</td>
                <td> $725,000</td>
            </tr>
            <tr>
                <td> Gloria Little</td>
                <td>Systems Administrator</td>
                <td>New York</td>
                <td>59</td>
                <td>2009/04/10</td>
                <td>$237,500</td>
            </tr>
            <tr>
                <td>Bradley Greer</td>
                <td>Software Engineer</td>
                <td>London</td>
                <td>41</td>
                <td>2012/10/13</td>
                <td>$132,000</td>
            </tr>
            <tr>
                <td>Dai Rios</td>
                <td>Personnel Lead</td>
                <td>Edinburgh</td>
                <td>35</td>
                <td>2012/09/26</td>
                <td>$217,500</td>
            </tr>
            <tr>
                <td>Jenette Caldwell</td>
                <td>Development Lead</td>
                <td>New York</td>
                <td>30</td>
                <td>2011/09/03</td>
                <td>$345,000</td>
            </tr>
      <tr>
                <td>Hassam Saeed</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
      <tr>
                <td>Hunaid Nawaz</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
      <tr>
                <td>Armaghan Fazal</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
      <tr>
                <td>Fahad Anwar</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
        </tbody>
    </table>
</div>


<script type="text/javascript">

  $(document).ready(function() {
      console.log($('#example'))
    $('#example').DataTable();
  });
</script>

app/assets/stylesheets/application.scss:

$fa-font-path: "@fortawesome/fontawesome-free/webfonts";
@import "@fortawesome/fontawesome-free/scss/fontawesome";
@import "@fortawesome/fontawesome-free/scss/solid";
@import "@fortawesome/fontawesome-free/scss/regular";
@import "@fortawesome/fontawesome-free/scss/brands";
@import "@fortawesome/fontawesome-free/scss/v4-shims";
@import "bootstrap/dist/css/bootstrap";

@import "toastr/toastr";
@import "custom";
@import "session";

app/javascript/packs/application.js:

require("jquery");
require("@rails/ujs").start();
require("turbolinks").start();
require("@rails/activestorage").start();
require("channels");


import $ from "jquery";
// window.$ = $
// window.$ = $
// require('datatables.net-bs4')
// require('datatables.net')( window, jQuery );
require("datatables.net-bs4")(window, $);

require("@nathanvda/cocoon");

import "controllers";
import "@fortawesome/fontawesome-free/js/all";

application.html.erb:

<!DOCTYPE html>
<html>
  <head>
    <title>HR-System</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%# <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/dataTables.bootstrap.min.css"/>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/fixedheader/3.1.7/css/fixedHeader.bootstrap.min.css"/>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/responsive/2.2.6/css/responsive.bootstrap.min.css"/> %>
  </head>

  <body>
    <%= yield %>
    
    <script><%= yield :javascript %></script>
    <%# <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.22/datatables.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/responsive/2.2.6/js/dataTables.responsive.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/responsive/2.2.6/js/responsive.bootstrap.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/fixedheader/3.1.7/js/dataTables.fixedHeader.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/1.10.22/js/dataTables.bootstrap.min.js"></script>      %>
    </body>
</html>

Whenever I uncomment these files in Application.html.erb all of the code working fine without any errors.

Hoping for the best reply.

like image 423
Hassam Saeed Avatar asked Oct 10 '20 15:10

Hassam Saeed


2 Answers

I'm not sure what is the root cause but I found some workaround if you want to use DataTable from Webpack instead of CDN.

If you want to use the DataTable function inside of the js file under the folder javascript/pack/:

// In application.js

var $  = require( 'jquery' );
var dt = require('datatables.net-bs4');

$(document).ready(() => {
  console.log($.fn.DataTable)
  //
})

/* Got
ƒ (opts) {
    return $(this).dataTable(opts).api();
  }
*/ 
 

From last line of bottom of document

Please note that the above is shown for CommonJS modules. If you are using an AMD loader, you do not need to execute the required library (i.e. remove the trailing ()).

Or if you want to call $('#example').DataTable(); in file views/attendances/_table.html.erb, you should edit the application.js file a little bit:

var $  = require( 'jquery' );
var dt = require('datatables.net-bs4');
window.$ = $

I have found this discussion, hope this help!

like image 58
Ninh Le Avatar answered Nov 06 '22 17:11

Ninh Le


I'm not sure if it's a typo, but your webpack directory is spelled incorrectly: webapck vs webpack.

I'm exposing jquery a little differently than you. This is with expose-loader 1.0 syntax: config/webpack/environment.js

environment.plugins.prepend('Provide', new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery',
  jquery: 'jquery', 
})
)

environment.loaders.append('expose', {
  test: require.resolve('jquery'),
  use: [
    { loader: 'expose-loader', options: { exposes: ['$', 'jQuery'] } }, 
  ]
})

Speaking of which, I have expose-loader explicitly included in package.json. I don't think any of the Rails webpacker packages include it by default.

    "@rails/webpacker": "5.1.1",
    "bootstrap": "^4.3.1",
    "datatables.net-bs4": "^1.10.19",
    "expose-loader": "^1.0.0",
    "jquery": "~3.4.1",
    "popper.js": "^1.15.0",

I do not have the config/webpack/loaders/datatable.js file at all.

In app/javascript/packs/application.js I do not import/require jquery at all, that is loaded globally with the above config.

import 'bootstrap'
require('datatables.net-bs4')

app/views/whatever.html.erb

...
<script>
    $('#assignments_table').DataTable({
        paging: false, 
        language: {
            emptyTable: "No assignments entered",
        },
    });
</script>
like image 34
Jim Avatar answered Nov 06 '22 15:11

Jim