从子组中获取父组的完整列表。 (Kendo UI)
Get a complete list of parent groups from child group. (Kendo UI)
可执行代码片段:https://demos.telerik.com/kendo-ui/grid/index(只需转到此示例并点击“编辑”)
我想在子组的 groupFooterTemplate 中显示完整的父组列表。
{
field: "Discontinued",
title: "In Stock",
template: "<span id='badge_#=ProductID#' class='badgeTemplate'></span>",
groupFooterTemplate: (data) => { return this.getPathToDataItem(data)} ,
width: 130,
}
上面我更改了其中一列以引用其 groupFooterTemplate 中的函数 getPathToDataItem(data)。现在我定义函数:
private getPathToDataItem(data): string {
var path: string = '';
//Javascript - JQuery - Black magic goes here!
return path; //Should look something like Seafood/Unavailable (assuming my groups are Category,
InStock in that order!)
}
实际获取模板。我想使用 javascript/jquery/kendo 获取正在玩的组的完整列表并为它们创建路径。因此,如果播放的组是 Category、Instock,则模板应显示 Seafood/Unavailable、Produce/Available 等
我的问题是我不知道如何在子组模板中获取父组!最后一个很简单,因为它只是 data.value,但我如何获得先前的组?我怀疑我需要做类似的事情:
group1/group2/.../data.value
但是我如何获得 group1、group2 以及通常的 groupN?
任何帮助将不胜感激,谢谢!
好的。将下面的代码粘贴到 Telerik DOJO 中。顺便说一下,从您的问题中删除 typescript
标签。这不是 typescript
,这是 Kendo UI jQuery。如果播放中的组是类别和库存,页脚将显示类似 'Seafood/available'、'Seafood/not available' 等内容。获取先前组的想法是分配对 Kendo 的引用grid 对象,以便我们可以访问 groupFooterTemplate
函数中的 dataSource
,这就是 Javascript 黑魔法发生的地方。希望下面的代码能帮助您解决问题。
<!DOCTYPE html>
<html>
<head>
<base href="https://demos.telerik.com/kendo-ui/grid/index">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2021.2.511/styles/kendo.bootstrap-v4.min.css" />
<script src="https://kendo.cdn.telerik.com/2021.2.511/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2021.2.511/js/kendo.all.min.js"></script>
</head>
<body>
<script src="//cdnjs.cloudflare.com/ajax/libs/jszip/2.4.0/jszip.min.js"></script>
<div id="example">
<div id="grid"></div>
<script>
$(document).ready(function () {
var crudServiceBaseUrl = "https://demos.telerik.com/kendo-ui/service",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "/detailproducts",
dataType: "jsonp"
},
update: {
url: crudServiceBaseUrl + "/detailproducts/Update",
dataType: "jsonp"
},
destroy: {
url: crudServiceBaseUrl + "/detailproducts/Destroy",
dataType: "jsonp"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
pageSize: 20,
autoSync: true,
aggregate: [{
field: "TotalSales",
aggregate: "sum"
}],
group: {
field: "Category.CategoryName",
dir: "desc",
aggregates: [
{ field: "TotalSales", aggregate: "sum" }
]
},
schema: {
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
Discontinued: { type: "boolean", editable: false },
TotalSales: { type: "number", editable: false },
TargetSales: { type: "number", editable: false },
LastSupply: { type: "date" },
UnitPrice: { type: "number" },
UnitsInStock: { type: "number" },
Category: {
defaultValue: {
CategoryID: 8,
CategoryName: "Seafood"
}
},
Country: {
defaultValue: {
CountryNameLong: "Bulgaria",
CountryNameShort: "bg"
}
}
}
}
}
});
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
columnMenu: {
filterable: false
},
height: 680,
editable: "incell",
pageable: true,
sortable: true,
navigatable: true,
resizable: true,
reorderable: true,
groupable: true,
filterable: true,
dataBound: onDataBound,
toolbar: ["excel", "pdf", "search"],
columns: [{
selectable: true,
width: 75,
attributes: {
"class": "checkbox-align",
},
headerAttributes: {
"class": "checkbox-align",
}
}, {
field: "ProductName",
title: "Product Name",
template: "<div class='product-photo' style='background-image: url(../content/web/foods/#:data.ProductID#.jpg);'></div><div class='product-name'>#: ProductName #</div>",
width: 300,
groupFooterTemplate: function(dataItem) {
var ds = grid.dataSource;
var groupingFields = [];
for (let a = 0; a < ds._group.length; a++) {
groupingFields.push(ds._group[a].field);
}
var items = dataItem.items;
for (let a = 0; a < items.length; a++) {
if (items[a].hasOwnProperty('hasSubgroups')) {
items = items[a].items;
break;
}
}
var path = '';
for (let a = 0; a < items.length; a++) {
var item = items[a];
for (let b = 0; b < groupingFields.length; b++) {
var groupingField = groupingFields[b];
if (b > 0) {
path += '/';
}
if (groupingField.includes('.')) {
path += groupingField.split('.').reduce(getValue, item);
} else {
if (groupingField === 'Discontinued') {
path += item[groupingField] ? 'available' : 'not available';
} else {
path += item[groupingField];
}
}
if (groupingField === dataItem.field) {
break;
}
}
break;
}
return path;
function getValue(obj, prop) {
return obj[prop];
}
},
}, {
field: "UnitPrice",
title: "Price",
format: "{0:c}",
width: 105
}, {
field: "Discontinued",
title: "In Stock",
template: "<span id='badge_#=ProductID#' class='badgeTemplate'></span>",
width: 130,
}, {
field: "Category.CategoryName",
title: "Category",
editor: clientCategoryEditor,
groupHeaderTemplate: "Category: #=data.value#, Total Sales: #=kendo.format('{0:c}', aggregates.TotalSales.sum)#",
width: 125
}, {
field: "CustomerRating",
title: "Rating",
template: "<input id='rating_#=ProductID#' data-bind='value: CustomerRating' class='rating'/>",
editable: returnFalse,
width: 140
}, {
field: "Country.CountryNameLong",
title: "Country",
template: "<div class='k-text-center'><img src='../content/web/country-flags/#:data.Country.CountryNameShort#.png' alt='#: data.Country.CountryNameLong#' title='#: data.Country.CountryNameLong#' width='30' /></div>",
editor: clientCountryEditor,
width: 120
}, {
field: "UnitsInStock",
title: "Units",
width: 105
}, {
field: "TotalSales",
title: "Total Sales",
format: "{0:c}",
width: 140,
aggregates: ["sum"],
}, {
field: "TargetSales",
title: "Target Sales",
format: "{0:c}",
template: "<span id='chart_#= ProductID#' class='sparkline-chart'></span>",
width: 220
},
{ command: "destroy", title: " ", width: 120 }],
}).data('kendoGrid');
});
function onDataBound(e) {
var grid = this;
grid.table.find("tr").each(function () {
var dataItem = grid.dataItem(this);
if (dataItem === undefined) {
return;
}
var themeColor = dataItem.Discontinued ? 'success' : 'error';
var text = dataItem.Discontinued ? 'available' : 'not available';
$(this).find(".badgeTemplate").kendoBadge({
themeColor: themeColor,
text: text,
});
$(this).find(".rating").kendoRating({
min: 1,
max: 5,
label: false,
selection: "continuous"
});
$(this).find(".sparkline-chart").kendoSparkline({
legend: {
visible: false
},
data: [dataItem.TargetSales],
type: "bar",
chartArea: {
margin: 0,
width: 180,
background: "transparent"
},
seriesDefaults: {
labels: {
visible: true,
format: '{0}%',
background: 'none'
}
},
categoryAxis: {
majorGridLines: {
visible: false
},
majorTicks: {
visible: false
}
},
valueAxis: {
type: "numeric",
min: 0,
max: 130,
visible: false,
labels: {
visible: false
},
minorTicks: { visible: false },
majorGridLines: { visible: false }
},
tooltip: {
visible: false
}
});
kendo.bind($(this), dataItem);
});
}
function returnFalse() {
return false;
}
function clientCategoryEditor(container, options) {
$('<input required name="Category">')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataTextField: "CategoryName",
dataValueField: "CategoryID",
dataSource: {
data: categories
}
});
}
function clientCountryEditor(container, options) {
$('<input required name="Country">')
.appendTo(container)
.kendoDropDownList({
dataTextField: "CountryNameLong",
dataValueField: "CountryNameShort",
template: "<div class='dropdown-country-wrap'><img src='../content/web/country-flags/#:CountryNameShort#.png' alt='#: CountryNameLong#' title='#: CountryNameLong#' width='30' /><span>#:CountryNameLong #</span></div>",
dataSource: {
transport: {
read: {
url: " https://demos.telerik.com/kendo-ui/service/countries",
dataType: "jsonp"
}
}
},
autoWidth: true
});
}
var categories = [{
"CategoryID": 1,
"CategoryName": "Beverages"
}, {
"CategoryID": 2,
"CategoryName": "Condiments"
}, {
"CategoryID": 3,
"CategoryName": "Confections"
}, {
"CategoryID": 4,
"CategoryName": "Dairy Products"
}, {
"CategoryID": 5,
"CategoryName": "Grains/Cereals"
}, {
"CategoryID": 6,
"CategoryName": "Meat/Poultry"
}, {
"CategoryID": 7,
"CategoryName": "Produce"
}, {
"CategoryID": 8,
"CategoryName": "Seafood"
}];
</script>
<style type="text/css">
.customer-photo {
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
background-size: 32px 35px;
background-position: center center;
vertical-align: middle;
line-height: 32px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
margin-left: 5px;
}
.customer-name {
display: inline-block;
vertical-align: middle;
line-height: 32px;
padding-left: 3px;
}
.k-grid tr .checkbox-align {
text-align: center;
vertical-align: middle;
}
.product-photo {
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
background-size: 32px 35px;
background-position: center center;
vertical-align: middle;
line-height: 32px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
margin-right: 5px;
}
.product-name {
display: inline-block;
vertical-align: middle;
line-height: 32px;
padding-left: 3px;
}
.k-rating-container .k-rating-item {
padding: 4px 0;
}
.k-rating-container .k-rating-item .k-icon {
font-size: 16px;
}
.dropdown-country-wrap {
display: flex;
flex-wrap: nowrap;
align-items: center;
white-space: nowrap;
}
.dropdown-country-wrap img {
margin-right: 10px;
}
#grid .k-grid-edit-row > td > .k-rating {
margin-left: 0;
width: 100%;
}
.k-grid .k-grid-search {
margin-left: auto;
margin-right: 0;
}
</style>
</div>
</body>
</html>
可执行代码片段:https://demos.telerik.com/kendo-ui/grid/index(只需转到此示例并点击“编辑”)
我想在子组的 groupFooterTemplate 中显示完整的父组列表。
{
field: "Discontinued",
title: "In Stock",
template: "<span id='badge_#=ProductID#' class='badgeTemplate'></span>",
groupFooterTemplate: (data) => { return this.getPathToDataItem(data)} ,
width: 130,
}
上面我更改了其中一列以引用其 groupFooterTemplate 中的函数 getPathToDataItem(data)。现在我定义函数:
private getPathToDataItem(data): string {
var path: string = '';
//Javascript - JQuery - Black magic goes here!
return path; //Should look something like Seafood/Unavailable (assuming my groups are Category,
InStock in that order!)
}
实际获取模板。我想使用 javascript/jquery/kendo 获取正在玩的组的完整列表并为它们创建路径。因此,如果播放的组是 Category、Instock,则模板应显示 Seafood/Unavailable、Produce/Available 等
我的问题是我不知道如何在子组模板中获取父组!最后一个很简单,因为它只是 data.value,但我如何获得先前的组?我怀疑我需要做类似的事情:
group1/group2/.../data.value
但是我如何获得 group1、group2 以及通常的 groupN?
任何帮助将不胜感激,谢谢!
好的。将下面的代码粘贴到 Telerik DOJO 中。顺便说一下,从您的问题中删除 typescript
标签。这不是 typescript
,这是 Kendo UI jQuery。如果播放中的组是类别和库存,页脚将显示类似 'Seafood/available'、'Seafood/not available' 等内容。获取先前组的想法是分配对 Kendo 的引用grid 对象,以便我们可以访问 groupFooterTemplate
函数中的 dataSource
,这就是 Javascript 黑魔法发生的地方。希望下面的代码能帮助您解决问题。
<!DOCTYPE html>
<html>
<head>
<base href="https://demos.telerik.com/kendo-ui/grid/index">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2021.2.511/styles/kendo.bootstrap-v4.min.css" />
<script src="https://kendo.cdn.telerik.com/2021.2.511/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2021.2.511/js/kendo.all.min.js"></script>
</head>
<body>
<script src="//cdnjs.cloudflare.com/ajax/libs/jszip/2.4.0/jszip.min.js"></script>
<div id="example">
<div id="grid"></div>
<script>
$(document).ready(function () {
var crudServiceBaseUrl = "https://demos.telerik.com/kendo-ui/service",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "/detailproducts",
dataType: "jsonp"
},
update: {
url: crudServiceBaseUrl + "/detailproducts/Update",
dataType: "jsonp"
},
destroy: {
url: crudServiceBaseUrl + "/detailproducts/Destroy",
dataType: "jsonp"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
pageSize: 20,
autoSync: true,
aggregate: [{
field: "TotalSales",
aggregate: "sum"
}],
group: {
field: "Category.CategoryName",
dir: "desc",
aggregates: [
{ field: "TotalSales", aggregate: "sum" }
]
},
schema: {
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
Discontinued: { type: "boolean", editable: false },
TotalSales: { type: "number", editable: false },
TargetSales: { type: "number", editable: false },
LastSupply: { type: "date" },
UnitPrice: { type: "number" },
UnitsInStock: { type: "number" },
Category: {
defaultValue: {
CategoryID: 8,
CategoryName: "Seafood"
}
},
Country: {
defaultValue: {
CountryNameLong: "Bulgaria",
CountryNameShort: "bg"
}
}
}
}
}
});
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
columnMenu: {
filterable: false
},
height: 680,
editable: "incell",
pageable: true,
sortable: true,
navigatable: true,
resizable: true,
reorderable: true,
groupable: true,
filterable: true,
dataBound: onDataBound,
toolbar: ["excel", "pdf", "search"],
columns: [{
selectable: true,
width: 75,
attributes: {
"class": "checkbox-align",
},
headerAttributes: {
"class": "checkbox-align",
}
}, {
field: "ProductName",
title: "Product Name",
template: "<div class='product-photo' style='background-image: url(../content/web/foods/#:data.ProductID#.jpg);'></div><div class='product-name'>#: ProductName #</div>",
width: 300,
groupFooterTemplate: function(dataItem) {
var ds = grid.dataSource;
var groupingFields = [];
for (let a = 0; a < ds._group.length; a++) {
groupingFields.push(ds._group[a].field);
}
var items = dataItem.items;
for (let a = 0; a < items.length; a++) {
if (items[a].hasOwnProperty('hasSubgroups')) {
items = items[a].items;
break;
}
}
var path = '';
for (let a = 0; a < items.length; a++) {
var item = items[a];
for (let b = 0; b < groupingFields.length; b++) {
var groupingField = groupingFields[b];
if (b > 0) {
path += '/';
}
if (groupingField.includes('.')) {
path += groupingField.split('.').reduce(getValue, item);
} else {
if (groupingField === 'Discontinued') {
path += item[groupingField] ? 'available' : 'not available';
} else {
path += item[groupingField];
}
}
if (groupingField === dataItem.field) {
break;
}
}
break;
}
return path;
function getValue(obj, prop) {
return obj[prop];
}
},
}, {
field: "UnitPrice",
title: "Price",
format: "{0:c}",
width: 105
}, {
field: "Discontinued",
title: "In Stock",
template: "<span id='badge_#=ProductID#' class='badgeTemplate'></span>",
width: 130,
}, {
field: "Category.CategoryName",
title: "Category",
editor: clientCategoryEditor,
groupHeaderTemplate: "Category: #=data.value#, Total Sales: #=kendo.format('{0:c}', aggregates.TotalSales.sum)#",
width: 125
}, {
field: "CustomerRating",
title: "Rating",
template: "<input id='rating_#=ProductID#' data-bind='value: CustomerRating' class='rating'/>",
editable: returnFalse,
width: 140
}, {
field: "Country.CountryNameLong",
title: "Country",
template: "<div class='k-text-center'><img src='../content/web/country-flags/#:data.Country.CountryNameShort#.png' alt='#: data.Country.CountryNameLong#' title='#: data.Country.CountryNameLong#' width='30' /></div>",
editor: clientCountryEditor,
width: 120
}, {
field: "UnitsInStock",
title: "Units",
width: 105
}, {
field: "TotalSales",
title: "Total Sales",
format: "{0:c}",
width: 140,
aggregates: ["sum"],
}, {
field: "TargetSales",
title: "Target Sales",
format: "{0:c}",
template: "<span id='chart_#= ProductID#' class='sparkline-chart'></span>",
width: 220
},
{ command: "destroy", title: " ", width: 120 }],
}).data('kendoGrid');
});
function onDataBound(e) {
var grid = this;
grid.table.find("tr").each(function () {
var dataItem = grid.dataItem(this);
if (dataItem === undefined) {
return;
}
var themeColor = dataItem.Discontinued ? 'success' : 'error';
var text = dataItem.Discontinued ? 'available' : 'not available';
$(this).find(".badgeTemplate").kendoBadge({
themeColor: themeColor,
text: text,
});
$(this).find(".rating").kendoRating({
min: 1,
max: 5,
label: false,
selection: "continuous"
});
$(this).find(".sparkline-chart").kendoSparkline({
legend: {
visible: false
},
data: [dataItem.TargetSales],
type: "bar",
chartArea: {
margin: 0,
width: 180,
background: "transparent"
},
seriesDefaults: {
labels: {
visible: true,
format: '{0}%',
background: 'none'
}
},
categoryAxis: {
majorGridLines: {
visible: false
},
majorTicks: {
visible: false
}
},
valueAxis: {
type: "numeric",
min: 0,
max: 130,
visible: false,
labels: {
visible: false
},
minorTicks: { visible: false },
majorGridLines: { visible: false }
},
tooltip: {
visible: false
}
});
kendo.bind($(this), dataItem);
});
}
function returnFalse() {
return false;
}
function clientCategoryEditor(container, options) {
$('<input required name="Category">')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataTextField: "CategoryName",
dataValueField: "CategoryID",
dataSource: {
data: categories
}
});
}
function clientCountryEditor(container, options) {
$('<input required name="Country">')
.appendTo(container)
.kendoDropDownList({
dataTextField: "CountryNameLong",
dataValueField: "CountryNameShort",
template: "<div class='dropdown-country-wrap'><img src='../content/web/country-flags/#:CountryNameShort#.png' alt='#: CountryNameLong#' title='#: CountryNameLong#' width='30' /><span>#:CountryNameLong #</span></div>",
dataSource: {
transport: {
read: {
url: " https://demos.telerik.com/kendo-ui/service/countries",
dataType: "jsonp"
}
}
},
autoWidth: true
});
}
var categories = [{
"CategoryID": 1,
"CategoryName": "Beverages"
}, {
"CategoryID": 2,
"CategoryName": "Condiments"
}, {
"CategoryID": 3,
"CategoryName": "Confections"
}, {
"CategoryID": 4,
"CategoryName": "Dairy Products"
}, {
"CategoryID": 5,
"CategoryName": "Grains/Cereals"
}, {
"CategoryID": 6,
"CategoryName": "Meat/Poultry"
}, {
"CategoryID": 7,
"CategoryName": "Produce"
}, {
"CategoryID": 8,
"CategoryName": "Seafood"
}];
</script>
<style type="text/css">
.customer-photo {
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
background-size: 32px 35px;
background-position: center center;
vertical-align: middle;
line-height: 32px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
margin-left: 5px;
}
.customer-name {
display: inline-block;
vertical-align: middle;
line-height: 32px;
padding-left: 3px;
}
.k-grid tr .checkbox-align {
text-align: center;
vertical-align: middle;
}
.product-photo {
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
background-size: 32px 35px;
background-position: center center;
vertical-align: middle;
line-height: 32px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
margin-right: 5px;
}
.product-name {
display: inline-block;
vertical-align: middle;
line-height: 32px;
padding-left: 3px;
}
.k-rating-container .k-rating-item {
padding: 4px 0;
}
.k-rating-container .k-rating-item .k-icon {
font-size: 16px;
}
.dropdown-country-wrap {
display: flex;
flex-wrap: nowrap;
align-items: center;
white-space: nowrap;
}
.dropdown-country-wrap img {
margin-right: 10px;
}
#grid .k-grid-edit-row > td > .k-rating {
margin-left: 0;
width: 100%;
}
.k-grid .k-grid-search {
margin-left: auto;
margin-right: 0;
}
</style>
</div>
</body>
</html>