jQWidgets Forums

jQuery UI Widgets Forums Navigation Menu, Context Menu context menu on jqxGrid: itemclick not working

Tagged: 

This topic contains 11 replies, has 2 voices, and was last updated by  Peter Stoev 11 years, 5 months ago.

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author

  • JohnSeymour
    Participant

    Hi,

    I tried to integrate a context menu into my jqxGrid-component, currently following some basic tutorials and forum posts.

    I took the context menu from here: Context menu example

    And the itemclick listener from here: http://www.jqwidgets.com/community/topic/jqxmenu-basics-action-handler/

    So all in all this is what I added to my working jqxGrid (I will strip the li-tags for the menu, they are completely copied from above example):

    
    var contextMenu = $("#jqxContextMenu").jqxMenu({ 
        width: '120px', height: '140px', 
        autoOpenPopup: false, mode: 'popup', 
        theme: theme 
    });
    // open the context menu when the user presses the mouse right button.
    $("#jqxWidget").on('mousedown', function (event) {
        var rightClick = isRightClick(event);
        if (rightClick) {
            var scrollTop = $(window).scrollTop();
            var scrollLeft = $(window).scrollLeft();
            contextMenu.jqxMenu('open', parseInt(event.clientX) + 5 + scrollLeft, parseInt(event.clientY) + 5 + scrollTop);
            return false;
        }
    });
    // disable the default browser's context menu.
    $(document).on('contextmenu', function (e) {
        return false;
    });
    function isRightClick(event) {
        var rightclick;
        if (!event) var event = window.event;
        if (event.which) rightclick = (event.which == 3);
        else if (event.button) rightclick = (event.button == 2);
        return rightclick;
    }
    $('#jqxContextMenu').bind('itemclick', function (event) {
        var LI_element = event.args;
        var menuitemText = $(args).text();
        console.log(menuitemText);
    });

    IDs and everything is valid, I see the context menu when I right click my grid. But when I click on a menu item, the corresponding item is not logged into the console. There is no warning, error whatsoever.

    Any idea what I am doing wrong?

    Regards,
    John


    Peter Stoev
    Keymaster

    Hi John,

    There’s already a working sample with Context Menu integration with jqxGrid: http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxgrid/contextmenu.htm?arctic

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com


    JohnSeymour
    Participant

    Besides the ‘itemclick’ handler being more complex, thats more or less identical to what I posted. Meanwhile I tried that too, after stripping all popup-window related code the method is not getting called… I did test it now too with the popup menu code from this example but the method is not called either.


    Peter Stoev
    Keymaster

    Hi John,

    I do not know what could be the issue on your side. As you can see on our sample, the “itemclick” event works as expected so I suggest you to check whether all the ID/CSS classes used in the jQuery Selectors in your code are correct.

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com


    JohnSeymour
    Participant

    Sorry, but I can’t solve it.

    This is the HTML to define my context menu:

          <div id='jqxContextMenu'>
            <ul>
                <li>Edit Selected Row</li>
                <li>Delete Selected Row</li>
            </ul>
           </div>

    Meanwhile through testing I defined three handlers, two for events defined by the jqxMenu api and a third just to try if a standard jQuery handler might work:

    			$('#jqxContextMenu').on('initialized', function () {
    				console.log("call initialized");
    			});
    			$('#jqxContextMenu').on('itemclick', function (event) {
    				console.log("call itemclick");
    			});
    			$('#jqxContextMenu').on('click', function (event) {
    				console.log("call click");
    			});

    None of the handlers ever gets called. Other handlers like

    			$("#jqxWidget").on('mousedown', function (event) {
    				console.log("call mousedown");
    				// open context menu
    			});

    are executed and the context menu shows up – so jQuery in general works. But I can’t get the itemclick handler to execute. There is no error message in the console.

    Every handler is declared in

    $(document).ready()

    and the line where the handler is added gets executed.


    Peter Stoev
    Keymaster

    Hi John,

    Here’s a working demo:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta name="keywords" content="jQuery Menu, Main Menu, Context Menu, Vertical Menu, Popup Menu, Menu, jqxMenu" /> 
        <meta name="description" content="This demo demonstrates how to use the jqxMenu widget as a Context Menu. In order to display the jqxMenu as Context Menu, you need to set the 'mode' property to 'popup'. "/>
        <title id='Description'>
        This demo demonstrates how to use the jqxMenu widget as a Context Menu. In order to display the jqxMenu as Context Menu, you need to set the 'mode' property to 'popup'. 
        </title>
        <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" />
        <script type="text/javascript" src="../../scripts/jquery-1.10.2.min.js"></script>
        <script type="text/javascript" src="../../scripts/demos.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxmenu.js"></script>
    </head>
    <body>
        <div id='content'>
            <script type="text/javascript">
                $(document).ready(function () {
                    // Create a jqxMenu
                    var contextMenu = $("#jqxMenu").jqxMenu({ width: '120px', height: '140px', autoOpenPopup: false, mode: 'popup'});
                    // open the context menu when the user presses the mouse right button.
                    $("#jqxWidget").on('mousedown', function (event) {
                        var rightClick = isRightClick(event);
                        if (rightClick) {
                            var scrollTop = $(window).scrollTop();
                            var scrollLeft = $(window).scrollLeft();
    
                            contextMenu.jqxMenu('open', parseInt(event.clientX) + 5 + scrollLeft, parseInt(event.clientY) + 5 + scrollTop);
                            return false;
                        }
                    });
    
                    // disable the default browser's context menu.
                    $(document).on('contextmenu', function (e) {
                        return false;
                    });
    
                    function isRightClick(event) {
                        var rightclick;
                        if (!event) var event = window.event;
                        if (event.which) rightclick = (event.which == 3);
                        else if (event.button) rightclick = (event.button == 2);
                        return rightclick;
                    }
    
                    $("#jqxMenu").on('itemclick', function () {
                        alert('ItemClick is fired');
                    });
                });
            </script>
            <div id='jqxWidget' style='vertical-align: middle; text-align: center; background: #eee;
                height: 400px; width: 400px;'>
                <div id='jqxMenu'>
                    <ul>
                        <li><a href="#">Home</a></li>
                        <li>About Us
                            <ul>
                                <li><a href="#">History</a></li>
                                <li><a href="#">Our Vision</a></li>
                                <li><a href="#">The Team</a>
                                    <ul>
                                        <li><a href="#">Brigita</a></li>
                                        <li><a href="#">John</a></li>
                                        <li><a href="#">Michael</a></li>
                                        <li><a href="#">Peter</a></li>
                                        <li><a href="#">Sarah</a></li>
                                    </ul>
                                </li>
                                <li><a href="#">Clients</a></li>
                                <li><a href="#">Testimonials</a></li>
                                <li><a href="#">Press</a></li>
                                <li><a href="#">FAQs</a></li>
                            </ul>
                        </li>
                        <li>Services
                            <ul>
                                <li><a href="#">Product Development</a></li>
                                <li><a href="#">Delivery</a></li>
                                <li><a href="#">Shop Online</a></li>
                                <li><a href="#">Support</a></li>
                                <li><a href="#">Training & Consulting</a></li>
                            </ul>
                        </li>
                        <li>Products
                            <ul>
                                <li><a href="#">New</a>
                                    <ul>
                                        <li><a href="#">Corporate Use</a></li>
                                        <li><a href="#">Private Use</a></li>
                                    </ul>
                                </li>
                                <li><a href="#">Used</a>
                                    <ul>
                                        <li><a href="#">Corporate Use</a></li>
                                        <li><a href="#">Private Use</a></li>
                                    </ul>
                                </li>
                                <li><a href="#">Featured</a></li>
                                <li><a href="#">Top Rated</a></li>
                                <li><a href="#">Prices</a></li>
                            </ul>
                        </li>
                        <li><a href="#">Contact Us</a>
                            <ul>
                                <li><a href="#">Enquiry Form</a></li>
                                <li><a href="#">Map & Driving Directions</a></li>
                                <li><a href="#">Your Feedback</a></li>
                            </ul>
                        </li>
                    </ul>
                </div>
                <span style='font-size: 14px; position: relative; top: 180px; font-family: Verdana Arial;'>
                    Right-Click here to Open the Menu </span>
            </div>
        </div>
    </body>
    </html>
    

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com


    JohnSeymour
    Participant

    Hi Peter,

    thanks for your patience.

    Starting from your working example I backtracked until the error occured again. And indeed I was looking at the wrong end for the whole time: Not the context menu causes the failure but the grid!

    When I start my application and the grid is empty, everything works. As soon as I fill the grid with data, the handler ceases to work.

    This is the code I use for initializing the grid:

    var dataAdapter = new $.jqx.dataAdapter(myData);
    $("#jqxgrid").jqxGrid({
      width : "99%",
      autoheight: true,
        				
      source : dataAdapter,
      theme : "smoothness",
      altrows: true,
      columnsresize: true,
      selectionmode: 'multiplecellsadvanced',
        				
      editable: true,
      editMode: 'dblclick',
        				
      filterable: true,
      sortable : true,
      showsortcolumnbackground: true,
        				
      columns: [
        { text: 'Col1', datafield: 'Col1', editable: false },
        { text: 'Col2', datafield: 'Col2' },
        { text: 'Col3', datafield: 'Col3' }
      ]
    });
    $("#jqxgrid").on('cellendedit', function(event) {
      // write back new value
    });

    myData is a JavaScript array that gets changed according to the program state. Changes are propageted to the grid in the following way:

    myData.localdata = mySomewhereElseBuiltNewDataArray;
    $('#jqxgrid').jqxGrid('updatebounddata', 'cells');

    And as soon as this code is executed for the first time, the grid displays the new data (so the array seems to be correct), the context menu appears, but the itemclick-handler stops working.

    Could you maybe have a last look at this?

    The HTML code I use looks like this:

    <div id='jqxWidget' style="font-size: 13px; font-family: Verdana;">
      <div id="jqxgrid"></div>
      <div id='jqxMenu'>
        <ul>
          <li><a href="#">Home</a></li>
        </ul>
      </div>
    </div>

    Regards,
    John


    Peter Stoev
    Keymaster

    Hi John,

    Please, look at the Context Menu demo of jqxGrid – http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxgrid/contextmenu.htm?arctic. Right-Click to Open the Context Menu. On “itemclick”, a row is edited or deleted depending on the clicked Context Menu item.

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com


    JohnSeymour
    Participant

    This does not explain why a working handler stops working once the data of the table has been updated.


    Peter Stoev
    Keymaster

    Hi John,

    The provided code in your post does not have any event handlers about jqxMenu.

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com


    JohnSeymour
    Participant

    It is the one from your example above:

    $("#jqxMenu").on('itemclick', function () {
      alert('ItemClick is fired');
    });

    I took your example and simplified the context menu (only one item remaining). I removed the <span>-tag. I added the grid with the code provided above.
    The context menu shows up and works, when the grid is initially empty (myData.localdata is an empty array). Then myData.localdata changes and the grid is updated to the new values. The context menu still shows up but the itemclick-handler is not triggered anymore.


    Peter Stoev
    Keymaster

    Hi John,

    Ok, here’s the same Context Menu sample with Grid Reloading.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title id='Description'>Right-Click on a jqxGrid Row to open a Context Menu.</title>
        <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" />
        <script type="text/javascript" src="../../scripts/jquery-1.10.2.min.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script> 
        <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxmenu.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.pager.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxgrid.selection.js"></script> 
        <script type="text/javascript" src="../../jqwidgets/jqxnumberinput.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxwindow.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script>
        <script type="text/javascript" src="../../jqwidgets/jqxdropdownlist.js"></script>
        <script type="text/javascript" src="../../scripts/demos.js"></script>
        <script type="text/javascript" src="generatedata.js"></script>
        <script type="text/javascript">
            $(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(150);
                $("#firstName").height(23);
                $("#lastName").width(150);
                $("#lastName").height(23);
                $("#product").width(150);
                $("#product").height(23);
    
                if (theme.length > 0) {
                    $("#firstName").addClass('jqx-input-' + theme);
                    $("#lastName").addClass('jqx-input-' + theme);
                    $("#product").addClass('jqx-input-' + theme);
                }
    
                $("#quantity").jqxNumberInput({ width: 150, height: 23,  decimalDigits: 0, spinButtons: true });
                $("#price").jqxNumberInput({symbol: '$', width: 150, height: 23,  spinButtons: true });
    
                var dataAdapter = new $.jqx.dataAdapter(source);
                var editrow = -1;
    
                // initialize jqxGrid
                $("#jqxgrid").jqxGrid(
                {
                    width: 670,
                    source: dataAdapter,
                    pageable: true,
                    autoheight: true,
                    columns: [
                      { text: 'First Name', datafield: 'firstname', width: 100 },
                      { text: 'Last Name', datafield: 'lastname', width: 100 },
                      { 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, height: 58, autoOpenPopup: false, mode: 'popup'});
    
                $("#jqxgrid").on('contextmenu', function () {
                    return false;
                });
    
                // handle context menu clicks.
                $("#Menu").on('itemclick', function (event) {
                    var args = event.args;
                    var rowindex = $("#jqxgrid").jqxGrid('getselectedrowindex');
                    if ($.trim($(args).text()) == "Edit Selected Row") {
                        editrow = rowindex;
                        var offset = $("#jqxgrid").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 = $("#jqxgrid").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 = $("#jqxgrid").jqxGrid('getrowid', rowindex);
                        $("#jqxgrid").jqxGrid('deleterow', rowid);
                    }
                });
    
                $("#jqxgrid").on('rowclick', function (event) {
                    if (event.args.rightclick) {
                        $("#jqxgrid").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: 250, 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 = $("#jqxgrid").jqxGrid('getrowid', editrow);
                        $('#jqxgrid').jqxGrid('updaterow', rowid, row);
                        $("#popupWindow").jqxWindow('hide');
                    }
                });
    
                $("#reloadGrid").click(function () {
                    $("#jqxgrid").jqxGrid('updatebounddata', 'cells');
                });
            });
        </script>
    </head>
    <body class='default'>
        <button id="reloadGrid">Reload Grid</button>
        <div id='jqxWidget'>
            <div id="jqxgrid"></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>
                        <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>
                    </table>
                </div>
           </div>
           <div id='Menu'>
            <ul>
                <li>Edit Selected Row</li>
                <li>Delete Selected Row</li>
            </ul>
           </div>
        </div>
    </body>
    </html>
    

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com

Viewing 12 posts - 1 through 12 (of 12 total)

You must be logged in to reply to this topic.