【问题标题】:Capture change/click event of drop down in jqGrid捕获 jqGrid 中下拉菜单的更改/单击事件
【发布时间】:2012-11-08 12:16:14
【问题描述】:

我的下拉菜单上的点击事件不会触发。我没有看到警报,并且当我在 Firebug 中添加断点时,它没有到达断点。如果我对它们进行断点,它确实会到达单击和双击事件。

具体来说,当我:

  1. 双击编辑一行
  2. 选择客户下拉菜单并选择其他内容
  3. 移到另一行

然后一行

alert("I changed");

不运行。

我想知道是不是因为当我移动到另一行时,值会被还原(即使我已经注释掉了 restoreRow 方法)

我是否使用正确的事件来捕捉我的下拉值何时发生变化(无需更改焦点)。

$(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 () {

修订的工作代码:

$(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 () {

【问题讨论】:

  • 你能写出你使用哪个版本的jqGrid吗?我看到您使用了从 3.5 版开始的 jqGrid 未使用的 imgpath 选项。 jqGrid 的当前版本是 4.4.1。如果您使用一些旧版本,它可能对您描述的问题非常重要。
  • 版本为 4.4.1。 imgpath 可能是我之前的 hack 之一——它当然什么也没做,我会拿出来清理它。我会说代码是 20% 的理解和 80% 的黑客。像大多数 jqGrid 开发人员一样,代码库很大程度上基于您的建议!

标签: javascript jquery asp.net jqgrid jquery-events


【解决方案1】:

此外,不清楚您为什么同时使用inlineNavondblClickRow 内部手动调用editRow?如果您选择行然后单击导航器中的按钮,则不会调整dataUrl

您描述的主要问题的原因是dataEvents的错误使用。在editoptions 的文档中,您会发现dataEventseditoptions 的属性,例如dataUrl。目前你把dataEvents放在了colModel的错误位置。

我建议您另外阅读the answer,其中描述了如何使用dataUrl,哪些参数取决于当前选定的行。此外,我建议您验证您是否在dataUrl 的响应中设置了Cache-Control(请参阅the answer)。或者,您可以使用here 描述的另一个选项。

【讨论】:

  • 非常好,感谢您的帮助。我将 dataEvents 放在正确的位置,现在我看到了警报!我的目标是实现级联下拉菜单,所以我现在将看看您提供的链接。然而简短的问题:我可以根据选定的下拉列表从 URL 动态填充第二个下拉列表。我见过的所有示例都使用代码更改了相关下拉列表的内容。我已经根据参数从 URL 填充下拉列表 - 我现在需要更改参数并根据选择进行刷新。无论如何,我可能很快会问另一个问题。
  • @ElectricLlama:不客气!目前实现依赖选择的可能性并不多(参见here)。我在答案中包含的链接几乎是您可以做的所有事情。我最近想到了这个问题并发布了the feature request。它简要描述了如何更改 jqGrid 的代码,以便在构建动态 dataUrl 时提供更大的灵活性。
  • 呵呵,我在那个链接的问题中发布了在这个问题之前问同样的事情。我已经检查了几次该帖子。在我看来,一种解决方法是将 FULL 下拉列表加载到某种“本地”记录集或数组中,然后每次都有选择地从中选择......或者这就是你在其他示例中所做的?
  • @ElectricLlama:您也可以在服务器端构建&lt;select&gt; 选项。您只需在 change 事件句柄内手动进行 Ajax 调用并重置 success 句柄内的第二个 &lt;select&gt; 的选项(在您从服务器获得响应之后)。无论如何,必须手动修改依赖选择的选项。 jqGrid 在这里帮不了你。 dataUrl 或依赖选择的更改仅在 next 创建选择时需要。
  • 在上面的代码中,您过去曾帮助我在调用editRow 函数之前 动态设置dataUrl 属性。我知道这会在控件创建之前针对控件设置属性。然后当它被创建时,它使用这个属性来填充控件。有没有办法重新初始化 select 控件的创建,从而让它从(新更改的)dataUrl 重新初始化?
猜你喜欢
  • 2017-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-27
  • 1970-01-01
相关资源
最近更新 更多