3

我正在尝试为剑道网格启用不区分大小写的过滤(服务器端)。有谁知道将 tolower(toupper 等)注入过滤器以启用不区分大小写过滤的方法?

背景:

我放入了一个剑道网格以使用来自控制器(EntitySetController.NET 4.5)的数据,一切似乎都运行良好。内联编辑、服务器分页、添加新行等。

为了启用不区分大小写的过滤,我只需构建过滤器,将过滤器文本和字段包裹在 tolower 中(如此推荐)。我还没有找到使用剑道元素自定义过滤器的方法。

控制器:

public class CategoriesController : EntitySetController<Category, int>
{
    public override IQueryable<Category> Get()
    {
        return _repository.Find().OrderBy(c => c.Name);
    }
}

数据源创建:

var serviceBaseUrl = "api/Categories",
    dataSource = new kendo.data.DataSource({
        type: "odata",
        transport: {
            read: {
                url: serviceBaseUrl,
                dataType: "json"
            }
        },
        schema: {
            // omitted for brevity
        },
        serverFiltering: true,
        serverPaging: true,
        pageSize: 10
});

网格创建:

$("#grid").kendoGrid({
    dataSource: dataSource,
    pageable: true,
    filterable: {
        extra: false,
        operators: {
            string: {
                contains: "Contains",
            }
        }
    },
    columns: [
        // omitted for brevity
    ]
});
4

3 回答 3

9

基于完全没有回应,我猜很少有人遇到这个问题,也没有看到我最终想出的明显解决方案。以防万一其他可怜的灵魂像我一样被卡住,这就是我想出的。

数据源上的传输对象需要一个名为 parameterMap 的函数。在那里,执行以下操作:

parameterMap: function (data, type) {
    if (type == "read") {
        if (nameFilter) { // pull nameFilter from a viewmodel or wherever
            data.filter = {
                field: "tolower(Name)",
                operator: "contains",
                value: nameFilter.toLowerCase()
            };
        }

        var newData = kendo.data.transports.odata.parameterMap(data);
        delete newData.$format; // not currently supported by webapi.
        return newData;
    }
},

为了这个答案,我做了一些简化,所以如果这个例子被破坏了,我深表歉意。我尽我所能让它真正发挥作用。

于 2013-08-26T15:57:21.490 回答
3

通过从 https://github.com/telerik/kendo-examples-asp-net下载代码来执行所有操作的服务器端

并更改 QueryableExtensions.cs 函数过滤器

对此

    private static IQueryable<T> Filter<T>(IQueryable<T> queryable, Filter filter)
    {
        if (filter != null && filter.Logic != null)
        {
            // Collect a flat list of all filters
            var filters = filter.All();

            // Get all filter values as array (needed by the Where method of Dynamic Linq)
            var values = filters.Select(f => f.Value is string ? f.Value.ToString().ToLower() : f.Value).ToArray();

            //Add toLower() for all filter Fields with type of string in the values 
            for (int i = 0; i < values.Length; i++)
            {
                if (values[i] is string)
                {
                    filters[i].Field = String.Format("{0}.ToString().ToLower()", filters[i].Field);
                }
            }
            // Create a predicate expression e.g. Field1 = @0 And Field2 > @1
            string predicate = filter.ToExpression(filters);


            // Use the Where method of Dynamic Linq to filter the data
            queryable = queryable.Where(predicate, values);
        }

        return queryable;
    }
于 2015-08-28T13:55:00.343 回答
0

我知道这是一个老问题,但我认为这对于正在寻找答案的其他人来说应该是一个有用的解决方案:

parameterMap: function (options, operation) {
    if (operation == "read") {
        if (options.filter) {
            //console.log(`options: ${JSON.stringify(options)}`);

            var newFilter = {
                logic: options.filter.logic,
                filters: []
            };

            $.each(options.filter.filters, function (index, filter) {
                var fieldName = filter.field;
                var fieldType = $('#grid').data("kendoGrid").dataSource.options.schema.model.fields[fieldName].type;
                //console.log(`field: ${fieldName} has type: ${fieldType}`);

                if (fieldType == "string") {
                    var newFilterField = {
                        field: `tolower(${filter.field})`,
                        operator: filter.operator,
                        value: filter.value.toLowerCase()
                    };
                    newFilter.filters.push(newFilterField);
                }
                else {
                    newFilter.filters.push(filter);
                }
            });

            options.filter = newFilter;
        }

        var paramMap = kendo.data.transports["odata-v4"].parameterMap.call(this, options, operation);
        return paramMap;
    }
}

请注意,我确实ignoreCase在列中看到了一个选项。这是一个示例(取自columns.filterable.ignoreCase):

$("#grid").kendoGrid({
    columns: [{
        field: "country",
        filterable: {
            multi: true,
            search: true,
            ignoreCase: true // <-- Here
        }
    }],
    filterable: true,
    dataSource: [{ country: "BG" }, { country: "USA" }]
});

但是,这似乎没有任何作用..至少在使用 OData 时是这样。

于 2022-02-05T00:58:00.460 回答