datatables with webpack $.fn.dataTable undefined

datatables with webpack $.fn.dataTable undefined

spigandromedaspigandromeda Posts: 4Questions: 2Answers: 0

Hi,

I am trying to migrate my project to Symfony 4. To do so I want to use webpack/encore instead of static assets. I am unsing the datatables plugin and now I am trying to make it work. After requiring the module I cannot use $.fn.dataTables.

TypeError: $.fn.dataTable is undefined

The module is imported via require('datatables.net');
I also tried to use AMD: require('datatables.net')(window, $); this resulted in TypeError: this is undefined (jquery.dataTables.js:132).

Writing the require output to $.fn.dataTable also doesn't work.
dataTable = require('datatables.net'); $.fn.dataTable = dataTable;

Of course it's no longer undefined but it also doensn't work because the module exports DataTable and not $.fn.dataTable. So the resulting error when unsing it is TypeError: $(...).DataTable is not a function

I would appreciate your help to finally make this work like I would use static assets.

Answers

  • colincolin Posts: 2,381Questions: 0Answers: 427

    Hi @spigandromeda ,

    Take a look at this thread here - hopefully that will get you going.

    Cheers,

    Colin

  • spigandromedaspigandromeda Posts: 4Questions: 2Answers: 0

    Nope. I am afraight that didn't work.
    I am not sure how datatables and webpack internally work. But I guess the package attaches itself to the jquery space (why we can use $.fn.dataTable).
    So when calling the package via require ... does webpack handle $ to the module so it can attach itself to jquery or isn't that even designated?

  • spigandromedaspigandromeda Posts: 4Questions: 2Answers: 0

    Ok I found a solution. Its not pretty but it works:

    var DataTable = require('datatables.net');
    require( 'datatables.net-buttons' );
    require( 'datatables.net-responsive' );
    
    $.fn.dataTable = DataTable;
    $.fn.dataTableSettings = DataTable.settings;
    $.fn.dataTableExt = DataTable.ext;
    DataTable.$ = $;
    
    $.fn.DataTable = function ( opts ) {
        return $(this).dataTable( opts ).api();
    };
    

    Simple: just adding all functions to $.fn manually. I just took the code lines from the actual code in the nodeJS module.

    If somebody knows the proper solution to add such prototypes from inside the module: please let us know :smile:

  • allanallan Posts: 48,075Questions: 1Answers: 6,907 Site admin

    That shouldn't be required... If you are AMD loading, which it appears you are, then DataTables does this:

            define( ['jquery'], function ( $ ) {
                return factory( $, window, document );
            } );
    

    So as long as jquery is resolvable (it is case sensitive) then it should work.

    Can you confirm both if you are use AMD and if jquery is resolvable in your loader?

    Allan

  • dmezieredmeziere Posts: 5Questions: 0Answers: 0

    Thank you a thousand times spigandromeda ! You have provided the only solution that works for me ! I think I tried any other way I could find on the web for several days now.

  • dmezieredmeziere Posts: 5Questions: 0Answers: 0

    Well, partially. If I try to use datatables.net-bt, after it, again, "DataTable is undefined".

  • allanallan Posts: 48,075Questions: 1Answers: 6,907 Site admin

    I don't think there is a datatables.net-bt package. Perhaps you means dataTables.net-bs?

    Allan

  • dmezieredmeziere Posts: 5Questions: 0Answers: 0

    Well, I don't really know. I am a PHP dev, and I hate JS and it's weird behaviour. I am really forced to use it and loose patience very rapidly with it. But I love DataTables, and use it for years now. That thing, Webpack Encore, is a curse for us PHP developpers.

    What I understood, is that Webpack Encore uses yarn in place of npm, so maybe the packages names are different. I also found that on a blank Symfony 4 project, DataTables works fine. But on my project, the only way I found to make it work is by redefining the $.fn.dataTable thing. and if i try to use plugins with it, they craches.

    It is so frustrating to copy-paste obscur things found on the web and not understand why it would work or why it wouldn't. Having globals, not-so-globals, and maybe-globals variables ... For me JS is not a programming anguage. It isn't even build by the ones that specifies it. Each browsers make their own JS engine, respecting or not the specs ... It couldn't and shouldn't work.

  • dmezieredmeziere Posts: 5Questions: 0Answers: 0
    edited October 16

    It seems that I made it work. But I don't really know how, as I modified so much things in a week.

    I've replaced all "require()" calls with "import" ones, and defined window.jQuery, and now it seems to work.

    import $ from 'jquery';
    window.jQuery = $;
    import DataTable from 'datatables.net';
    import 'datatables.net-bs';
    

    No more need to redeclare $.fn.dataTable. Like we say in french "C'est tombé en marche". It works, but I can't explain why.

    Edit: It looks like "window.jQuery = $;" isn't event required, thanks to Encore's autoProvidejQuery()

  • dmezieredmeziere Posts: 5Questions: 0Answers: 0

    Ignore my previous message, it's all false :/ Can you even delete it, Allan ?

Sign In or Register to comment.