gpt4 book ai didi

javascript - jqGrid 级联下拉更改事件不会触发

转载 作者:行者123 更新时间:2023-11-30 18:15:38 25 4
gpt4 key购买 nike

在 Oleg 和许多网站的帮助下,我一直致力于让级联数据绑定(bind)下拉菜单在 jqGrid 中运行

我有三个下拉菜单:客户 > 项目 > 任务。更改客户应使用该客户项目重新加载项目。更改项目应使用该项目任务重新加载任务。

实际上,我已经通过在 Customer 中创建一个更改事件处理程序来让 Project 重新加载该 Customers 任务,该处理程序又针对 URL 调用 getJson,然后将 Project 下拉列表的内容替换为新的选项。效果很好。

然后我将同样的逻辑应用到“项目”下拉列表中,但“项目”事件似乎没有触发。更改项目下拉列表时,我观察到以下内容:

  1. 任务下拉列表没有变化
  2. Task Json controller 事件没有被调用(它意味着在 Project change 事件中被 getJSON 调用)
  3. 在 Firebug 中,在 Network 监视器中,不会出现对 Task Json Controller 事件的​​调用和响应。
  4. 在 Firebug 中它没有命中我在项目更改事件处理程序中设置的断点

然而,Customer 事件处理程序运行完美,并且在我更改 Customer 时按预期执行所有上述 4 点。

我相当确定它不会针对项目下拉列表触发更改事件。

如果我运行网页并编辑和更改项目下拉值作为我的第一个操作,它不会触发项目事件处理程序,所以我认为不是客户事件重置了项目事件处理程序。

那么,有人知道为什么我的客户变更事件被调用而我的项目事件没有被调用吗?

有没有一种方法可以检查 DOM 或其他东西并查看我的事件是否已在运行时附加?这是它的工作方式吗?

我正在使用 jqGrid 4.4.1

我的 jqGrid 是这样设置的:

  • 使用内联编辑
  • 点击选择dbl点击编辑
  • 日期选择器附在日期列上
  • 编辑后,我从隐藏字段中获得了选择数据库键值,但我希望我可以删除它。
  • 我有三个相邻的选择

这是我的 jqGrid 定义

$(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"
// .jqGrid means attach a jqGrid 'thing' to all elements that have ts as their element name (there's only one)
// jqGrid is a thing defined in the jqGrid javascript file
$("#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' },
// Defintion for customer column
{name: 'Customer', index: 'Customer', width: 250, align: 'left', editable: true, edittype: "select",
editoptions: {
// Default URL used to populate drop down when the column goes into edit mode
dataUrl: 'Timesheet/CustomerList',
dataEvents: [
{
// this is the change handler. This is called when the customer is changed
type: 'change',
fn: function (e) {
// get a reference to the project and task drop downs on this same row
var eProject = '#' + $(this).attr("id").replace("_Customer", "_Project");
var eTask = '#' + $(this).attr("id").replace("_Customer", "_Task");
// Call getJSON to get data from a URL and process it with a callback function
$.getJSON(
// the URL to call
'Timesheet/ProjectListJSON',
// the parameter(s) to pass to the URL
{Customer_ID: this.value },
// The callback function. The results of the JSON call are passed into jData
function (jData) {
var selectHtml = ""
// Repopulate the project drop down with the results of the JSON call
$.each(
jData,
function (jdIndex, jdData) {
selectHtml = selectHtml + "<option value='" + jdData.Value + "'>" + jdData.Text + "</option>";
});
// dont use innerHTML as it is not supported properly by IE
// insted use jQuery html to change the select list options
$(eProject).html(selectHtml);
// blank out tasks
$(eTask).html("");
} // END getJSON callback function definition
); // END getJSON function call
} // END change event definition
}] // END dataEvents definition
} // END editoptions list
}, // END Customer jqGrid field definition
// Definition for Project drop down
{name: 'Project', index: 'Project', width: 250, align: 'left', editable: true, edittype: "select",
editoptions: {
dataUrl: 'Timesheet/ProjectList',
dataEvents: [
{
type: 'change',
fn: function (e) {
var eTask = '#' + $(this).attr("id").replace("_Project", "_Task");
$.getJSON(
'Timesheet/TaskListJSON',
{ CustomerProject_ID: this.value },
function (jData) {
var selectHtml = "";
$.each(
jData,
function (jdIndex, jdData) {
selectHtml = selectHtml + "<option value='" + jdData.Value + "'>" + jdData.Text + "</option>";
});
$(eTask).html(selectHtml);
} // END getJSON callback function definition
); // END getJSON function call
} // END change event handler definition
}] // END dataevents definition
} // END editoptions list
}, // END Project jqGrid field definition
{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 () {

固定代码在这里

我将 change 事件处理程序定义从列定义中移到了 dblclick 事件处理程序中。它仍然不完美。我确信每次附加事件处理程序都会产生一些开销,并且当客户发生更改时,它会更新并选择第一个项目但会清除任务。

$(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"
// .jqGrid means attach a jqGrid 'thing' to all elements that have ts as their element name (there's only one)
// jqGrid is a thing defined in the jqGrid javascript file
$("#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' },
// Defintion for customer column
{name: 'Customer', index: 'Customer', width: 250, align: 'left', editable: true, edittype: "select",
editoptions: {
// Default URL used to populate drop down when the column goes into edit mode
dataUrl: 'Timesheet/CustomerList',
dataEvents: [
{
// this is the change handler. This is called when the customer is changed
type: 'change',
fn: function (e) {
// get a reference to the project and task drop downs on this same row
var eProject = '#' + $(this).attr("id").replace("_Customer", "_Project");
var eTask = '#' + $(this).attr("id").replace("_Customer", "_Task");
// Call getJSON to get data from a URL and process it with a callback function
$.getJSON(
// the URL to call
'Timesheet/ProjectListJSON',
// the parameter(s) to pass to the URL
{Customer_ID: this.value },
// The callback function. The results of the JSON call are passed into jData
function (jData) {
var selectHtml = ""
// Repopulate the project drop down with the results of the JSON call
$.each(
jData,
function (jdIndex, jdData) {
selectHtml = selectHtml + "<option value='" + jdData.Value + "'>" + jdData.Text + "</option>";
});
// dont use innerHTML as it is not supported properly by IE
// insted use jQuery html to change the select list options
$(eProject).html(selectHtml);
// clear task list
$(eTask).html("");
} // END getJSON callback function definition
); // END getJSON function call
} // END change event definition
}] // END dataEvents definition
} // END editoptions list
}, // END Customer jqGrid field definition
// Definition for Project drop down
{name: 'Project', index: 'Project', width: 250, align: 'left', editable: true,
edittype: "select", editoptions: { dataUrl: 'Timesheet/ProjectList'}
}, // END Project jqGrid field definition
{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
// By default tasks are limited to the current project
$(this).jqGrid('setColProp', 'Task', { editoptions: { dataUrl: 'Timesheet/TaskList?CustomerProject_ID=' + $(this).jqGrid('getCell', rowid, 'hProject_ID')} });

// By default projects are limited to the current Customer (dataUrl)
// Also attach event handler to autopopulate tasks (dataEvents)
$(this).jqGrid('setColProp', 'Project', {
// editoptions: { dataUrl: 'Timesheet/ProjectList?Customer_ID=' + $(this).jqGrid('getCell', rowid, 'hCustomer_ID')} });
editoptions: {
dataUrl: 'Timesheet/ProjectList?Customer_ID=' + $(this).jqGrid('getCell', rowid, 'hCustomer_ID'),
dataEvents: [
{
type: 'change',
fn: function (e) {
var eTask = '#' + $(this).attr("id").replace("_Project", "_Task");
$.getJSON(
'Timesheet/TaskListJSON',
{ CustomerProject_ID: this.value },
function (jData) {
var selectHtml = "";
$.each(
jData,
function (jdIndex, jdData) {
selectHtml = selectHtml + "<option value='" + jdData.Value + "'>" + jdData.Text + "</option>";
});
$(eTask).html(selectHtml);
} // END getJSON callback function definition
); // END getJSON function call
} // END change event handler definition
}] // END dataevents definition
} // END editoptions list
} // END data to be applied to setColProp
); // END jqGrid setColProp

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

最佳答案

我想您遇到问题的原因是 jQuery.empty 的用法(参见 eTask.empty();eProject.empty(); 行)。如果您检查 jQuery.empty 的描述您会发现以下内容:

To avoid memory leaks, jQuery removes other constructs such as data and event handlers from the child elements before removing the elements themselves.

If you want to remove elements without destroying their data or event handlers (so they can be re-added later), use .detach() instead.

在我看来,在你的情况下,可以只构造字符串,它是所有 <option> 的串联。元素。然后你可以使用jQuery.html将所有旧选项替换为新选项。您不仅可以解决您的主要问题,而且还具有一些性能优势。您应该了解的问题是,如果您更改页面上的某些元素,网络浏览器必须重新计算页面上所有现有元素 的位置或样式。所以如果你调用jQuery.append在循环中,那么每次调用都将至少跟随到 reflow这是膨胀的。所以你应该更好地编写你的程序,这样页面上的更改次数就会减少。如果你构造 innerHTML<select>元素首先作为 HTML 字符串并使用 一次调用 jQuery.html (或仅设置 DOM 元素的 innerHTML 属性)您将获得性能提升。

我在您的程序中看到的另一个问题是初始化“项目”和“任务”中的选择。如果用户开始编辑该行,则选择元素将填充为 dataUrl: 'Timesheet/TaskList'dataUrl: 'Timesheet/ProjectList' .因此,您将拥有所有 项目和任务,而不仅仅是'Customer' 的项目。以及基于 'Customer' 的任务和 'Project'值。我认为您将必须设置 行相关初始值 dataUrl在开始编辑之前。在表单编辑的情况下,您可以在 onInitializeForm 中执行此操作例如回调。如果您使用内联编辑,您应该调用editRow 之前执行相同的操作.

我建议你仔细检查the demo的代码来自 the answer .它不使用 dataUrl但它改变了value属性(property)多次。更改 value在您的情况下,属性将对应于 dataUrl 的设置.

关于javascript - jqGrid 级联下拉更改事件不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13331569/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com