将新行插入网格会导致重复行
Inserting new row into grid causes a duplicate row
我有一个网格,其中第一行始终是一个空行,您可以在其中 select 来自多列组合框的姓氏,一旦您 select 找到那个人,它就会插入该记录到网格中,然后它再次重新添加一个空行,您可以继续向网格中添加记录。
我遇到的一个大问题是,当我从组合框中 select 一个姓氏时,它会添加该记录,但随后会添加一个新行(如预期的那样),但该行包含新添加的记录新空行中的姓氏...
这是添加新记录之前的屏幕截图
这是我添加新记录后的截图
有谁知道如何解决这个问题以及它的原因是什么?
function AddNewRow() {
let grid = $("#GridList").data("kendoGrid");
grid.dataSource.insert(0, {
CustomerID: null,
FirstName: "",
LastName: "",
Address: "",
City: "",
Zip: ""
});
}
var junkData = [{
"FirstName": "Ben",
"LastName": "abc",
ID: 1
},
{
"FirstName": "Bob",
"LastName": "def",
ID: 2
},
{
"FirstName": "Joe",
"LastName": "ghi",
ID: 3
},
{
"FirstName": "Clarice",
"LastName": "jkl",
ID: 4
},
];
function LNameEditor(container, options) {
let combobox = $('<input data-text-field="LastName" data-value-field="LastName" data-bind="value:' + options.field + '" />')
.appendTo(container)
.kendoMultiColumnComboBox({
dataTextField: "LastName",
height: 300,
columns: [{
field: "LastName",
title: "Last Name",
width: 100
}],
filter: "startswith",
filterFields: ["LastName"],
dataSource: {
data: junkData
},
change: function(e) {
let items = e.sender._data()[0];
let grid = $("#GridList").data("kendoGrid");
grid.dataSource.insert(1, {
CustomerID: items.ID,
FirstName: items.FirstName,
LastName: items.LastName,
Address: items.Address,
City: items.City,
Zip: items.Zip,
});
},
select: function(e) {}
});
}
var readonlyEditor = function(container, options) {
let gridWidget = $("#GridList").data("kendoGrid");
gridWidget.closeCell();
};
var gridData = [{
"CustomerID": 3,
"FirstName": "The Skipper",
"LastName": "Gilligan",
"Address": "1 Main St.",
"City": "Toledo",
"Zip": "123456"
},
{
"CustomerID": 4,
"FirstName": "Archie Bunker",
"LastName": "Edith Bunker",
"Address": "2 South St.",
"City": "Memphis",
}
];
function LoadGrid() {
$("#GridList").kendoGrid({
dataSource: {
data: gridData
},
schema: {
model: {
fields: {
CustomerID: {
type: "number",
editable: false
},
CustomerFirstName: {
type: "string"
},
CustomerLastName: {
type: "string"
},
CustomerAddress1: {
type: "string"
},
City: {
type: "string"
},
Zip: {
type: "string"
}
},
}
},
filterable: {
mode: "row"
},
columns: [{
title: "<input id='checkAll', type='checkbox', class='check-box' />",
template: "<input name='Selected' class='checkbox' type='checkbox'>",
width: "30px"
},
{
field: "CustomerID",
title: "CustomerID",
hidden: false,
headerAttributes: {
"class": "wrap-header"
},
editor: readonlyEditor
},
{
field: "LastName",
title: "Last Name",
filterable: {
cell: {
showOperators: false,
operator: "contains"
}
},
editor: LNameEditor,
template: "#=LastName #"
},
{
field: "FirstName",
title: "Name",
filterable: {
cell: {
showOperators: false,
operator: "contains"
}
},
editor: readonlyEditor
},
{
field: "Address",
title: "Address",
filterable: {
cell: {
showOperators: false,
operator: "contains"
}
},
editor: readonlyEditor
},
{
field: "City",
title: "City",
filterable: {
cell: {
showOperators: false,
operator: "contains"
}
},
editor: readonlyEditor
},
{
field: "Zip",
title: "Zip",
filterable: {
cell: {
showOperators: false,
operator: "contains"
}
},
editor: readonlyEditor
}
],
editable: true,
scrollable: true,
sortable: true,
pageable: false,
selectable: "row",
change: function(e) {
// Function call goes here
var detailRow = this.dataItem(this.select());
var optionID = detailRow.get("CustomerID")
},
height: 400
});
AddNewRow();
}
$(document).ready(function() {
LoadGrid();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.1.220/js/kendo.all.min.js"></script>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.common.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.rtl.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.silver.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.mobile.all.min.css" />
<div id="MyDiv">
<div id="GridList" tabindex="-1"></div>
</div>
这里有2个问题:
- 你不是 clearing/resetting "empty" 行,但我认为你认为你是。
在 ComboBox 的更改事件中,您所做的只是在索引 1 处添加一个新行,仅此而已……您将单独保留第 0 行,其中包括将 LastName 设置为所选的任何内容。
您实际上需要重置第 0 行。
这可以通过删除当前行 0 并将其替换为 "clean" 行 0 来完成。您可以使用 AddNewRow() 助手来执行此操作。
- 您实际上并没有从组合框中选择的项目中选择数据。
在 ComboBox 更改事件中,您只是从 ComboBox 的数据源中获取第一个项目,而不是所选项目。
您确实想要所选项目而不是项目 0。
如果将更改事件更新为类似这样的内容,它应该会更好地工作:
change: function(e) {
// THIS IS NOT THE DATA YOU WANT.
// e.sender is the ComboBox so this will always be "abc"(index 0 of the ComboBox dataSource) rather than the selected item.
// let items = e.sender._data()[0];
let items = e.sender._data()[e.sender.selectedIndex];
let grid = $("#GridList").data("kendoGrid");
grid.dataSource.insert(1, {
CustomerID: items.ID,
FirstName: items.FirstName,
LastName: items.LastName,
Address: items.Address,
City: items.City,
Zip: items.Zip,
});
// Need to "clear" the "empty" row, which is always row 0.
// We can do this by removing and re-adding the row(among other ways).
let dataItem = grid.dataSource.at(0);
grid.dataSource.remove(dataItem);
AddNewRow();
}
我有一个网格,其中第一行始终是一个空行,您可以在其中 select 来自多列组合框的姓氏,一旦您 select 找到那个人,它就会插入该记录到网格中,然后它再次重新添加一个空行,您可以继续向网格中添加记录。
我遇到的一个大问题是,当我从组合框中 select 一个姓氏时,它会添加该记录,但随后会添加一个新行(如预期的那样),但该行包含新添加的记录新空行中的姓氏...
这是添加新记录之前的屏幕截图
这是我添加新记录后的截图
有谁知道如何解决这个问题以及它的原因是什么?
function AddNewRow() {
let grid = $("#GridList").data("kendoGrid");
grid.dataSource.insert(0, {
CustomerID: null,
FirstName: "",
LastName: "",
Address: "",
City: "",
Zip: ""
});
}
var junkData = [{
"FirstName": "Ben",
"LastName": "abc",
ID: 1
},
{
"FirstName": "Bob",
"LastName": "def",
ID: 2
},
{
"FirstName": "Joe",
"LastName": "ghi",
ID: 3
},
{
"FirstName": "Clarice",
"LastName": "jkl",
ID: 4
},
];
function LNameEditor(container, options) {
let combobox = $('<input data-text-field="LastName" data-value-field="LastName" data-bind="value:' + options.field + '" />')
.appendTo(container)
.kendoMultiColumnComboBox({
dataTextField: "LastName",
height: 300,
columns: [{
field: "LastName",
title: "Last Name",
width: 100
}],
filter: "startswith",
filterFields: ["LastName"],
dataSource: {
data: junkData
},
change: function(e) {
let items = e.sender._data()[0];
let grid = $("#GridList").data("kendoGrid");
grid.dataSource.insert(1, {
CustomerID: items.ID,
FirstName: items.FirstName,
LastName: items.LastName,
Address: items.Address,
City: items.City,
Zip: items.Zip,
});
},
select: function(e) {}
});
}
var readonlyEditor = function(container, options) {
let gridWidget = $("#GridList").data("kendoGrid");
gridWidget.closeCell();
};
var gridData = [{
"CustomerID": 3,
"FirstName": "The Skipper",
"LastName": "Gilligan",
"Address": "1 Main St.",
"City": "Toledo",
"Zip": "123456"
},
{
"CustomerID": 4,
"FirstName": "Archie Bunker",
"LastName": "Edith Bunker",
"Address": "2 South St.",
"City": "Memphis",
}
];
function LoadGrid() {
$("#GridList").kendoGrid({
dataSource: {
data: gridData
},
schema: {
model: {
fields: {
CustomerID: {
type: "number",
editable: false
},
CustomerFirstName: {
type: "string"
},
CustomerLastName: {
type: "string"
},
CustomerAddress1: {
type: "string"
},
City: {
type: "string"
},
Zip: {
type: "string"
}
},
}
},
filterable: {
mode: "row"
},
columns: [{
title: "<input id='checkAll', type='checkbox', class='check-box' />",
template: "<input name='Selected' class='checkbox' type='checkbox'>",
width: "30px"
},
{
field: "CustomerID",
title: "CustomerID",
hidden: false,
headerAttributes: {
"class": "wrap-header"
},
editor: readonlyEditor
},
{
field: "LastName",
title: "Last Name",
filterable: {
cell: {
showOperators: false,
operator: "contains"
}
},
editor: LNameEditor,
template: "#=LastName #"
},
{
field: "FirstName",
title: "Name",
filterable: {
cell: {
showOperators: false,
operator: "contains"
}
},
editor: readonlyEditor
},
{
field: "Address",
title: "Address",
filterable: {
cell: {
showOperators: false,
operator: "contains"
}
},
editor: readonlyEditor
},
{
field: "City",
title: "City",
filterable: {
cell: {
showOperators: false,
operator: "contains"
}
},
editor: readonlyEditor
},
{
field: "Zip",
title: "Zip",
filterable: {
cell: {
showOperators: false,
operator: "contains"
}
},
editor: readonlyEditor
}
],
editable: true,
scrollable: true,
sortable: true,
pageable: false,
selectable: "row",
change: function(e) {
// Function call goes here
var detailRow = this.dataItem(this.select());
var optionID = detailRow.get("CustomerID")
},
height: 400
});
AddNewRow();
}
$(document).ready(function() {
LoadGrid();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.1.220/js/kendo.all.min.js"></script>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.common.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.rtl.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.silver.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.mobile.all.min.css" />
<div id="MyDiv">
<div id="GridList" tabindex="-1"></div>
</div>
这里有2个问题:
- 你不是 clearing/resetting "empty" 行,但我认为你认为你是。 在 ComboBox 的更改事件中,您所做的只是在索引 1 处添加一个新行,仅此而已……您将单独保留第 0 行,其中包括将 LastName 设置为所选的任何内容。 您实际上需要重置第 0 行。 这可以通过删除当前行 0 并将其替换为 "clean" 行 0 来完成。您可以使用 AddNewRow() 助手来执行此操作。
- 您实际上并没有从组合框中选择的项目中选择数据。 在 ComboBox 更改事件中,您只是从 ComboBox 的数据源中获取第一个项目,而不是所选项目。 您确实想要所选项目而不是项目 0。
如果将更改事件更新为类似这样的内容,它应该会更好地工作:
change: function(e) {
// THIS IS NOT THE DATA YOU WANT.
// e.sender is the ComboBox so this will always be "abc"(index 0 of the ComboBox dataSource) rather than the selected item.
// let items = e.sender._data()[0];
let items = e.sender._data()[e.sender.selectedIndex];
let grid = $("#GridList").data("kendoGrid");
grid.dataSource.insert(1, {
CustomerID: items.ID,
FirstName: items.FirstName,
LastName: items.LastName,
Address: items.Address,
City: items.City,
Zip: items.Zip,
});
// Need to "clear" the "empty" row, which is always row 0.
// We can do this by removing and re-adding the row(among other ways).
let dataItem = grid.dataSource.at(0);
grid.dataSource.remove(dataItem);
AddNewRow();
}