1

The click event on my drop down does not fire. I do not see an alert and when I add a breakpoint in Firebug, it does not reach the breakpoint. It does reach the click and double click events if I breakpoint those.

Specifically, when I:

  1. Double click to edit a line
  2. Pick the Customer Drop Down and pick something else
  3. Move to another line

then the line

alert("I changed");

Does not run.

I wonder if it's because when I move to another line, the value gets reverted (even though I have commented out the restoreRow method)

Am I using the right event to capture when my drop down value changes (without having to change focus).

$(document).ready(
    function () {
        // This is executed as soon as the DOM is loaded and before the page contents are loaded
        var lastsel;
        // $ is short for JQuery which is in turn a super overloaded function that does lots of things.
        // # means select an element by its ID name, i.e. below we have <table id="ts"
        $("#ts").jqGrid({
            //=============
            // Grid Setup
            url: 'Timesheet/GridData/',
            datatype: 'json',
            mtype: 'GET',
            pager: $('#pager'),
            rowNum: 30,
            rowList: [10, 20, 30, 40, 80],
            viewrecords: true,
            imgpath: '/Content/themes/base/images',
            caption: 'Timesheet',
            height: 450,
            // Column definition
            colNames: ['hCustomer_ID', 'hProject_ID', 'hTask_ID', 'Date', 'Customer', 'Project', 'Task', 'Description', 'Hours', '$'],
            colModel: [
              { name: 'hCustomer_ID', index: 'hCustomer_ID', editable: false, hidden: true },
              { name: 'hProject_ID', index: 'hProject_ID', editable: false, hidden: true },
              { name: 'hTask_ID', index: 'hTask_ID', editable: false, hidden: true },
              { name: 'tsdate', index: 'tsdate', width: 80, editable: true, datefmt: 'yyyy-mm-dd' },
              { name: 'Customer', index: 'Customer', width: 250, align: 'left', editable: true, edittype: "select",
                  editoptions: { dataUrl: 'Timesheet/CustomerList' },
                  dataEvents: [
                    {
                        type: 'click',
                        fn: function (e) {
                            alert("I changed");
                        }
                    }]
              },
              { name: 'Project', index: 'Project', width: 250, align: 'left', editable: true, edittype: "select", editoptions: { dataUrl: 'Timesheet/ProjectList'} },
              { name: 'Task', index: 'Task', width: 250, align: 'left', editable: true, edittype: "select", editoptions: { dataUrl: 'Timesheet/TaskList'} },
              { name: 'Desc', index: 'Desc', width: 300, align: 'left', editable: true },
              { name: 'Hours', index: 'Hours', width: 50, align: 'left', editable: true },
              { name: 'Charge', index: 'Charge', edittype: 'checkbox', width: 18, align: 'center', editoptions: { value: "0:1" }, formatter: "checkbox", formatoptions: { disabled: false }, editable: true }
            ],
            //=============
            // Grid Events
            // when selecting, undo anything else
            onSelectRow: function (rowid, iRow, iCol, e) {
                if (rowid && rowid !== lastsel) {
                    // $(this).jqGrid('restoreRow', lastsel);
                    lastsel = rowid;
                }
            },
            // double click to edit
            ondblClickRow: function (rowid, iRow, iCol, e) {
                // browser independent stuff
                if (!e) e = window.event;
                var element = e.target || e.srcElement

                // When editing, change the drop down datasources to filter on the current parent
                $(this).jqGrid('setColProp', 'Project', { editoptions: { dataUrl: 'Timesheet/ProjectList?Customer_ID=' + $(this).jqGrid('getCell', rowid, 'hCustomer_ID')} });
                $(this).jqGrid('setColProp', 'Task', { editoptions: { dataUrl: 'Timesheet/TaskList?CustomerProject_ID=' + $(this).jqGrid('getCell', rowid, 'hProject_ID')} });

                // Go into edit mode (automatically moves focus to first field)
                // Use setTimout to apply the focus and datepicker after the first field gets the focus
                $(this).jqGrid(
                    'editRow',
                    rowid,
                    {
                        keys: true,
                        oneditfunc: function (rowId) {
                            setTimeout(function () {
                                $("input, select", element).focus();
                                $("#" + rowId + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' });
                            }, 50);
                        }
                    }
                );

            },  // end ondblClickRow event handler
            postData:
                {
                    startDate: function () { return $('#startDate').val(); }
                }
        }); // END jQuery("#ts").jqGrid

        $("#ts").jqGrid('navGrid', '#pager', { view: false, edit: false, add: false, del: false, search: false });
        $("#ts").jqGrid('inlineNav', "#pager");

    });                  // END jQuery(document).ready(function () {

REVISED WORKING CODE:

$(document).ready(
    function () {
        // This is executed as soon as the DOM is loaded and before the page contents are loaded
        var lastsel;
        // $ is short for JQuery which is in turn a super overloaded function that does lots of things.
        // # means select an element by its ID name, i.e. below we have <table id="ts"
        $("#ts").jqGrid({
            //=============
            // Grid Setup
            url: 'Timesheet/GridData/',
            datatype: 'json',
            mtype: 'GET',
            pager: $('#pager'),
            rowNum: 30,
            rowList: [10, 20, 30, 40, 80],
            viewrecords: true,
            caption: 'Timesheet',
            height: 450,
            // Column definition
            colNames: ['hCustomer_ID', 'hProject_ID', 'hTask_ID', 'Date', 'Customer', 'Project', 'Task', 'Description', 'Hours', '$'],
            colModel: [
              { name: 'hCustomer_ID', index: 'hCustomer_ID', editable: false, hidden: true },
              { name: 'hProject_ID', index: 'hProject_ID', editable: false, hidden: true },
              { name: 'hTask_ID', index: 'hTask_ID', editable: false, hidden: true },
              { name: 'tsdate', index: 'tsdate', width: 80, editable: true, datefmt: 'yyyy-mm-dd' },
              { name: 'Customer', index: 'Customer', width: 250, align: 'left', editable: true, edittype: "select",
                  editoptions: {
                      dataUrl: 'Timesheet/CustomerList',
                      dataEvents: [
                      {
                        type: 'change',
                        fn: function (e) {
                            alert("I changed");
                            }
                      }]
                  }
              },
              { name: 'Project', index: 'Project', width: 250, align: 'left', editable: true, edittype: "select", editoptions: { dataUrl: 'Timesheet/ProjectList'} },
              { name: 'Task', index: 'Task', width: 250, align: 'left', editable: true, edittype: "select", editoptions: { dataUrl: 'Timesheet/TaskList'} },
              { name: 'Desc', index: 'Desc', width: 300, align: 'left', editable: true },
              { name: 'Hours', index: 'Hours', width: 50, align: 'left', editable: true },
              { name: 'Charge', index: 'Charge', edittype: 'checkbox', width: 18, align: 'center', editoptions: { value: "0:1" }, formatter: "checkbox", formatoptions: { disabled: false }, editable: true }
            ],
            //=============
            // Grid Events
            // when selecting, undo anything else
            onSelectRow: function (rowid, iRow, iCol, e) {
                if (rowid && rowid !== lastsel) {
                    // $(this).jqGrid('restoreRow', lastsel);
                    lastsel = rowid;
                }
            },
            // double click to edit
            ondblClickRow: function (rowid, iRow, iCol, e) {
                // browser independent stuff
                if (!e) e = window.event;
                var element = e.target || e.srcElement

                // When editing, change the drop down datasources to filter on the current parent
                $(this).jqGrid('setColProp', 'Project', { editoptions: { dataUrl: 'Timesheet/ProjectList?Customer_ID=' + $(this).jqGrid('getCell', rowid, 'hCustomer_ID')} });
                $(this).jqGrid('setColProp', 'Task', { editoptions: { dataUrl: 'Timesheet/TaskList?CustomerProject_ID=' + $(this).jqGrid('getCell', rowid, 'hProject_ID')} });

                // Go into edit mode (automatically moves focus to first field)
                // Use setTimout to apply the focus and datepicker after the first field gets the focus
                $(this).jqGrid(
                    'editRow',
                    rowid,
                    {
                        keys: true,
                        oneditfunc: function (rowId) {
                            setTimeout(function () {
                                $("input, select", element).focus();
                                $("#" + rowId + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' });
                            }, 50);
                        }
                    }
                );

            },  // end ondblClickRow event handler
            postData:
                {
                    startDate: function () { return $('#startDate').val(); }
                }
        }); // END jQuery("#ts").jqGrid

        $("#ts").jqGrid('navGrid', '#pager', { view: false, edit: false, add: false, del: false, search: false });
        $("#ts").jqGrid('inlineNav', "#pager");

    });                   // END jQuery(document).ready(function () {
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Nick.Mc
  • 18,304
  • 6
  • 61
  • 91
  • Could you write which version of jqGrid you use? I see that you use `imgpath` option which not used by jqGrid starting with version 3.5. The current version of jqGrid is 4.4.1. If you use some old version it could be very important for the problem which you describe. – Oleg Nov 08 '12 at 12:29
  • It is version 4.4.1. imgpath is probably one of my prior hacks - it certainly doesn't do anything and I'll take it out to clean it up. I would say the code is 20% understanding and 80% hacks. Like most jqGrid developers, the codebase is largely based off your advice! – Nick.Mc Nov 09 '12 at 04:00

1 Answers1

1

Additionally it's unclear why you use both inlineNav and manual call of editRow inside of ondblClickRow? If you would select row and then click on the button from the navigator the dataUrl will not be adjusted.

The reason of the main problem which you describe is wrong usage of dataEvents. In the documentation of editoptions you will find the dataEvents is the property of editoptions like dataUrl for example. Currently you placed dataEvents on the wrong place in colModel.

I would recommend you additionally to read the answer which describe how you can use dataUrl which parameters depend on the current selected row. Additionally I would recommend you to verify that you set Cache-Control in the response of dataUrl (see the answer). Alternatively you can use anothe option described here.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Excellent, thanks for your help. I put the dataEvents in the correct spot and now I see an alert! My objective is to implement cascading drop downs so I will now take a look at the links you have provided. However short question: Can I dynamically populate a second drop down from a URL based on a selected drop down. All of the examples I have seen change the contents of the dependent drop down using code. I have drop down's populating from URL based on parameters - I now need to change the parameter and refresh based on a selection. Anyway I will probably ask another question shortly. – Nick.Mc Nov 09 '12 at 09:28
  • @ElectricLlama: You are welcome! Currently there are not so many possibilities to implement dependent selects (see [here](http://stackoverflow.com/a/4480184/315935)). The links which I included in my answer are almost all what you can do. I though about the problem recently and posted [the feature request](http://www.trirand.com/blog/?page_id=393/feature-request/support-dataurl-as-function/#p27702). It described shortly how the code of jqGrid can be changed to allow much more flexibility in building of dynamic `dataUrl`. – Oleg Nov 09 '12 at 10:05
  • hehe I posted in that linked question asking that same thing right before this one. I have checked that post out a few times. It seems to me that a workaround would be to load the FULL dropdown to some kind of 'local' recordset or array then selectively pick from it each time... or is that what you're doing in the other examples? – Nick.Mc Nov 09 '12 at 11:31
  • @ElectricLlama: You can build `` inside of `success` handle (after you get response from the server). In any way one have to modify the options of dependent select **manually**. jqGrid can't help you here. The changing of `dataUrl` or dependent select are needed only for the *next* creation of the select. – Oleg Nov 09 '12 at 11:39
  • In the code above, you have in the past assisted me to dynamically set the `dataUrl` property just _prior_ to calling the `editRow` function. I understand this sets up the propery against the control right before it is created. Then when it is created it uses this property to populate the control. Is there any way to reinitialise the creation of the `select` control and therefore get it to reinitialise from a (newly changed) dataUrl? – Nick.Mc Nov 09 '12 at 12:07
  • I think understand what you are saying: you can either use the dataUrl property to tell it what to load at creation time _or_ you can just do an Ajax call inside code to extract the new list from a URL and populate the select manuallty. So you can make a selection in drop down A and have it immediately affect drop down B based of the database, but you need to code it manually rather than using dataUrl – Nick.Mc Nov 09 '12 at 12:14
  • @ElectricLlama: `dataUrl` will be used by jqGrid at the moment of creating of the corresponding select. It make Ajax call and fill the option of the select. So to see correct select **at the initialization time** you need have correct `dataUrl` value. To be able to **refresh** dependent select you will have to do almost the same what jqGrid do for you at the initialization time. I thought already to suggest to implement "Refresh" method for select which you could just call, but till now I didn't find time for it. – Oleg Nov 09 '12 at 12:40
  • Thanks for that, it gives me an avenue to research. I would happily take a crack at enhancing the library but I am at best a javascript amateur. Good evening to you and thanks for your help. – Nick.Mc Nov 09 '12 at 12:48