Version 5.2 Released!

Click to checkout the new features

Menus, Popups & Alerts

Menus

Tabulator has a range of options for providing context menus and header menus on a table.

In the example below the headerMenu column definition option is used to add a menu to column headers, and the rowContextMenu option is used to add a right click context menu to rows.

Loading Example...
Source Code

HTML

<div id="example-table"></div>

JavaScript

//define row context menu contents
var rowMenu = [
    {
        label:"<i class='fas fa-user'></i> Change Name",
        action:function(e, row){
            row.update({name:"Steve Bobberson"});
        }
    },
    {
        label:"<i class='fas fa-check-square'></i> Select Row",
        action:function(e, row){
            row.select();
        }
    },
    {
        separator:true,
    },
    {
        label:"Admin Functions",
        menu:[
            {
                label:"<i class='fas fa-trash'></i> Delete Row",
                action:function(e, row){
                    row.delete();
                }
            },
            {
                label:"<i class='fas fa-ban'></i> Disabled Option",
                disabled:true,
            },
        ]
    }
]

//define column header menu as column visibility toggle
var headerMenu = function(){
    var menu = [];
    var columns = this.getColumns();

    for(let column of columns){

        //create checkbox element using font awesome icons
        let icon = document.createElement("i");
        icon.classList.add("fas");
        icon.classList.add(column.isVisible() ? "fa-check-square" : "fa-square");

        //build label
        let label = document.createElement("span");
        let title = document.createElement("span");

        title.textContent = " " + column.getDefinition().title;

        label.appendChild(icon);
        label.appendChild(title);

        //create menu item
        menu.push({
            label:label,
            action:function(e){
                //prevent menu closing
                e.stopPropagation();

                //toggle current column visibility
                column.toggle();

                //change menu item icon
                if(column.isVisible()){
                    icon.classList.remove("fa-square");
                    icon.classList.add("fa-check-square");
                }else{
                    icon.classList.remove("fa-check-square");
                    icon.classList.add("fa-square");
                }
            }
        });
    }

   return menu;
};

//initialize table
var table = new Tabulator("#example-table", {
    height:"311px",
    layout:"fitColumns",
    rowContextMenu: rowMenu, //add context menu to rows
    columns:[
        {title:"Name", field:"name", headerMenu:headerMenu},
        {title:"Progress", field:"progress", hozAlign:"right", sorter:"number", headerMenu:headerMenu},
        {title:"Gender", field:"gender", headerMenu:headerMenu},
        {title:"Rating", field:"rating", hozAlign:"center", headerMenu:headerMenu},
        {title:"Favourite Color", field:"col", headerMenu:headerMenu},
    ],
});

Menu Items

Each menu option accepts an array of menu item objects, with each object representing an item in the menu

var table = new Tabulator("#example-table", {
    rowContextMenu: [
        {
            label:"Hide Column",
            action:function(e, column){
                column.hide();
            }
        },
        {
            separator:true,
        },
        {
            disabled:true,
            label:"Move Column",
            action:function(e, column){
                column.move("col");
            }
        }
    ]
});

Labels

The label is a mandatory property for standard menu items and sets the display text for the item

This property can take either a string, HTML or a DOM Node for the labels contents

{
    label:"Hide Column",
}

Alternativly you can pass a function to this property which will be called when the menu is loaded. A Component for the column/cell/row that triggered the menu will be passed in as the first argument. The function should return the contents for the label as outlined above.

{
    label:function(component){
        //component - column/cell/row component that triggered the menu

        return "Delete " . component.getData().name; //customise menu contents with row data
    },
}

Action

The action is a mandatory property for standard menu items and sets a callback that will be triggered when the menu item is clicked

The first argument is the event object for the click event on the menu item. The second argument will be a column/cell/row Component for the component that triggered the menu

{
    action:function(e, component){
        //e - click event from the menu item click
        //component - column/cell/row component that triggered the menu

        return component.delete(); //delete the row the context menu was loaded on
    },
}
e action this is a callback that will be triggered if the user clicks on the menu item, it is passed two arguments

Columns of the table can be set as editable using the editor property in the column definition. (see Define Columns for more details).

Disabled Items

You can disable a menu item by setting the disabled property to true on the item. This will grey out the item in the menu and prevent the user from clicking on it

{
    disabled:true,
}

Alternativly you can pass a function to this property which will be called when the menu is loaded. A Component for the column/cell/row that triggered the menu will be passed in as the first argument. The function should return a boolean to indicate the status of the item, a value of true will disable the item, a value of false will enable the item.

{
    disabled:function(component){
        //component - column/cell/row component that triggered the menu

        return !component.getData().approved; //disable the menu item if the row data approved property is true
    },
}

Separators

You can add a horizontal separator to a list of menu items by including an object with the separator property set to true

{
    separator:true,
}

Nested Menus

It is possible to build out more complex menu systems by using nested sub menus. To add a sub menu to an item, set the menu property with an array of menu items.

Sub menus can be nested as many layers deep as you need.

var table = new Tabulator("#example-table", {
    rowContextMenu: [
        {
            label:"Hide Column",
            action:function(e, column){
                column.hide();
            }
        },
        {
            label:"Sub Menu", //sub menu
            menu:[
                {
                    label:"Do Something",
                    action:function(e, column){
                        //do something
                    }
                },
                {
                    label:"Do Something Else",
                    action:function(e, column){
                        //do something else
                    }
                },
                {
                    label:"Deeper Sub Menu", //sub menu nested in sub menu
                    menu:[
                        {
                            label:"Do Another Thing",
                            action:function(e, column){
                                //do another thing
                            }
                        },
                    ]
                }
            ]
        }
    ]
});

Menu Items Generator Function

If you would prefer to generate your menu item layout when the menu is opened you can pass a callback function to any of the menu options.

A Component for the column/cell/row that triggered the menu will be passed in as the first argument. The function should return an array of menu objects for the menu.

If the function returns a value of false or an empty array, the menu will not be shown

var table = new Tabulator("#example-table", {
    rowContextMenu: function(e, component){
        //component - column/cell/row component that triggered the menu
        //e - click event object

        var menu = [];

        if(!component.getData().approved){
            menu.push({
                label:"Approve User",
                action:function(e, column){
                    component.update({"approved":true});
                }
            })
        }else{
            menu.push({
                label:"Unapprove User",
                action:function(e, column){
                    component.update({"approved":false});
                }
            })
        }

        return menu;
    }
});

Container Element

By default Tabulator will append the menu element to the body element of the DOM as this allows the menu to appear correctly in the vast majority of situations.

There are some circumstances where you may want the menu to be appended to a different element, such as the body of a modal, so that the menu is contained with that element.

In these circumstances you can use the popupContainer option to specify the element that the menu should be appended to.

var table = new Tabulator("#example-table", {
    popupContainer:"#modal-div", //append menu to this element
});

The popupContainer option can accept one of the following values:

  • false - Append menu to the body element (default)
  • true - Append menu to the table
  • CSS selector string - A valid CSS selector string
  • DOM node - A DOM Node

If Tabulator cannot find a matching element from the property, it will default to the document body element.

Container Position
Menu elements are positioned absolutely inside their container. For this reason you must make sure that your container has its position defined in CSS

Parent Element
The element you pass into the popupContainer option must be a parent of the table element or it will be ignored

Chnage Affects All Popup
The popupContainer option affects the container for all popups (menus, popups, tooltips, list editors), so make sure you select an option that works for them all

Column Header Menus

You can add a menu to any column by passing an array of menu items to the headerMenu option in that columns definition.

Adding a header menu will cause a button to appear to the left of the column header title. clicking on this button will open the menu.

//define row context menu
var headerMenu = [
    {
        label:"Hide Column",
        action:function(e, column){
            column.hide();
        }
    },
]

//add header menu in column definition
var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", headerMenu:headerMenu}, //add menu to this column header
    ]
});

Column Group Header Menus

Column header menus can also be added to column groups using the same headerMenu option, but declared in the column group object

//define row context menu
var headerMenu = [
    {
        label:"Hide Column",
        action:function(e, column){
            column.hide();
        }
    },
]

//add header menu in column definition
var table = new Tabulator("#example-table", {
    columns:[
        {
            title:"Column Group",
            headerMenu:headerMenu, //add a menu to this column header
            columns:[
                {title:"Name", field:"name", width:200},
                {title:"Age", field:"age", width:200}
            ]
        }
    ]
});

Column Header Menu Icon

When you insert a header menu, Tabulator will add a button to the header element with an icon. You can change the contents of this button using headerMenuIcon column definition option

The headerMenuIcon option will accept one of three types of value. You can pass in a string for the HTML contents of the button

{title:"Name", field:"name", headerMenuIcon:"<i class='fas fa-filter'></i>", headerMenu:headerMenu}

Or you can pass the DOM node for the button. Though be careful not to pass the same node to multple columns or you may run into issues.

//define element
var buttonContents = document.createElement("span");
buttonContents.innerText = "Filter";

//column definition
{title:"Name", field:"name", headerMenuIcon:buttonContents, headerMenu:headerMenu}

Or you can define a function that is called when the column header is rendered that should return either an HTML string or the contents of the element. This funtion is passed the column component as its first argument

{title:"Name", field:"name", headerMenuIcon:function(component){
    //component - column component for header

    return "<i class='fas fa-filter'></i>";
}}

Column Header Context Menus

You can add a right click context menu to any column by passing an array of menu items to the headerContextMenu option in that columns definition.

//define row context menu
var headerContextMenu = [
    {
        label:"Hide Column",
        action:function(e, column){
            column.hide();
        }
    },
]

//add header menu in column definition
var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", headerContextMenu:headerContextMenu}, //add a context menu to this column header
    ]
});

Mobile Devices
When used on a mobile device the context menu will be triggered by a long press on the element

Column Group Header Context Menus

Column header context menus can also be added to column groups using the same headerContextMenu option, but declared in the column group object

//define row context menu
var headerContextMenu = [
    {
        label:"Hide Column",
        action:function(e, column){
            column.hide();
        }
    },
]

//add header menu in column definition
var table = new Tabulator("#example-table", {
    columns:[
        {
            title:"Column Group",
            headerContextMenu:headerContextMenu, //add a context menu to this column header
            columns:[
                {title:"Name", field:"name", width:200},
                {title:"Age", field:"age", width:200}
            ]
        }
    ]
});

If you declare context menu in both column headers and column group headers then which menu appears will depend on where the user clicks.

Cell Context Menus

You can add a right click context menu to any columns cells by passing an array of menu items to the contextMenu option in that columns definition.

//define cell context menu
var cellContextMenu = [
    {
        label:"Reset Value",
        action:function(e, cell){
            cell.setValue("");
        }
    },
]

//add header menu in column definition
var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", contextMenu:cellContextMenu}, //add a context menu to the cells in this column
    ]
});

Mobile Devices
When used on a mobile device the context menu will be triggered by a long press on the element

Left Click Menu

As an alternative to the right click context menu, you can also trigger a menu on a left click by using the clickMenu option in the column definition.

//add header menu in column definition
var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", clickMenu:cellContextMenu}, //add a left click menu to the cells in this column
    ]
});

Row Context Menus

You can add a right click context menu to rows passing an array of menu items to the rowContextMenu table setup option.

var table = new Tabulator("#example-table", {
    rowContextMenu:[
        {
            label:"Delete Row",
            action:function(e, row){
                row.delete();
            }
        },
    ]
});

Mobile Devices
When used on a mobile device the context menu will be triggered by a long press on the element

Left Click Menu

As an alternative to the right click context menu, you can also trigger a menu on a left click by using the rowClickMenu option in the column definition.

var table = new Tabulator("#example-table", {
    rowClickMenu:[
        {
            label:"Delete Row",
            action:function(e, row){
                row.delete();
            }
        },
    ]
});

Group Header Context Menus

You can add a right click context menu to row group headers passing an array of menu items to the groupContextMenu table setup option.

var table = new Tabulator("#example-table", {
    groupContextMenu:[
        {
            label:"Hide Group",
            action:function(e, group){
                //e - context click event
                //group - group component for group

                group.hide();
            }
        },
    ]
});

Mobile Devices
When used on a mobile device the context menu will be triggered by a long press on the element

Left Click Menu

As an alternative to the right click context menu, you can also trigger a menu on a left click by using the groupClickMenu table setup option.

var table = new Tabulator("#example-table", {
    groupClickMenu:[
        {
            label:"Hide Group",
            action:function(e, group){
                //e - context click event
                //group - group component for group

                group.hide();
            }
        },
    ]
});

Popups

Popups work in a similar way to menus, but instead of only displaying lists of menu items then allow you to fill them with any custom content you like, text, input elements, forms, anything you fancy.

The example below has two type of popup, if you click on a row you will see a popup with more row details, and if you click on the filter icon in the column header you will see a popup that lets you filter the column data:

Loading Example...
Source Code

HTML

<div id="example-table"></div>

JavaScript

//create row popup contents
var rowPopupFormatter = function(e, row, onRendered){
    var data = row.getData(),
    container = document.createElement("div"),
    contents = "<strong style='font-size:1.2em;'>Row Details</strong><br/><ul style='padding:0;  margin-top:10px; margin-bottom:0;'>";
    contents += "<li><strong>Name:</strong> " + data.name + "</li>";
    contents += "<li><strong>Gender:</strong> " + data.gender + "</li>";
    contents += "<li><strong>Favourite Colour:</strong> " + data.col + "</li>";
    contents += "</ul>";

    container.innerHTML = contents;

    return container;
};

//create header popup contents
var headerPopupFormatter = function(e, column, onRendered){
    var container = document.createElement("div");

    var label = document.createElement("label");
    label.innerHTML = "Filter Column:";
    label.style.display = "block";
    label.style.fontSize = ".7em";

    var input = document.createElement("input");
    input.placeholder = "Filter Column...";
    input.value = column.getHeaderFilterValue() || "";

    input.addEventListener("keyup", (e) => {
        column.setHeaderFilterValue(input.value);
    });

    container.appendChild(label);
    container.appendChild(input);

    return container;
}

//create dummy header filter to allow popup to filter
var emptyHeaderFilter = function(){
    return document.createElement("div");;
}

//initialize table
var table = new Tabulator("#example-table", {
    height:"311px",
    layout:"fitColumns",
    rowClickPopup:rowPopupFormatter, //add click popup to row
    columns:[
        {title:"Name", field:"name", headerPopup:headerPopupFormatter, headerPopupIcon:"<i class='fas fa-filter' title='Filter column'></i>", headerFilter:emptyHeaderFilter, headerFilterFunc:"like"},
    ],
});

Defining a Popup

When definind a popup you can pass one of three types of value into the option. You can pass in a string for the HTML contents of the button

{title:"Name", field:"name", cellPopup:"Hey, Im a Popup!"}

Or you can pass the DOM node for the button. Though be careful not to pass the same node to multple columns or you may run into issues.

//define element
var popupContents = document.createElement("span");
popupContents.innerText = "Hey Im a Popup!";

//column definition
{title:"Name", field:"name", cellPopup:popupContents}

Or you can define a function that is called when the popup is rendered that should return either an HTML string or the contents of the element. This funtion is passed the mouse/touch event as its first argument and the component of the element that triggered the popup as the second argument

{title:"Name", field:"name", cellPopup:function(e, component, onRendered){
    //e - the mouse/touch event that triggered the popup
    //component - column/row/cell component that triggered this popup
    //onRendered - function to call when the formatter has been rendered

    return "Hey Im a Popup!";
}}

The onRendered callback function passed into the third argument allows you to register a callback that will be triggered when the popup has been added to the dom but before its position is confirmed. This can be useful when you are trying to use a 3rd party library that needs the element to be visible before it can be instatiated

To use this function you need to pass a callback that runs any of your required code as the only argument. The example below uses the jQuery sparkline widget to add a small chart to the popup

{title:"Name", field:"name", cellPopup:function(e, component, onRendered){
    //component - column/row/cell component that triggered this popup
    //e - the mouse/touch event that triggered the popup
    //onRendered - function to call when the formatter has been rendered

    var element = document.createElement("div");

    onRendered(function(){
        $(element).sparkline(component.getValue(), {width:"100%", type:"bar"});
    });

    return element;
}}

Close On Blur

Popups will automatically close when focus on the popup element is lost.

Column Header Popups

Column Header Popup

You can add a popup to any column by passing the popup contents to the headerPopup option in that columns definition.

Adding a header popup will cause a button to appear to the left of the column header title. clicking on this button will open the popup.

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", headerPopup:"Im a Popup"}, //add popup button to this column header
    ]
});

Column Header Popup Icon

When you insert a header popup, Tabulator will add a button to the header element with an icon. You can change the contents of this button using headerPopupIcon column definition option

The headerPopupIcon option will accept one of three types of value. You can pass in a string for the HTML contents of the button

{title:"Name", field:"name", headerPopupIcon:"<i class='fas fa-bars'></i>"}

Or you can pass the DOM node for the button. Though be careful not to pass the same node to multple columns or you may run into issues.

//define element
var buttonContents = document.createElement("span");
buttonContents.innerText = "Popup";

//column definition
{title:"Name", field:"name", headerPopupIcon:buttonContents}

Or you can define a function that is called when the column header is rendered that should return either an HTML string or the contents of the element. This funtion is passed the column component as its first argument

{title:"Name", field:"name", headerPopupIcon:function(component){
    //component - column component for header

    return "<i class='fas fa-bars'></i>";
}}

Column Header Context Popup

You can add a right click popup to any column by passing the popup contents to the headerContextPopup option in that columns definition.

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", headerContextPopup:"Im a Popup"}, //add context popup to this column header
    ]
});

Mobile Devices
When used on a mobile device the context menu will be triggered by a long press on the element

Row Popups

Row Click Popup

You can add a click popup to any row by passing the popup contents to the rowClickPopup option in the table constructor object.

var table = new Tabulator("#example-table", {
    rowClickPopup:"Im a Popup"
});

Row Context Popup

You can add a right click popup to any row by passing the popup contents to the rowContextPopup option in the table constructor object.

var table = new Tabulator("#example-table", {
    rowContextPopup:"Im a Popup"
});

Mobile Devices
When used on a mobile device the context menu will be triggered by a long press on the element

Cell Popups

Cell Click Popup

You can add a click popup to any cell by passing the popup contents to the clickPopup option in that columns definition.

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", clickPopup:"Im a Popup"} //add cell click popup
    ]
});

Cell Context Popup

You can add a right click popup to any cell by passing the popup contents to the contextPopup option in that columns definition.

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", contextPopup:"Im a Popup"} //add cell context popup
    ]
});

Group Popups

Group Header Click Popup

You can add a click popup to any group header by passing the popup contents to the groupClickPopup option in the table constructor object.

var table = new Tabulator("#example-table", {
    groupClickPopup:"Im a Popup"
});

Group Header Context Popup

You can add a right click popup to any group header by passing the popup contents to the groupContextPopup option in the table constructor object.

var table = new Tabulator("#example-table", {
    groupContextPopup:"Im a Popup"
});

Alerts

Alerts provide full table modal take over messages, with a semi transparent full table sized background and a centered message. These are used for example to show a loading message when the table is loading remote data via ajax request.

Click the buttons on the example below to see alerts in action

Alert Controls

Loading Example...
Source Code

HTML

<div class="table-controls">
  <button id="alert-show">Show Alert</button>
  <button id="alert-clear">Hide Alert</button>
</div>

<div id="example-table"></div>

JavaScript

//Define variables for buttons
var showBtn = document.getElementById("alert-show");
var hideBtn = document.getElementById("alert-clear");

//handle button click events
showBtn.addEventListener("click", (e)=> {
  table.alert("Hey There! I'm An Alert!");
});

hideBtn.addEventListener("click", (e)=> {
  table.clearAlert();
});

//Build Tabulator
var table = new Tabulator("#example-table", {
    height:"311px",
    layout:"fitColumns",
    columns:[
        {title:"Name", field:"name", width:200},
        {title:"Progress", field:"progress", formatter:"progress", sorter:"number"},
        {title:"Gender", field:"gender"},
        {title:"Rating", field:"rating", formatter:"star", hozAlign:"center", width:100},
        {title:"Favourite Color", field:"col"},
        {title:"Date Of Birth", field:"dob", hozAlign:"center", sorter:"date"},
        {title:"Driver", field:"car", hozAlign:"center", formatter:"tickCross"},
    ],
});

Showing an Alert

To show an alert, call the alert function on the table. Passing the message into the first argument of the function.

table.alert("This is an alert!");

The alert function will accept one of several diffrent types alert:

  • string - A text string or valid HTML content for the alert
  • DOM node - A DOM Node of the element to be included inside the alert

Alert Styles

The alert function also provides a way to style the alert message being presented to the user. There are two built in styles:

  • msg - A black border with black text (default)
  • error - A red border with red text

You can pass the style into the optional second argument of the alert function:

table.alert("This is an alert!", "error");

Behind the scenes this works by applying the tabulator-alert-state-error class to the .tabulator-alert-msg element. You can therefor provide any string you like to the second argument and then use it to apply custom styles to the alert.

For example if we passed a value of warning to the second argument of the alertfunction the tabulator-alert-state-warning class to the .tabulator-alert-msg element

Clearing an Alert

To clear an active alert, call the clearAlert funtion on the table.

table.clearAlert();

Tooltips

Cell Tooltips

You can set tooltips to be displayed when the cursor hovers over cells, these can contain any value and be formatted in any way you like.

Tooltips can either be set per column in the column definition object

//column definition object in the columns array
    {title:"Name", field:"name", tooltip:true},

Or globally in the columnDefaults object:

var table = new Tabulator("#example-table", {
    columnDefaults:{
        tooltip:true,
    }
});

The tooltip parameter can take three different types of value

  • boolean - a value of false disables the tooltip, a value of true sets the tooltip of the cell to its value
  • string - a string that will be displayed for all cells in the matching column/table.
  • DOM Node - a DOM node for the tooltip
  • function - a callback function that returns either the html/text contents for the tooltip, or a DOM node for the contents of the tooltip:

The function accepts three arguments, the first is the mouseover event object that triggered the tooltip, the second is CellComponent for the cell the tooltip is being generated for, the third argument is the onRendered function that allows you to register a callback that will be triggered when the popup has been added to the DOM but before its position is confirmed.

This function wil also allow you to style the tooltip by applying styles to the returned element if desired

var table = new Tabulator("#example-table", {
    columnDefaults:{
        tooltip:function(e, cell, onRendered){
            //e - mouseover event
            //cell - cell component
            //onRendered - onRendered callback registration function
            
            var el = document.createElement("div");
            el.style.backgroundColor = "red";
            el.innerText = cell.getColumn().getField() + " - " + cell.getValue(); //return cells "field - value";
            
            return el; 
        },
    }
});

Column Header Tooltips

It is also possible to set tooltips to display on the column headers. This is particularly useful when your columns are too narrow to display full header names.

Header tooltips can either be in a columns definition object:

//column definition object in the columns array
    {title:"name", field:"name", headerTooltip:true},

The tooltip headerTooltip can take three different types of value

  • boolean - a value of false disables the tooltip, a value of true sets the tooltip of the column header to its title value.
  • string - a string that will be displayed for the tooltip.
  • DOM Node - a DOM node for the tooltip
  • function - a callback function that returns either the html/text contents for the tooltip, or a DOM node for the contents of the tooltip:

The function accepts three arguments, the first is the mouseover event object that triggered the tooltip, the second is ColumnComponent for the column header the tooltip is being generated for, the third argument is the onRendered function that allows you to register a callback that will be triggered when the popup has been added to the DOM but before its position is confirmed.

This function wil also allow you to style the tooltip by applying styles to the returned element if desired

var table = new Tabulator("#example-table", {
    columnDefaults:{
        headerTooltip:function(e, cell, onRendered){
            //e - mouseover event
            //cell - cell component
            //onRendered - onRendered callback registration function
            
            var el = document.createElement("div");
            el.style.backgroundColor = "red";
            el.innerText = column.getDefinition().title;
            
            return el; 
        },
    }
});
Support