Show/Hide or Toggle Nested Table Child In Tabulator
Asked Answered
M

3

7

I was wondering if you could help with something I believe to be pretty simple. Using the Tabulator nested table example(Not Tree), how can I make the child table show/hide on click? I want users to be able to expand for further information if they require it similar to the tree example.

I have seen a few answers to this but they don't seem to work for me.

//define table
var table = new Tabulator("#example-table", {
    height:"311px",
    layout:"fitColumns",
    resizableColumns:false,
    data:nestedData,
    columns:[
        {title:"Make", field:"make"},
        {title:"Model", field:"model"},
        {title:"Registration", field:"reg"},
        {title:"Color", field:"color"},
    ],
    rowFormatter:function(row){
        //create and style holder elements
       var holderEl = document.createElement("div");
       var tableEl = document.createElement("div");

       holderEl.style.boxSizing = "border-box";
       holderEl.style.padding = "10px 30px 10px 10px";
       holderEl.style.borderTop = "1px solid #333";
       holderEl.style.borderBotom = "1px solid #333";
       holderEl.style.background = "#ddd";

       tableEl.style.border = "1px solid #333";

       holderEl.appendChild(tableEl);

       row.getElement().appendChild(holderEl);

       var subTable = new Tabulator(tableEl, {
           layout:"fitColumns",
           data:row.getData().serviceHistory,
           columns:[
           {title:"Date", field:"date", sorter:"date"},
           {title:"Engineer", field:"engineer"},
           {title:"Action", field:"actions"},
           ]
       })
    },
});
Madrid answered 2/5, 2019 at 1:55 Comment(1)
Thank you, please see updated jsfiddle.net/2Lnyrqg4.Madrid
M
6

Using a mix of @dota2pro example here is a nice working solution:

https://jsfiddle.net/ustvnz5a/2/

    var nestedData = [{
    id: 1,
    make: "Ford",
    model: "focus",
    reg: "P232 NJP",
    color: "white",
    serviceHistory: [{
        date: "01/02/2016",
        engineer: "Steve Boberson",
        actions: "Changed oli filter"
      },
      {
        date: "07/02/2017",
        engineer: "Martin Stevenson",
        actions: "Break light broken"
      },
    ]
  },
  {
    id: 2,
    make: "BMW",
    model: "m3",
    reg: "W342 SEF",
    color: "red",
    serviceHistory: [{
        date: "22/05/2017",
        engineer: "Jimmy Brown",
        actions: "Aligned wheels"
      },
      {
        date: "11/02/2018",
        engineer: "Lotty Ferberson",
        actions: "Changed Oil"
      },
      {
        date: "04/04/2018",
        engineer: "Franco Martinez",
        actions: "Fixed Tracking"
      },
    ]
  },
]

var hideIcon = function(cell, formatterParams, onRendered){ //plain text value
    return "<i class='fa fa-eye-slash'></i>";
};

const table = new Tabulator("#example-table", {
  height: "311px",
  layout: "fitColumns",
  resizableColumns: false,
  data: nestedData,
  selectable: true,
  columns: [{
      title: "Make",
      field: "make"
    },
    {
      title: "Model",
      field: "model"
    },
    {
      title: "Registration",
      field: "reg"
    },
    {
      title: "Color",
      field: "color"
    },
    {formatter:hideIcon, align:"center", title:"Hide Sub", headerSort:false, cellClick:function(e, row, formatterParams){
     const id = row.getData().id;
    $(".subTable" + id + "").toggle();      
    }
}
  ],
  rowFormatter: function(row, e) {
    //create and style holder elements
    var holderEl = document.createElement("div");
    var tableEl = document.createElement("div");

    const id = row.getData().id;

    holderEl.style.boxSizing = "border-box";
    holderEl.style.padding = "10px 10px 10px 10px";
    holderEl.style.borderTop = "1px solid #333";
    holderEl.style.borderBotom = "1px solid #333";
    holderEl.style.background = "#ddd";
    holderEl.setAttribute('class', "subTable" + id + "");


    tableEl.style.border = "1px solid #333";
    tableEl.setAttribute('class', "subTable" + id + "");

    holderEl.appendChild(tableEl);

    row.getElement().appendChild(holderEl);

    var subTable = new Tabulator(tableEl, {
      layout: "fitColumns",
      data: row.getData().serviceHistory,
      columns: [{
          title: "Date",
          field: "date",
          sorter: "date"
        },
        {
          title: "Engineer",
          field: "engineer"
        },
        {
          title: "Action",
          field: "actions"
        },
      ]
    })
  },
}); 
Madrid answered 3/5, 2019 at 2:54 Comment(2)
This is using an Icon to unhide/hide the sub-table. The reason I haven't done it on row click is because in my example the users needs to click to edit the field.Madrid
This is exactly what I was looking for with the only small detail of launching with the initial state of the nested tables hidden.Heteroplasty
D
3

Check this jsfiddle

  selectable: true,
  rowClick: function(e, row) {
    const id = row.getData().id;
    $(".subTable" + id + "").toggle();

  },
Demetrius answered 3/5, 2019 at 0:9 Comment(3)
This is a start but would be better to show/hide by clicking the row. I found this on Github and they suggest using rowformatter. Maybe you have a better chance then I have of working this out. github.com/olifolkerd/tabulator/issues/175.Madrid
Nice!! I will edit this so I can toggle the rows individually.Madrid
I found a working solution when you hit a cell to close the corresponding sub-table. Example here: jsfiddle.net/86sdqLpaMadrid
C
1

This is just for help with hiding the expanded sections by default. My solution has 2 parts. One when I load the data and one when the page changes using the pagination controls.

Here is my part when I set the data:

myTable.setData(myData);

            myTable.setHeight("100%");
            myTable.redraw();

            var rows = myTable.getRows();

            rows.forEach(function (row) {
                var data2 = row.getData();

                const id = data2.IDField;
                $(".subTable" + id + "").toggle();
            });

I use this event to handle page changes:

pageLoaded: function (pageno) {

                var rows = myTable.getRows();

                rows.forEach(function (row) {
                    var data = row.getData();


                    const id = data.AssetNumber;
                    //use hide, toggle works great first time you view the tab, 2nd time it opens them all
                    $(".subTable" + id + "").hide();
                    //$(".subTable" + id + "").toggle();
                });
            }

Thanks for the great code used everyone else.

Cerebroside answered 24/2, 2023 at 18:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.