Kendo/JQuery 搜索框不通过“ICollection”进行搜索?
Kendo/JQuery searchbox doesn't search through `ICollection`?
我有一个 Kendo 网格,在 .ToolBar
我有一个搜索框,可以根据输入的内容过滤网格,总体来说,它工作正常。
问题是它不是 reading/searching 通过涉及使用 ICollection
的特定列(Maker 和 Associated)。我尝试了一些方法,但我不知道如何为这些列正确编写搜索。
我会注意到 Maker
和 Associated
列本身被正确填充,并且每个列自己的过滤器也能正常工作
首先,这是一个精简示例,说明如何在 Index.cshtml
中创建列和搜索框
@(Html.Kendo().Grid(Model).Name("gridWF")
.Columns(columns =>
{
column.Bound (p1 => p1.Id.Filterable(ftb => ftb.Cell(cell => cell.ShowOperators(true).InputWidth(90))).Width(150);
column.Bound (p1 => p1.Name.Filterable(ftb => ftb.Cell(cell => cell.ShowOperators(true).InputWidth(90))).Width(150);
column.Bound (p1 => p1.Item.Filterable(ftb => ftb.Cell(cell => cell.ShowOperators(true).InputWidth(90))).Width(150);
column.Bound (p1 => p1.Maker.Filterable(ftb => ftb.Cell(cell => cell.ShowOperators(true).InputWidth(90))).Width(150);
column.Bound (p1 => p1.Associated.Filterable(ftb => ftb.Cell(cell => cell.ShowOperators(true).InputWidth(90))).Width(150);
}
.Pageable()
.ColumnMenu()
.ToolBar(toolBar => toolBar.Template(@<text><input class='k-textbox' value="Search..." onfocus="if (this.value=='Search...') this.value='';" onblur="this.value = this.value==''?'Search...':this.value;" id='searchbox'/></text>)
.DataSource(datasource => datasource.Ajax()
.PageSize(15)
.ServerOperation(false)
.Read(r => r.Action("Read", "Workflows").Data("addSearch"))
)
<script type="text/javascript">
function addSearch() {
return { searchbox: $('#searchbox').val() };
}
$('#searchbox').keyup(function () {
$('#gridWF').data('kendoGrid').dataSource.read();
});
</script>
控制器的搜索部分
private IEnumerable<WorkflowViewModel> GetData(string searchbox = "")
{
var number = 0;
int.TryParse (searchbox, out number);
var result = (from w in Repo.GetWF()
where w.Id == number ||
w.Name.ToLower ().Contains (searchbox.ToLower ()) ||
//Failed attempt w.UserRoles.Where (ur => ur.Role.Name.ToLower ().Contains (searchbox.ToLower())) != null ||
//Failed attempt w.UserRoles.Where (ur => ur.Role != null && wr.Role.Name.ToLower().Equals ("maker", StringComparison.InvariantCultureIgnoreCase)).Select (wr => wr.UserName).FirstOrDefault ().Contains (searchbox.ToLower()) ||
w.ImportProduct.Item.Name.ToLower ().Contains (searchbox.ToLower ()) ||
searchbox == ""
select new ViewModel (w, User.Identity.Name)).ToList();
return result;
}
这里是ViewModel.cs
中的适用代码
public class ViewModel
public ViewModel(Workflow workflow, string userName = null)
{
Id = workflow.Id;
Name = workflow.Name;
Item= workflow.ImportProduct.Item.Name
Maker= Workflow.GetByRoles(workflow, "maker");
Associated= Workflow.GetByRoles(workflow, "associated");
}
Workflow.cs
public class Workflow
{
public Workflow()
{
UserRoles = new List<UserRole>();
}
[Key]
public int Id
{
get;
set;
}
[Required(ErrorMessage="*")]
[Display(Name="Name")]
public string Name
{
get;
set;
}
[Required]
public int ImportId
{
get;
set;
}
[ForeignKey("ImportId")]
public virtual Product ImportProduct
{
get;
set;
}
public ICollection<UserRole> UserRoles
{
get;
set;
}
public static string GetByRoles (Workflow workflow, string role)
{
string userString = "";
if(workflow.UserRoles != null)
{
var query = from ur in workflow.UserRoles
where ur.Role.Name.ToLower() == role.ToLower()
select ur.User.DisplayName;
foreach(string user in query.ToList()
{
usersString += user + ",";
}
usersString = usersString.Trim(' ');
usersString = usersString.Trim(',');
}
return usersString;
}
如果我遗漏了什么,或者有什么地方不清楚,请发表评论,我会尽力澄清。
谢谢
更新:
我为搜索框找到了一个轻微的解决方法,它成功地搜索了列。
//$('#searchbox').keyup(function () {
// $('#gridWF').data('kendoGrid').dataSource.read();
//});
$('#searchbox').keyup(function () {
var q = $("#searchbox").val();
var int = parseInt(q);
var grid = $("#gridWF").data("kendoGrid");
grid.dataSource.filter({
logic: "or",
filters: [
{ field: "Id", operator: "eq", value: int},
{ field: "Name", operator: "contains", value: q},
{ field: "Item", operator: "contains", value: q},
{ field: "Maker", operator: "contains", value: q },
{ field: "Associated", operator: "contains", value: q }
]
}
});
但是,此代码的行为不符合我的需要。这会在每行顶部的所有过滤器框中键入,这是不可接受的;我希望之前使用单个过滤器进行的任何过滤都保留下来。
解决了!
我在 Controller.cs
中需要的行是:
`w.UserRoles.Where (ur => ur.Role.Name.ToLower ().Contains ("maker")).Any (ur => ur.User.Name.ToLower ().Contains (searchbox.ToLower ())) ||`
我尝试失败的问题是 .Select
是 System.Collections.Generic.IEnumerable<bool>
,||
运算符无法使用。 .Any
解决了这个问题,因为它确定是否有任何元素满足条件。
我有一个 Kendo 网格,在 .ToolBar
我有一个搜索框,可以根据输入的内容过滤网格,总体来说,它工作正常。
问题是它不是 reading/searching 通过涉及使用 ICollection
的特定列(Maker 和 Associated)。我尝试了一些方法,但我不知道如何为这些列正确编写搜索。
我会注意到 Maker
和 Associated
列本身被正确填充,并且每个列自己的过滤器也能正常工作
首先,这是一个精简示例,说明如何在 Index.cshtml
@(Html.Kendo().Grid(Model).Name("gridWF")
.Columns(columns =>
{
column.Bound (p1 => p1.Id.Filterable(ftb => ftb.Cell(cell => cell.ShowOperators(true).InputWidth(90))).Width(150);
column.Bound (p1 => p1.Name.Filterable(ftb => ftb.Cell(cell => cell.ShowOperators(true).InputWidth(90))).Width(150);
column.Bound (p1 => p1.Item.Filterable(ftb => ftb.Cell(cell => cell.ShowOperators(true).InputWidth(90))).Width(150);
column.Bound (p1 => p1.Maker.Filterable(ftb => ftb.Cell(cell => cell.ShowOperators(true).InputWidth(90))).Width(150);
column.Bound (p1 => p1.Associated.Filterable(ftb => ftb.Cell(cell => cell.ShowOperators(true).InputWidth(90))).Width(150);
}
.Pageable()
.ColumnMenu()
.ToolBar(toolBar => toolBar.Template(@<text><input class='k-textbox' value="Search..." onfocus="if (this.value=='Search...') this.value='';" onblur="this.value = this.value==''?'Search...':this.value;" id='searchbox'/></text>)
.DataSource(datasource => datasource.Ajax()
.PageSize(15)
.ServerOperation(false)
.Read(r => r.Action("Read", "Workflows").Data("addSearch"))
)
<script type="text/javascript">
function addSearch() {
return { searchbox: $('#searchbox').val() };
}
$('#searchbox').keyup(function () {
$('#gridWF').data('kendoGrid').dataSource.read();
});
</script>
控制器的搜索部分
private IEnumerable<WorkflowViewModel> GetData(string searchbox = "")
{
var number = 0;
int.TryParse (searchbox, out number);
var result = (from w in Repo.GetWF()
where w.Id == number ||
w.Name.ToLower ().Contains (searchbox.ToLower ()) ||
//Failed attempt w.UserRoles.Where (ur => ur.Role.Name.ToLower ().Contains (searchbox.ToLower())) != null ||
//Failed attempt w.UserRoles.Where (ur => ur.Role != null && wr.Role.Name.ToLower().Equals ("maker", StringComparison.InvariantCultureIgnoreCase)).Select (wr => wr.UserName).FirstOrDefault ().Contains (searchbox.ToLower()) ||
w.ImportProduct.Item.Name.ToLower ().Contains (searchbox.ToLower ()) ||
searchbox == ""
select new ViewModel (w, User.Identity.Name)).ToList();
return result;
}
这里是ViewModel.cs
public class ViewModel
public ViewModel(Workflow workflow, string userName = null)
{
Id = workflow.Id;
Name = workflow.Name;
Item= workflow.ImportProduct.Item.Name
Maker= Workflow.GetByRoles(workflow, "maker");
Associated= Workflow.GetByRoles(workflow, "associated");
}
Workflow.cs
public class Workflow
{
public Workflow()
{
UserRoles = new List<UserRole>();
}
[Key]
public int Id
{
get;
set;
}
[Required(ErrorMessage="*")]
[Display(Name="Name")]
public string Name
{
get;
set;
}
[Required]
public int ImportId
{
get;
set;
}
[ForeignKey("ImportId")]
public virtual Product ImportProduct
{
get;
set;
}
public ICollection<UserRole> UserRoles
{
get;
set;
}
public static string GetByRoles (Workflow workflow, string role)
{
string userString = "";
if(workflow.UserRoles != null)
{
var query = from ur in workflow.UserRoles
where ur.Role.Name.ToLower() == role.ToLower()
select ur.User.DisplayName;
foreach(string user in query.ToList()
{
usersString += user + ",";
}
usersString = usersString.Trim(' ');
usersString = usersString.Trim(',');
}
return usersString;
}
如果我遗漏了什么,或者有什么地方不清楚,请发表评论,我会尽力澄清。
谢谢
更新:
我为搜索框找到了一个轻微的解决方法,它成功地搜索了列。
//$('#searchbox').keyup(function () {
// $('#gridWF').data('kendoGrid').dataSource.read();
//});
$('#searchbox').keyup(function () {
var q = $("#searchbox").val();
var int = parseInt(q);
var grid = $("#gridWF").data("kendoGrid");
grid.dataSource.filter({
logic: "or",
filters: [
{ field: "Id", operator: "eq", value: int},
{ field: "Name", operator: "contains", value: q},
{ field: "Item", operator: "contains", value: q},
{ field: "Maker", operator: "contains", value: q },
{ field: "Associated", operator: "contains", value: q }
]
}
});
但是,此代码的行为不符合我的需要。这会在每行顶部的所有过滤器框中键入,这是不可接受的;我希望之前使用单个过滤器进行的任何过滤都保留下来。
解决了!
我在 Controller.cs
中需要的行是:
`w.UserRoles.Where (ur => ur.Role.Name.ToLower ().Contains ("maker")).Any (ur => ur.User.Name.ToLower ().Contains (searchbox.ToLower ())) ||`
我尝试失败的问题是 .Select
是 System.Collections.Generic.IEnumerable<bool>
,||
运算符无法使用。 .Any
解决了这个问题,因为它确定是否有任何元素满足条件。