排序 Kendo 按 DataTextField 多选所选项目
Sort Kendo Multiselects selected Items by DataTextField
我们正在使用 kendo multiselect 和 mvc 包装器。设置中的所有内容都工作正常,但 selected 项目按数据值字段排序。我只是希望它们按数据文本字段排序,但到目前为止没有任何效果。
@(Html.Kendo().MultiSelectFor(m => m.SelectedPersonIds)
.HtmlAttributes(new { style = "width: 400px" })
.DataTextField("Name")
.DataValueField("PersonID")
.Filter("contains")
.Height(400)
.DataSource(ds =>
{
ds.Read(read =>
{
read.Action("GetPersons", "Person", new { area = "" });
});
})
.ItemTemplateId("detailTemplate")
.TagTemplateId("valueTemplate")
)
这是工作版本。我尝试添加
ds.Custom().Sort(s => s.Add("Name").Ascending());
和其他方法,但仍然没有运气。来自服务器的初始数据已排序,因此您 select 来自的列表已完美排序(按名称)。
如何实现 selected 项目也按名称而不是按 ID 排序?
提前致谢。
我不知道有没有ASP.NET的解决办法,但我可以给你JavaScript来解决:
function onMultiselectChange(e) {
e.sender.tagList.find('> li').sort(function (a, b) {
return $(a).text() > $(b).text();
}).appendTo(e.sender.tagList);
}
});
您可以像这样将它应用于您的 ASP.NET 多选:
.Events(e =>
{
e.Change("onMultiselectChange")
})
不要手动重新排列 DOM 元素。这样做会破坏显示项和内部数据之间的映射。如果您要手动重新排列 DOM 元素,则取消选择一个项目将导致在基础数据中取消选择不同的数据项目。绑定回服务器将产生不正确的结果。
这是正确的排序方式,假设值字段是 PersonID
但您希望它按 Name
排序
function orderMultiSelect(multi) {
const dataItems = multi.dataItems();
dataItems.sort(
(a, b) => {
const textA = a.Name;
const textB = b.Name;
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
}
);
const values = dataItems.map(di => di.PersonID);
multi.value(values);
}
function onMultiselectChange(e) {
orderMultiselect(e.sender);
}
然后您可以将此处理程序函数绑定到 DataBound
和 Change
事件:
@(Html.Kendo().MultiSelectFor(m => m.SelectedPersonIds)
.HtmlAttributes(new { style = "width: 400px" })
.DataTextField("Name")
.DataValueField("PersonID")
.Filter("contains")
.Height(400)
.DataSource(
ds =>
{
ds.Read(
read =>
read.Action("GetPersons", "Person", new { area = "" })
);
}
).ItemTemplateId("detailTemplate")
.TagTemplateId("valueTemplate")
.Event(
e =>
e.DataBound("onMultiselectChange")
.Change("onMultiselectChange")
)
)
我们正在使用 kendo multiselect 和 mvc 包装器。设置中的所有内容都工作正常,但 selected 项目按数据值字段排序。我只是希望它们按数据文本字段排序,但到目前为止没有任何效果。
@(Html.Kendo().MultiSelectFor(m => m.SelectedPersonIds)
.HtmlAttributes(new { style = "width: 400px" })
.DataTextField("Name")
.DataValueField("PersonID")
.Filter("contains")
.Height(400)
.DataSource(ds =>
{
ds.Read(read =>
{
read.Action("GetPersons", "Person", new { area = "" });
});
})
.ItemTemplateId("detailTemplate")
.TagTemplateId("valueTemplate")
)
这是工作版本。我尝试添加
ds.Custom().Sort(s => s.Add("Name").Ascending());
和其他方法,但仍然没有运气。来自服务器的初始数据已排序,因此您 select 来自的列表已完美排序(按名称)。
如何实现 selected 项目也按名称而不是按 ID 排序? 提前致谢。
我不知道有没有ASP.NET的解决办法,但我可以给你JavaScript来解决:
function onMultiselectChange(e) {
e.sender.tagList.find('> li').sort(function (a, b) {
return $(a).text() > $(b).text();
}).appendTo(e.sender.tagList);
}
});
您可以像这样将它应用于您的 ASP.NET 多选:
.Events(e =>
{
e.Change("onMultiselectChange")
})
不要手动重新排列 DOM 元素。这样做会破坏显示项和内部数据之间的映射。如果您要手动重新排列 DOM 元素,则取消选择一个项目将导致在基础数据中取消选择不同的数据项目。绑定回服务器将产生不正确的结果。
这是正确的排序方式,假设值字段是 PersonID
但您希望它按 Name
function orderMultiSelect(multi) {
const dataItems = multi.dataItems();
dataItems.sort(
(a, b) => {
const textA = a.Name;
const textB = b.Name;
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
}
);
const values = dataItems.map(di => di.PersonID);
multi.value(values);
}
function onMultiselectChange(e) {
orderMultiselect(e.sender);
}
然后您可以将此处理程序函数绑定到 DataBound
和 Change
事件:
@(Html.Kendo().MultiSelectFor(m => m.SelectedPersonIds)
.HtmlAttributes(new { style = "width: 400px" })
.DataTextField("Name")
.DataValueField("PersonID")
.Filter("contains")
.Height(400)
.DataSource(
ds =>
{
ds.Read(
read =>
read.Action("GetPersons", "Person", new { area = "" })
);
}
).ItemTemplateId("detailTemplate")
.TagTemplateId("valueTemplate")
.Event(
e =>
e.DataBound("onMultiselectChange")
.Change("onMultiselectChange")
)
)