Reputation: 2184
I am using the KendoUI in my MVC application. I am filtering my grid using some input boxes and a multiselect widget. The multiselect widget passes the selected elements as an array. My question is how can I filter the grid using the multiselect?
At the moment all the input's share a global condition of "AND" so that they can work together when returning the data, the multiselect however will need to have a sub condition of "OR" to work.
What I have attempted to do is iterate over the passed in array objects and return them individually. I need the multiselect condition of "or" to be applied to them. I can see that the array objects are being returned individually to the console but tehy are not being included in the overall filtering of the grid making it redundant.
Can anyone shed some like on how I can resolve this problem? I have included my code below which shows where the multiselect widget sits in my javascript code and the approach I've taken.
@(Html.Kendo().Grid<MyProject.ViewModels.FixtureSearchViewModel>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(c => c.fixture_idx).Hidden();
columns.Bound(c => c.fixture_date)
.Title("Date")
.ClientTemplate("#=fixture_date ? kendo.toString(kendo.parseDate(fixture_date), 'dd/MM/yyyy') : '' #");
columns.Bound(c => c.owner_company)
.Title("Owner");
columns.Bound(c => c.vessel_name)
.Title("Name");
columns.Bound(c => c.vessel_type)
.Title("Type");
columns.Bound(c => c.charterer_company)
.Title("Charterer");
columns.Bound(c => c.fixture_type)
.Title("Type");
columns.Bound(c => c.workscopecode)
.Title("Duties");
columns.Bound(c => c.fixture_start)
.Title("Start")
.ClientTemplate("#=fixture_start ? kendo.toString(kendo.parseDate(fixture_start), 'dd/MM/yyyy') : '' #");
columns.Bound(c => c.on_hire_location)
.Title("Location");
columns.Bound(c => c.fixture_end)
.Title("End")
.ClientTemplate("#=fixture_end ? kendo.toString(kendo.parseDate(fixture_end), 'dd/MM/yyyy') : '' #");
columns.Bound(c => c.off_hire_location)
.Title("Location");
columns.Bound(c => c.initial_rate)
.Title("Rate")
.ClientTemplate(" #=initial_rate_currency# #=initial_rate#");
})
.Pageable()
.Sortable(sortable =>
{
sortable.SortMode(GridSortMode.MultipleColumn);
}).ToolBar(toolbar =>
{
toolbar.Template(@<text>
<table class="table">
<tr>
<td>Charterer</td>
<td>
@(Html.Kendo().DropDownList()
.Name("charterer_company")
.Filter("contains")
.OptionLabel("Choose Charterer")
.DataTextField("CompanyName")
.DataValueField("CompanyName")
.DataSource(e => e.Read("GetChartererCompanies", "FormAssets"))
)
</td>
</tr>
<tr>
<td>Start(After)</td>
<td>
@(Html.Kendo().DatePicker()
.Name("fixture_start"))
</td>
</tr>
<tr>
<td>End(Before)</td>
<td>
@(Html.Kendo().DatePicker()
.Name("fixture_end"))
</td>
</tr>
<tr>
<td>Vessel Types</td>
<td>
@(Html.Kendo().DropDownList()
.Name("vessel_type")
.Filter("contains")
.DataTextField("Text")
.DataValueField("Value")
.BindTo(new List<SelectListItem>() {
new SelectListItem() {
Text = "AHTS",
Value = "AHTS",
},
new SelectListItem() {
Text = "PSV",
Value = "PSV"
},
new SelectListItem() {
Text = "Special",
Value = "Special"
},
new SelectListItem() {
Text = "Standby",
Value = "Standby"
},
new SelectListItem() {
Text = "Tug",
Value = "Tug"
}
}))
</td>
</tr>
<tr>
<td>Duties</td>
<td>
@(Html.Kendo().MultiSelect()
.Name("workscopecode")
.DataTextField("WorkScopeName")
.DataValueField("WorkScopeName")
.Placeholder("Select Duties")
.AutoBind(false)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetDuties", "FormAssets");
})
.ServerFiltering(true);
})
)
</td>
</tr>
<tr>
<td>Onhire Location</td>
<td></td>
</tr>
<tr>
<td>Fixture Type</td>
<td></td>
</tr>
</table>
<button id="search-button" type="button">Search</button>
</text>);
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Model(model => model.Id(p => p.fixture_idx))
.Read(read => read.Action("readFixtures", "Search"))
))
Here is my javascript that controls the above search input boxes.
var search_btn = document.getElementById("search-button");
function search() {
var filters = [],
grid_aberdeen = $('#Grid').data('kendoGrid'),
search_charterer = $("#charterer_company").data("kendoDropDownList").value(),
search_start = $("#fixture_start").data("kendoDatePicker").value(),
search_end = $("#fixture_end").data("kendoDatePicker").value(),
search_type = $("#vessel_type").data("kendoDropDownList").value(),
search_duties = $("#workscopecode").data("kendoMultiSelect").value();
if (search_charterer) {
filters.push(
{
field: "charterer_company",
operator: "eq",
value: search_charterer
}
)
}
if (search_start) {
filters.push(
{
field: "fixture_start",
operator: "gte",
value: search_start
})
}
if (search_end) {
filters.push(
{
field: "fixture_end",
operator: "lte",
value: search_end
})
}
if (search_duties) {
var sub_filter = { logic: "or", filters: [] }
$.each(search_duties, function (i, v) {
sub_filter.filters.push[
{
field: "workscopecode",
operator: "eq",
value: v
}
]
console.log(v)
})
};
grid_aberdeen.dataSource.filter({
logic: "and",
filters: filters
});
}
search_btn.addEventListener("click", search);
As you can see I have tried to create a "sub condition" if you will, that I'd like to apply to the multiselect but it's not doing anything. The console shows that the array items are being seperated just fine but actually filter against them isn't working.
var sub_filter = { logic: "or", filters: [] }
Upvotes: 0
Views: 664
Reputation: 2184
Ok so to get this to work there was a small error in my formatting of the filter itself. To correct this I made the following chages which now allow the array to be iterated over and passed in as individual terms to the search filters.
if (search_duties) {
var sub_filter = {
logic: "or",
filters: []
}
$.each(search_duties, function (i, v) {
sub_filter.filters.push(
{
field: "workscopecode",
operator: "eq",
value: v
})
})
filters.push(sub_filter);
}
Note the removal of the bracket which changes this:
$.each(search_duties, function (i, v) {
sub_filter.filters.push[
{
field: "workscopecode",
operator: "eq",
value: v
}
]
console.log(v)
})
to this instead:
$.each(search_duties, function (i, v) {
sub_filter.filters.push(
{
field: "workscopecode",
operator: "eq",
value: v
})
})
Since [] was already defined in var filters: [] I didn't need to reclare it down in the actual filter itself otherwise the output would have looked like [[...filters...]] which was causing it to do nothing.
Upvotes: 1
Reputation: 4139
UPDATE
The problem is that sub_filter
is never added to the filters
array, which is passed in the dataSource.filter()
method.
Double-check the filters
object structure. The desired behaviour is supported:
var filters = {
logic: "and",
filters: [
{ field: "ShipName", operator: "contains", value: "o" },
{ field: "ShipCity", operator: "contains", value: "o" },
{
logic: "or",
filters: [
{ field: "OrderID", operator: "eq", value: 10251 },
{ field: "OrderID", operator: "eq", value: 10259 }
]
}
]
};
$("#grid").data("kendoGrid").dataSource.filter(filters);
Upvotes: 2