javascriptjquerydatatablesdatatables-1.10

How do I override a JQuery (Datatable RowGroup) library function?


I'm rather new to Javascript, and the scoping syntax definitely confuses me when looking at open source libraries especially when it has a lot of advanced concepts like closure, anonymous functions, etc. The Jquery Datatables RowGroup is a a bit buggy with Responsiveness, so I took the bold attempt of writing my own attempt at a solution.

Below is the relevant snippet from the RowGroup library, source code from https://cdn.datatables.net/rowgroup/1.1.1/js/dataTables.rowGroup.js:

/** <Not sure what is going on here!> */
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery', 'datatables.net'], function ($) {
            return factory($, window, document);
        });
    } else if (typeof exports === 'object') {
        // CommonJS
        module.exports = function (root, $) {
            if (!root) {
                root = window;
            }

            if (!$ || !$.fn.dataTable) {
                $ = require('datatables.net')(root, $).$;
            }

            return factory($, root, root.document);
        };
    } else {
        // Browser
        factory(jQuery, window, document);
    }
}(function ($, window, document, undefined) {
    /** </Not sure what is going on here!> */
    'use strict';
    var DataTable = $.fn.dataTable;

    var RowGroup = function (dt, opts) {
        //...
    };
    $.extend(RowGroup.prototype, {
        //...
        _constructor: function () {
            //...
            dt.on('responsive-resize.dt', function () {
                that._adjustColspan();
            });
        },

        /** I would like to override this function, externally */
        _adjustColspan: function () {
            @ @override
        }
    });
}));

Although it is open source, instead of modifying the library directly, I'd like to override the function _adjustColspan from a separate Javascript file (which will be included after this library). This will allow the library still be update-able without hassle, and any custom changes can be easily tracked.

So first off, is what I'm trying to accomplish possible? If it is possible, how would I go about overriding this function in an external .js file?

Edit: It seems what I'm trying to do is coined "Monkey patching"


Solution

  • Looks like the RowGroup object comes from an extension over on https://github.com/DataTables/RowGroup/blob/master/js/dataTables.rowGroup.js, which we can read through to see if there's some easy place we can grab a reference to it... and there is.

    https://github.com/DataTables/RowGroup/blob/master/js/dataTables.rowGroup.js#L418 shows that its getting bound to $.fn.dataTable.RowGroup, which means that we can grab it from there in any context that has jQuery available.

    const RowGroup = $.fn.DataTable.RowGroup;
    
    RowGroup.prototype._adjustColspan = function() {
      // do your own things here
    }
    

    (With the original code over on https://github.com/DataTables/RowGroup/blob/master/js/dataTables.rowGroup.js#L180-L184)

    You can test this in your dev tools over on https://datatables.net/extensions/rowgroup/examples/styling/jqueryui.html, for instance. Typing $.fn.DataTable.RowGroup.prototype there gives us:

    {​  
      _adjustColspan: function _adjustColspan()​
      _colspan: function _colspan()​
      _constructor: function _constructor()​
      _draw: function _draw()​
      _group: function _group(b, g)​
      _groupDisplay: function _groupDisplay(b, a)​
      _rowWrap: function _rowWrap(b, g, c)​
      constructor: function h(b, g)​
      dataSrc: function dataSrc(b)​
      disable: function disable()​
      enable: function enable(b)​
      <prototype>: Object { … }
    }
    

    And we can change that prototype to be whatever we want.