У меня есть Kendo Grid, теперь для тестирования только с 4 столбцами. Каждый столбец имеет разные типы: string, DateTime, int и ForeignKey of Guid! Проблема возникает здесь: я хочу отфильтровать свою сетку, набрав что-нибудь в моем единственном текстовом поле фильтра, но Grid не может быть отфильтрован в столбец ForeignKey, потому что я, конечно, набираю видимый текст, а не Guid ...
Моя простая ViewModel:
public class ClientViewModel
{
public Guid Id { get; set; }
public string FullName { get; set; }
public DateTime DateOfBirth { get; set; }
public int ZipCode { get; set; }
public Guid CityId { get; set; }
}
По предложению поддержки Telerik я использую собственный источник данных для своей сетки (кстати, они все еще не могут дать мне правильный способ решения этой проблемы). Вид выглядит так:
@(Html.Kendo().Grid<ClientViewModel>().Name("clientGrid")
.Events(ev => ev.Edit("onEdit"))
.Columns(c =>
{
c.Bound(x => x.Id).Hidden(true);
c.Bound(x => x.FullName);
c.Bound(x => x.DateOfBirth).Format("{0:yyyy.MM.dd.}");
c.ForeignKey(x => x.CityId, (IEnumerable) ViewData["City"], "Id", "Name");
c.Bound(x => x.ZipCode);
})
.ToolBar(t =>
{
t.Template(@<text>
<div>
<label class="search-label" for="searchBox">Search:</label>
<input type="search" id="searchBox" class="k-textbox" style="width: 250px"/>
<input type="button" id="clearBox" value="Clear filters" class="k-primary" style="height: 1.65em;"/>
</div>
</text>);
})
.DataSource(source => source
.Custom()
.Type("odata-v4")
.Schema(sch => sch.Model(m =>
{
m.Id(p => p.Id);
m.Field(p => p.Id).DefaultValue(Guid.NewGuid());
m.Field(p => p.FullName);
m.Field(p => p.DateOfBirth);
m.Field(p => p.CityId).DefaultValue(Guid.Empty);
m.Field(p => p.ZipCode);
}))
.Transport(tr =>
{
tr.Read(read => read.Url("result.json"));
tr.ParameterMap("parameterMap");
})
)
.Scrollable()
.Filterable()
.Sortable()
.HtmlAttributes(new { style = "height: 700px;" })
.Pageable(p => p.Refresh(true).PageSizes(true).ButtonCount(5)))
Часть javascript:
function parameterMap(options, operation) {
var result = kendo.data.transports["odata-v4"].parameterMap(options, operation);
if (result.$filter) {
var guid = /('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')/ig;
result.$filter = result.$filter.replace(guid, function (x) {
return x.substring(1, x.length - 1);
});
}
return result;
}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
$(document).ready(function () {
var grid = $('#clientGrid').data('kendoGrid');
$('#searchBox').on('input',
function (e) {
var columns = grid.columns;
var filter = { logic: 'or', filters: [] };
columns.forEach(function (x) {
if (x.field) {
var type = grid.dataSource.options.schema.model.fields[x.field].type;
var defaultValue = grid.dataSource.options.schema.model.fields[x.field].defaultValue;
if (type === 'string') {
filter.filters.push({
field: x.field,
operator: "contains",
value: e.target.value
});
} else if (type === 'number') {
if (isNumeric(e.target.value)) {
filter.filters.push({
field: x.field,
operator: 'eq',
value: e.target.value
});
}
} else if (type === 'date') {
var data = grid.dataSource.data();
for (var i = 0; i < data.length; i++) {
var dateStr = kendo.format(x.format, data[i][x.field]);
if (dateStr.startsWith(e.target.value)) {
filter.filters.push({
field: x.field,
operator: 'eq',
value: data[i][x.field]
});
}
}
}
}
});
grid.dataSource.filter(filter);
});
$('#clearBox').click(function(e) {
grid.dataSource.filter({});
$('#searchBox').val('');
});
});
Модель для ViewData ["City"] использует следующий класс City:
public abstract class BaseEntity
{
protected BaseEntity()
{
Id = Guid.NewGuid();
}
[Key]
public Guid Id { get; set; }
}
public class Country : BaseEntity
{
public Country()
{
Cities = new HashSet<City>();
}
[Required]
[StringLength(250)]
public string Name { get; set; }
[Required]
[StringLength(3)]
public string Code { get; set; }
public virtual ICollection<City> Cities { get; set; }
}
public class City : BaseEntity
{
public City()
{
Clients = new HashSet<Client>();
}
[Required]
[StringLength(250)]
public string Name { get; set; }
public int ZipCode { get; set; }
public Guid CountryId { get; set; }
[ForeignKey("CountryId")]
public virtual Country Country { get; set; }
public virtual ICollection<Client> Clients { get; set; }
}
public class Client : BaseEntity
{
[Required]
public string FullName { get; set; }
public DateTime DateOfBirth { get; set; }
public Guid CityId { get; set; }
[ForeignKey("CityId")]
public virtual City City { get; set; }
}
Фильтрация работает отлично, если я ввожу какой-либо текст, целое число или дату, но когда я пытаюсь отфильтровать любой из городов, она работает, только если я ввожу путеводитель по городу. Это не очень удобно для пользователя ...
Буду признателен за любую помощь