jQuery Grid: Context Menu

Right-Click on a jqxGrid Row to open a Context Menu.

A live JavaScript/jQuery example of jqxGrid, the jQWidgets Grid component, with its complete source code below. It is one of 139 jqxGrid demos for jQuery.

jqxGrid API used in this demo

Source code

To run it in your own page, load jqx.base.css, a theme and the library files below from npm (npm install jqwidgets-scripts) or the jsDelivr CDN, then add the markup and the script. jQuery is not required: jqxcore.js provides $. Getting started with jqxGrid shows the setup step by step.

The page loads jqx.base.css, a theme and these library files: jqxcore.js, jqxdata.js, jqxbuttons.js, jqxscrollbar.js, jqxmenu.js, jqxgrid.js, jqxgrid.pager.js, jqxgrid.selection.js, jqxnumberinput.js, jqxwindow.js, jqxlistbox.js, jqxdropdownlist.js.

It also loads helper scripts of this demo site, which are not part of the library: demos.js (getWidth() and other layout helpers), generatedata.js (generatedata(), random sample rows).

script.js

$(document).ready(function () {
    // prepare the data
    var data = generatedata(25);

    var source =
    {
        localdata: data,
        datatype: "array",
        datafields:
        [
            { name: 'firstname', type: 'string' },
            { name: 'lastname', type: 'string' },
            { name: 'productname', type: 'string' },
            { name: 'quantity', type: 'number' },
            { name: 'price', type: 'number' }
        ],
        updaterow: function (rowid, rowdata, commit) {
            // synchronize with the server - send update command
            // call commit with parameter true if the synchronization with the server is successful 
            // and with parameter false if the synchronization failed.
            commit(true);
        },
        deleterow: function (rowid, commit) {
            // synchronize with the server - send delete command
            // call commit with parameter true if the synchronization with the server is successful 
            // and with parameter false if the synchronization failed.
            commit(true);
        }
    };

    // initialize the input fields.
    $("#firstName").addClass('jqx-input');
    $("#lastName").addClass('jqx-input');
    $("#product").addClass('jqx-input');
    $("#firstName").width(250);
    $("#firstName").height(30);
    $("#lastName").width(250);
    $("#lastName").height(30);
    $("#product").width(250);
    $("#product").height(30);

    if (theme.length > 0) {
        $("#firstName").addClass('jqx-input-' + theme);
        $("#lastName").addClass('jqx-input-' + theme);
        $("#product").addClass('jqx-input-' + theme);
    }

    $("#quantity").jqxNumberInput({ width: 250, height: 30,  decimalDigits: 0, spinButtons: true });
    $("#price").jqxNumberInput({symbol: '$', width: 250, height: 30,  spinButtons: true });

    var dataAdapter = new $.jqx.dataAdapter(source);
    var editrow = -1;

    // initialize jqxGrid
    $("#grid").jqxGrid(
    {
        width: getWidth('Grid'),
        source: dataAdapter,
        pageable: true,
        autoheight: true,
        columns: [
          { text: 'First Name', datafield: 'firstname', width: 200 },
          { text: 'Last Name', datafield: 'lastname', width: 200 },
          { text: 'Product', datafield: 'productname', width: 190 },
          { text: 'Quantity', datafield: 'quantity', width: 90, cellsalign: 'right' },
          { text: 'Price', datafield: 'price', cellsalign: 'right', cellsformat: 'c2' }
        ]
    });

    // create context menu
    var contextMenu = $("#Menu").jqxMenu({ width: 200, autoOpenPopup: false, mode: 'popup'});

    $("#grid").on('contextmenu', function () {
        return false;
    });

    // handle context menu clicks.
    $("#Menu").on('itemclick', function (event) {
        var args = event.args;
        var rowindex = $("#grid").jqxGrid('getselectedrowindex');
        if ($.trim($(args).text()) == "Edit Selected Row") {
            editrow = rowindex;
            var offset = $("#grid").offset();
            $("#popupWindow").jqxWindow({ position: { x: parseInt(offset.left) + 60, y: parseInt(offset.top) + 60} });

            // get the clicked row's data and initialize the input fields.
            var dataRecord = $("#grid").jqxGrid('getrowdata', editrow);
            $("#firstName").val(dataRecord.firstname);
            $("#lastName").val(dataRecord.lastname);
            $("#product").val(dataRecord.productname);
            $("#quantity").jqxNumberInput({ decimal: dataRecord.quantity });
            $("#price").jqxNumberInput({ decimal: dataRecord.price });

            // show the popup window.
            $("#popupWindow").jqxWindow('show');
        }
        else {
            var rowid = $("#grid").jqxGrid('getrowid', rowindex);
            $("#grid").jqxGrid('deleterow', rowid);
        }
    });

    $("#grid").on('rowclick', function (event) {
        if (event.args.rightclick) {
            $("#grid").jqxGrid('selectrow', event.args.rowindex);
            var scrollTop = $(window).scrollTop();
            var scrollLeft = $(window).scrollLeft();
            contextMenu.jqxMenu('open', parseInt(event.args.originalEvent.clientX) + 5 + scrollLeft, parseInt(event.args.originalEvent.clientY) + 5 + scrollTop);

            return false;
        }
    });

    // initialize the popup window and buttons.
    $("#popupWindow").jqxWindow({ width: 350, height: 290, resizable: false,  isModal: true, autoOpen: false, cancelButton: $("#Cancel"), modalOpacity: 0.01 });
    $("#Cancel").jqxButton({ theme: theme });
    $("#Save").jqxButton({ theme: theme });

    // update the edited row when the user clicks the 'Save' button.
    $("#Save").click(function () {
        if (editrow >= 0) {
            var row = { firstname: $("#firstName").val(), lastname: $("#lastName").val(), productname: $("#product").val(),
                quantity: parseInt($("#quantity").jqxNumberInput('decimal')), price: parseFloat($("#price").jqxNumberInput('decimal'))
            };
            var rowid = $("#grid").jqxGrid('getrowid', editrow);
            $('#grid').jqxGrid('updaterow', rowid, row);
            $("#popupWindow").jqxWindow('hide');
        }
    });
});

body.html

<div id="jqxWidget">
    <div id="grid"></div>
    <div style="margin-top: 30px;">
        <div id="cellbegineditevent"></div>
        <div style="margin-top: 10px;" id="cellendeditevent"></div>
   </div>
   <div id="popupWindow">
        <div>Edit</div>
        <div style="overflow: hidden;">
            <table>
                <tbody><tr>
                    <td align="right">First Name:</td>
                    <td align="left"><input id="firstName"></td>
                </tr>
                <tr>
                    <td align="right">Last Name:</td>
                    <td align="left"><input id="lastName"></td>
                </tr>
                <tr>
                    <td align="right">Product:</td>
                    <td align="left"><input id="product"></td>
                </tr>
                <tr>
                    <td align="right">Quantity:</td>
                    <td align="left"><div id="quantity"></div></td>
                </tr>
                <tr>
                    <td align="right">Price:</td>
                    <td align="left"><div id="price"></div></td>
                </tr>
                <tr>
                    <td align="right"></td>
                    <td style="padding-top: 10px;" align="right"><input style="margin-right: 5px;" type="button" id="Save" value="Save"><input id="Cancel" type="button" value="Cancel"></td>
                </tr>
            </tbody></table>
        </div>
   </div>
   <div id="Menu">
    <ul>
        <li>Edit Selected Row</li>
        <li>Delete Selected Row</li>
    </ul>
   </div>
</div>

Learn more

More jQuery Grid demos