Will DataTables 2.0 require jQuery?

Will DataTables 2.0 require jQuery?

tacman1123tacman1123 Posts: 55Questions: 15Answers: 0

Since Bootstrap 5 no longer requires jQuery, will the next version of DataTables also be able to run without it?

Javascript has evolved so much since DataTables was first written, we now have real classes, etc. While I'm sure it's a big task (especially given all the excellent datatable plugins), I'm curious if that's your goal.

Thanks.

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 55,883Questions: 1Answers: 8,835 Site admin

    Yes it will. As you say it would be a major task to build a version of DataTables without jQuery - a task that we simply don't have the engineering resources available to dedicate to such a project with everything else we are working on.

    First we need to ask what we gain by using jQuery:

    • Extremely easy and compact DOM interface
    • An element eventing system
    • Comprehensive and compatible Ajax support
    • Wide compatibility with battle hardened and tested code

    What are the costs of jQuery:

    • More to download - 27KB, although keep in mind that DataTables without jQuery would be larger itself since we'd need to re-implement so much of what jQuery gives us.
    • Possible performance penalty. Any abstraction layer will have a performance penalty, so even if we were to replace jQuery with our own libraries we'd just be moving the performance hit elsewhere.
    • Marketing cost. "It's 2021 and you are still using jQuery... wtf" is a real thing and probably costs us customers.

    If anyone can give me a good argument for way we should spend months of development time effectively reimplementing jQuery, so we can call DataTables "vanilla JS" (which is a term I disagree with since jQuery is itself nothing but Javascript itself) then I'm all ears.

    DataTables will work with Zepto if the 27KB is too much, and I've looked into using Cash (another jQuery alternative) but it is missing utilities that we'd just need to replace.

    This thread also has more thoughts on the topic.

    I'd like to have my thought process on this challenged, so please, yourself @tacman1123, or anyone else with thoughts on this, write back with why we should drop jQuery.

    My personal preference is to rewrite DataTables in Typescript to gain all the goodness of ESNext, but again, I am currently preferring to spend my development efforts in other directions (you might notice from all our repos though that all new code we produce is TS).

    Allan

  • tacman1123tacman1123 Posts: 55Questions: 15Answers: 0

    Thanks, Allan. I'm not necessarily advocating for dropping jQuery, but as I'm refactoring some code to use Bootstrap 5, I'm wondering how much effort I should spend dropping jQuery on pages that don't use DataTables. So if you had said version 2 was dropping jQuery, I'd make it a goal to get rid of jQuery elsewhere.

    I imagine I'll try to follow this model, where jQuery is included in datatables.js itself, and not everywhere in the site.

    https://demo.adminkit.io/tables-datatables-responsive.html

    Much of my frustration comes from the sprinkling of jQuery plugins I've added over the years, and still occasionally getting a "jQuery is not defined" error, not in datatables, but on other pages.

    Again, thanks for the clarification!

  • hm123hm123 Posts: 79Questions: 22Answers: 1

    Hey Allan, just wanted to clarify,

    DataTables will work with Zepto

    As in, does DT work with it now, or is it planned for later?

  • allanallan Posts: 55,883Questions: 1Answers: 8,835 Site admin
    Answer ✓

    I had actually thought that it would work just now, but apparently not. I suspect I just need to add a little extra boiler plate condition checking. I'll do that and see if we can get that into our unit testing.

    @tacman1123 Apologies for not replying to your post before, I clean missed it! We almost certainly will not drop jQuery for v2. The amount of work involved in doing so would dwarf the benefits I think. That said, v1.11 is going to introduce a non-jQuery initialisation API, so you don't need to write jQuery code yourself, but DataTables would still be using it.

    Regards,
    Allan

  • nboisteaultnboisteault Posts: 1Questions: 0Answers: 0

    Hi,
    First, thank you allan for your geat work.
    I totally understand all your arguments concerning the jQuery dependency. Maybe it would not be too much work to depend on jquery-slim? It would be a good first step. A step beyond could be to build an even slimer jQuery by removing unused modules => https://github.com/jquery/jquery#modules
    I might help if you accept PRs.

  • allanallan Posts: 55,883Questions: 1Answers: 8,835 Site admin

    We already fully support jQuery slim :).

    Allan

  • tacman1123tacman1123 Posts: 55Questions: 15Answers: 0

    I love the idea of moving jQuery to being mostly internal. One thing that would help a lot is if the examples used modern javascript instead of jQuery. First, drop support for Internet Explorer 9 or earlier.

    For example, https://datatables.net/reference/option/createdRow

    Instead of having a jquery dependency, just use javscript

    // jQuery
    $(row).addClass( 'important' );
    // javascript
    row.classList.add("text-danger");
    

    In particular, examples of handling the events would be enormously helpful.

    https://datatables.net/examples/api/multi_filter.html

    $(document).ready(function() {
        // Setup - add a text input to each footer cell
        $('#example tfoot th').each( function () {
            var title = $(this).text();
            $(this).html( '<input type="text" placeholder="Search '+title+'" />' );
        } );
     
        // DataTable
        var table = $('#example').DataTable({
            initComplete: function () {
                // Apply the search
                this.api().columns().every( function () {
                    var that = this;
     
                    $( 'input', this.footer() ).on( 'keyup change clear', function () {
                        if ( that.search() !== this.value ) {
                            that
                                .search( this.value )
                                .draw();
                        }
                    } );
                } );
            }
        });
     
    } );
    

    I hate seeing $(this), and var that = this; as I often can't figure out how to convert this to ES6. Most of the examples use function(...) as the callback, but I think in many cases a (...) => {} (arrow functions) would be better and easier.

    TL;DR: If you can drop jQuery in the documentation and examples, the library will be easier to use.

  • allanallan Posts: 55,883Questions: 1Answers: 8,835 Site admin

    Thanks! I have been thinking about how to improve the examples and the main one I'd been thinking about was to allow each one to be styled by the various frameworks, but having ES6 code as well might be a really good option.

    For interest's sake, I rewrote the example you copy / pasted above in ES6 / Vanilla style:

    window.addEventListener("DOMContentLoaded", function () {
      // Setup - add a text input to each footer cell
      document.querySelectorAll("#example tfoot th").forEach((el) => {
        let title = el.textContent;
        el.innerHTML = '<input type="text" placeholder="Search ' + title + '" />';
      });
    
      let table = new DataTable("#example", {
        initComplete: function () {
          // Apply the search
          this.api()
            .columns()
            .every(function () {
              let el = this.footer().querySelector("input");
    
              el.addEventListener("keyup", () => search(this, el));
              el.addEventListener("change", () => search(this, el));
              el.addEventListener("clear", () => search(this, el));
            });
        },
      });
    });
    
    function search(dt, el) {
      if (dt.search() !== el.value) {
        dt.search(el.value).draw();
      }
    }
    
    
    

    http://live.datatables.net/qegerubi/1/edit

    I'm not sure it is much more readable, but then I'm happy reading either style, so I'm probably not the best judge!

    Allan

  • tacman1123tacman1123 Posts: 55Questions: 15Answers: 0
    edited March 12

    I LOVE having it in ES6.

    Two things -- since the latest version allows instantiating the DataTable without jQuery, how about

    var el = document.querySelector('#table'); // or create an element dynamically, etc.
    let table = new DataTable(el, {.. 
    

    I'm using datatable in a stimulus controller, and so I already have the element, in previous versions I had to add an id, then inject jQuery and initialize it with that identifier. White this particular example seems like more code, I think moving toward dom and away from jQuery-esque code is better.

    Secondly, with the initComplete example, if I want to use an anonymous function (to have access to the rest of my component), how do I get the api()? I've always found the this. to be a bit magical. I'd much rather get the elements in the callback, but not quite sure how to do that.

    initComplete: (obj, data) => {
          // what is obj?  How do I get the api()?
          //  this.api(), obj.api(), etc.
    
         // my hacks, trying to figure out how to get what the examples show as this.
    
                        // https://datatables.net/reference/api/
                        // console.error(obj.oApi, el, dt);
                        // console.warn(Object.getOwnPropertyNames(obj).filter(item => typeof obj[item] === 'function'));
                        // console.warn(Object.getOwnPropertyNames(obj).filter(item => typeof obj[item] !== 'function'));
    
    }
    

    I can certainly understand why the internals of DataTables will continue to use jQuery, it's an excellent library for DOM manipulation, and it's deeply embedded in the library. But anyone integrating DataTables shouldn't need to think about it or learn it, especially when there are so many alternatives to jQuery. So having the examples in jQuery, or returning jQuery objects in the callbacks, means that a programmer has to learn jQuery to use DataTables, which shouldn't be necessary.

    Maybe I'm missing something obviously, but I've spent a lot of time hacking the callbacks to avoid jQuery.

    You might be wondering why I'm trying to avoid jQuery so much. I got burned with duplicate copies of it, the whole idea of a global jQuery seems so delicate. You accidentally include jQuery via an import or require somewhere, and some other area of the code breaks. null is not an object. jQuery is not defined. So I swore off jQuery a few years ago, and only use it for select2 (though moving to TomSelect) and DataTables. What happens under the hood with datatables, as I've said, is fine.

    On a somewhat related note, during the transition away from jQuery I switched all my dt ajax calls to fetch, and then more recently switched them to axios. jQuery slim drops ajax and animations. Switching the examples to fetch or axios would certainly help the appearance that DataTables requires that the developer know jQuery.

    In short, that's the big difference, the answer to the title of this thread. If under the hood DataTables uses jQuery, Typescript and axios, it's of little concern, as long as the developers using DataTables don't need to concern themselves with that. (I realize that this argues that DataTables examples should use fetch and not axios, because x years from now axios may be replaced by something else).

    Final note: most of the time jQuery is used in the examples, it's to get an element or elements. And yes, sometimes that's longer as this excellent article points out: https://tobiasahlin.com/blog/move-from-jquery-to-vanilla-javascript/ but as the world moves away from jQuery, it'll be GREAT to never think about it when using your powerful library.

    Thanks for reading this long thread and considering this!

  • allanallan Posts: 55,883Questions: 1Answers: 8,835 Site admin
    edited March 14
    initComplete: function () { }
    // and
    initComplete: () => { }
    

    Are both anonymous functions. What you are referring to is an arrow function sometimes also called a fat arrow function.

    There is nothing wrong with using a regular function () { ... } in ES6. The key difference between the two forms is the scope in which they are executed. In DataTables the initComplete callback is executed in the scope of the table element, and the api() method added to that. Hence why you must use the function () { ... } form, rather than an arrow function. There is no way to access the correct scope in the arrow function. I might change it in v2 to pass an API method by parameter, but other than the benefit of being able to use shorter syntax, it isn't clear to me that it is worth any API changes.

    How about:

    var el = document.querySelector('#table'); // or create an element dynamically, etc.
    let table = new DataTable(el, {.. 
    

    You can already do that: http://live.datatables.net/qibebeqo/1/edit .

    Thanks for your feedback! Good to know the jQuery-less approach is being used.

    Allan

  • tacman1123tacman1123 Posts: 55Questions: 15Answers: 0

    The huge benefit I see for arrow functions is that the scope is the component rather than the table element.

    Let's say I want to do something with a row when it's rendered, depending on something else on the page, like a "debug" property. When the row is drawn, I don't have access to anything else in my component in the callback.

    I know I can say "this = that" before my function, and within the function I can access "that". But I have found this (and that) to make for very unreadable code. I'm not a very advanced JS developer, and I haven't use jQuery in years, so maybe this and that will be less intimidating with more experience.

    I love stimulus.js, so rarely access elements by classes or id. Instead, data is passed to the component by targets and values, which are accessed with this.debugValue and this.resultsTable.

    If the function only operates in the scope of the table element, then of course all the examples are going to be in jQuery - the table element IS a jquery object after all.

  • allanallan Posts: 55,883Questions: 1Answers: 8,835 Site admin

    If the function only operates in the scope of the table element, then of course all the examples are going to be in jQuery - the table element IS a jquery object after all.

    That's not the case as I demonstrated with the code above. The table element is an HTML DOM node. You can optionally encapsulate it in a jQuery object for manipulation with jQuery, but that is entirely optional and up to the developer writing the code.

    I also like the shorthand fat arrow syntax, and use it where appropriate. Sometimes scope shifting is the correct thing for an API to do though and Javascript offers the two methods of defining a function to account for the different ways a program might need to be developed. Scope is fundamentally important. I will look at updating our docs to make it clear what scope functions are executed in.

    Allan

  • tacman1123tacman1123 Posts: 55Questions: 15Answers: 0

    "Scope is fundamentally important. I will look at updating our docs to make it clear what scope functions are executed in." Thanks!

    On a related note, I think there are some jquery events that can likely be handled as DOM events, which would also make the examples easier for non-jQuery folks.

    The function is was referring to was the initComplete, where the function operates in the scope of a DataTable jQuery object, and thus you can get the api with this.api(). BUT I could be completely wrong. I'm simply trying to embed a DataTable in a stimulus controller, and the thing I'm stuck on is how a datatable can interact with the rest of the elements of the component because of the scope.

    I'd be happy to give feedback on specific examples as you update the code. Are the docs available in github? I can also make comments there, or even propose a PR if I get something working.

  • allanallan Posts: 55,883Questions: 1Answers: 8,835 Site admin

    Are the docs available in github?

    The reference docs and examples are. The manual pages are not - but do have comment boxes at the bottom of them for feedback.

    the thing I'm stuck on is how a datatable can interact with the rest of the elements of the component because of the scope.

    Another method for getting the API is to use new DataTable.Api(...) - e.g.:

    initComplete: (s, json) => {
      let api = new DataTable.Api(s);
      // ...
    }
    

    Allan

Sign In or Register to comment.