Including ERPNext's Internal Datatable, On A Page

I would like to figure out a way to use Frappe’s own datatable on a page in ERPNext. I have browsed through virtually every topic in discuss.frappe.io that seems relevant, but I haven’t come up with a solution other than using jQuery’s getScript() to load an external version of datatable. What follows are a list of my attempts, and their results.

Note: I am using ERPNext v12.18.0

My first attempt was using frappe.require():

    frappe.require([
        "/assets/frappe/js/lib/Sortable.min.js",
        "/assets/frappe/js/lib/clusterize.min.js",
        "/assets/frappe/js/lib/frappe-datatable.js",
    ], () => {
        // datatable logic here
    });

The results of this attempt looked like this:

Obviously not what I was going for. On examination, I discovered the data was present in the table, which led me to believe I was missing a CSS file. However, further experimentation led me to believe that the datatable CSS is part of frappe’s default desk CSS.

My second attempt was to use jQuery:

    $.when(
        $.getScript("/assets/frappe/js/lib/Sortable.min.js"),
        $.getScript("/assets/frappe/js/lib/clusterize.min.js"),
        $.getScript("/assets/frappe/js/lib/frappe-datatable.js"),
        $.Deferred(function( deferred ) {
            $( deferred.resolve );
        })
    ).done(() =>  {
        // datatable logic here
    });

My third attempt - using external libraries:

This resulted in the same table styling issue as before. I then attempted to use frappe.require() to load external libraries, and discovered that it only allows relative URLs. Not to be deterred, I went back to my jQuery crutch:

    $.when(
        $.getScript("https://unpkg.com/sortablejs@1.13.0/Sortable.min.js"),
        $.getScript("https://unpkg.com/clusterize.js@0.18.1/clusterize.min.js"),
        $.getScript("https://unpkg.com/frappe-datatable@1.15.3/dist/frappe-datatable.min.js"),
        $.Deferred(function( deferred ) {
            $( deferred.resolve );
        })
    ).done(() =>  {
        // datatable logic here
    });

This worked. However, it wasn’t what I wanted; firstly because it relies on javascript external to my app, secondly because it uses a different version of datatable than ERPNext (I want a consistent user interface) and finally because the version of datatable won’t keep pace with ERPNext.

My fourth attempt - using hooks.py:

I next attempted to use hooks.py’s page_js to load the datatable javascript onto the page, following several examples I found on discuss.frappe.io. Since I’m trying to add this to a frappe “Page” doctype, this seemed to be exactly what it was designed to do:

page_js = {
    "my-page" : [
        "/assets/frappe/js/lib/Sortable.min.js",
        "/assets/frappe/js/lib/clusterize.min.js",
        "/assets/frappe/js/lib/frappe-datatable.js",
    ],
}

The result: Datatable was not defined - the javascript didn’t load on the page.

Again, I tried external libraries as an experiment:

page_js = {
    "my-page" : [
        "https://unpkg.com/sortablejs@1.13.0/Sortable.min.js",
        "https://unpkg.com/clusterize.js@0.18.1/clusterize.min.js",
        "https://unpkg.com/frappe-datatable@1.15.3/dist/frappe-datatable.min.js",
    ],
}

Datatable was not defined.

I created a separate issue for this topic, since my question is more specific and I really want to make use of page_js for other reasons:

My final result: I could not get frappe’s internal datatables to work on my Page.

Is there anyone who can offer tips or direction to get this done?

3 Likes

In v13 DataTable is accessible at frappe.DataTable, e.g.

let table = new frappe.Datatable('.container', {
    ...datatableOptions,
    columns,
    data,
});

I did find some CSS “bugs” (at least to me), which I fixed with by adding the empty-table class to empty tables and inserting the following CSS into the page

/* begin fix tall tables when empty */
.empty-table .dt-scrollable {
    height     : initial!important;
    min-height : initial!important;
}
/* end fix tall tables when empty */

/* begin dynamicRowHeight fix */
.dt-row {
    position : relative!important;
    top      : auto!important;
    height   : initial!important;
}
.dt-cell {
    height : initial!important;
}
/* end dynamicRowHeight fix */
2 Likes

Just discovered: your filename cannot have dashes (-) in it.