Kendo Jquery Grid-过滤逗号分隔值列

时间:2019-05-28 03:14:06

标签: jquery jquery-ui filter kendo-ui kendo-grid

我们有一个Kendo Jquery Grid,并且我们试图在Column上提供过滤器,以逗号分隔的形式显示值。代码如下所示,我试图在dataBound事件中捕获过滤器对象,并尝试通过数据源过滤出记录,但无济于事。请提出我们如何实现这一目标。

我们需要实现的字段是 ProviderSpecialty

<script>
    var grid;
    var dataSource;
    var gridView = 'updatesRequired';

    $(document).ready(function () {
        $('#selectGridView').change(function () {
            gridView = $('#selectGridView').val();
            $('#grid').kendoGrid('destroy').empty();
            renderGrid();
        });
        renderGrid();
    });

    function renderGrid() {

        var fieldsSchema =
        {
            'ProviderDelegateId': { type: 'number' },
            'EndDate': {type: 'date' }
        };
        dataSource = new kendo.data.DataSource({
            transport: {
                read: {
                    url: providerProfileApiBaseUrl)
                }
            },
            error: function (e) {
                if (e.xhr.responseText != '') {
                    var jsonError = JSON.parse(e.xhr.responseText);

                    if (myApp.Web.utility.displacolumns !== undefined) {
                        myApp.Web.utility.displacolumns.push({
                            field: 'EndDate', template: '#= kendo.toString(kendo.parseDate(EndDate), "MM/dd/yyyy")#', title: 'Campaign End Dt', width: '125px', filterable: {
                                ui: function (element) {
                                    element.kendoDatePicker({
                                        format: "MM/dd/yyyy"
                                    });
                                }
                            }
                        });
                    }
                    myApp.Web.utility.displayErrorDialog(jsonError.error);
                }
            },
            pageSize: myApp.Web.config.grid.pageable.pageSize,
            schema: {
                model: {
                    id: 'UniqueId',
                    fields: fieldsSchema
                }
            },
            sort: { field: "ProviderLastName", dir: "asc" }
        });

        var columns = [];
        columns.push({ field: 'ProviderDelegateId', hidden: true });
        if (gridView === 'updatesRequired') {
            columns.push({ field: 'ProviderLastName', title: 'Last Name', width: '125px', template: '<a href="/ProviderLanding/ProviderUpdate/Index/#=CampaignTrackingId#">#=ProviderLastName#</a>' });
            columns.push({ field: 'ProviderFirstName', title: 'First Name', width: '125px', template: '<a href="/ProviderLanding/ProviderUpdate/Index/#=CampaignTrackingId#">#=ProviderFirstName#</a>' });
            columns.push({ field: 'ProviderNPI', title: 'NPI', width: '125px', template: '<a href="/ProviderLanding/ProviderUpdate/Index/#=CampaignTrackingId#">#=ProviderNPI != null ? ProviderNPI : \'\' #</a>' });
        } else {
            columns.push({ field: 'ProviderLastName', title: 'Last Name', width: '125px', template: '<a href="/ProviderUpdate/UpdateProfile?providerId=#=ProviderId#">#=ProviderLastName#</a>' });
            columns.push({ field: 'ProviderFirstName', title: 'First Name', width: '125px', template: '<a href="/ProviderUpdate/UpdateProfile?providerId=#=ProviderId#">#=ProviderFirstName#</a>' });
            columns.push({ field: 'ProviderNPI', title: 'NPI', width: '125px', template: '<a href="/ProviderUpdate/UpdateProfile?providerId=#=ProviderId#">#=ProviderNPI != null ? ProviderNPI : \'\' #</a>' });
        };
        columns.push({ field: 'ProviderSpecialty', title: 'Specialty', width: '125px', template: '#= getSpecialties(ProviderSpecialties) #' });
        columns.push({ field: 'ProviderEmail', title: 'Email', width: '125px' });
        columns.push({ field: 'LocationName', title: 'Location', width: '125px', template: '#= getLocations(ProviderLocations) #'  });
        if (gridView === 'updatesRequired') {
            columns.push({ field: 'CampaignName', title: 'Campaign', width: '125px', template: '<a href="/ProviderLanding/ProviderUpdate/Index/#=CampaignTrackingId#">#=CampaignName#</a>' });
            columns.push({
                field: 'EndDate', template: '#= kendo.toString(kendo.parseDate(EndDate), "MM/dd/yyyy")#', title: 'Campaign End Dt', width: '125px', filterable : {
                ui: function (element) {
                    element.kendoDatePicker({
                        format: "MM/dd/yyyy"
                    });
                }
            } });
        } else {
            columns.push({ field: 'IsPendingChangeAvailable', title: 'Pending Changes', width: '125px', template: '#if (IsPendingChangeAvailable) {# Yes #} else {# No #}#' });
        };

        grid = $("#grid").kendoGrid({
            dataSource: dataSource,
            columns: columns,
            scrollable: false,
            filterable: myApp.Web.config.grid.filterable,
            sortable: myApp.Web.config.grid.sortable,
            pageable: myAppWeb.config.grid.pageable,
        }).data('kendoGrid');
    };

    function getSpecialties(specialties) {
        // remove duplicates and then join...
        var result = [];
        $.each(specialties, function(i, e) {
            if ($.inArray(e.SpecialtyName, result) == -1) result.push(e.SpecialtyName);
        });
        return result.join(',');
    };

    function getLocations(locations) {
        return locations.map(function (location) {
            return location.LocationName
        }).join(',');
    };

    $(document).ajaxStart(function () {
        $('#overlay-screen').show();
    });
    $(document).ajaxStop(function () {
        $('#overlay-screen').hide();
    });
</script>

2 个答案:

答案 0 :(得分:0)

过滤器框不允许您添加逗号。我不确定您是否可以使用逗号来完成此操作,除非您覆盖UI以显示自己的过滤器框,并在更改时通过jquery / javascript应用过滤器,如下所示。如果我正确理解您的话。

//After user enters their values. Imagine "Tom,John" would be what the user entered
//After you exploded the comma list yourself
$('#grid').data('kendoGrid').dataSource.filter({
    logic: "or",
    filters: [
       { field: "Name", operator: "contains", value: 'Tom' },
       { field: "Name", operator: "contains", value: 'John' },
    ]
});

很明显,如果您还允许过滤其他列,那将更加先进。相反,您将修改过滤器而不是覆盖它们。请注意,我的示例使用了contains。如果您需要的话,这可以是等式。但是,假设要过滤的列是文本,则可以在可过滤对象上使用“ mulit:true”。这允许用户使用kendo的UI元素来管理选择

//On the column property
filterable: {
    multi:true
}

这将为您提供该列中每个可能值的复选框。请注意,如果您将网格的可过滤对象的模式设置为行。这是行不通的

//On the grid
filterable: {
    mode: "row"
}

从dojo中的以下链接打开代码 https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/configuration/columns.filterable.multi

希望这会有所帮助

答案 1 :(得分:0)

可以通过在三个位置更改网格的默认行为来解决此问题。

1。更改给定列的配置

在列可过滤配置中添加一个附加属性,以指示应应用特殊逻辑。 column.filterable = {multi:true,isCommaSeparatedList:true}

2。在过滤器菜单初始化(filterMenuInit事件)期间更改多重选择的数据源
从网格列集合中获取该列,并检查可过滤对象是否包含用户定义的属性“ isCommaSeparatedList”。

 filterMenuInit(event: kendo.ui.GridFilterMenuInitEvent) {
        const field = event.field;

        //Get the column where the user wants to set the filter
        filteredColumn = event.sender.columns.filter((column) => { return column.field === field })[0] as kendo.ui.GridColumn;
        if (filteredColumn && typeof filteredColumn.filterable === "object" && filteredColumn.filterable["isCommaSeparatedList"]) {

            //Declare an array to hold the unique select items
            var selectItems = new Array();

            //Declare an dictionary for fast lookup
            var valuesDictionary = new Object();

            //Get the data from the grid
            const gridRecords = event.sender.dataSource.data().toJSON();

            //Loop the records an find the individual values in the comma separated list
            for (let gridRecord of gridRecords) {
                const values = gridRecord[field].toString().split(",") as Array<string>;
                values.forEach((value) => {
                    value = value.trim();
                    //If the value is not found in the dictionary then the value is added to the dictionary and the selectItems Array
                    if (!valuesDictionary[value]) {
                        valuesDictionary[value] = true;
                        selectItems.push({ [field]: value });
                    }
                });
            }

            //Sort the selectItems
            selectItems.sort((a, b) => {
                if (a[field] < b[field]) return -1;
                else if (a[field] > b[field]) return 1;
                return 0;
            });

            //Set the datasource for the multi select column to the items found
            const filterable = filteredColumn.filterable as any as kendo.ui.GridColumnFilterable;
            filterable.dataSource.data(selectItems);
        }

3。用户选中或取消选中一个或多个项目(过滤器事件)后更改过滤器
如果将列的可过滤属性设置为{multi:true},则在通过选中或取消选中过滤器菜单中的复选框更改过滤器时,将导致将运算符设置为“ eq”的过滤器。这不是我们想要的水。因为基础数据源包含逗号分隔的列表。因此,我们希望运算符为“包含”。我使用的技巧是在网格“ filter”事件中复制过滤器表达式。我遍历应用于给定列的所有过滤器,并添加相同的过滤器,但使用operator =“ contains”

       filter: (event: kendo.ui.GridFilterEvent) => {
            //This function is called each time the filter in the grid is changed.
            if (event.filter) {
                //Try to get the column definition from the columns dictionary for the column where the filter has changed.
                const column = event.sender.columns.filter((column) => { return column.field === event.field })[0] as kendo.ui.GridColumn;

                //Find out if the filterable property of the column is set to an object and if the object has a property "isList"
                if (column && column.filterable && typeof column.filterable === "object" && column.filterable["isCommaSeparatedList"]) {
                    //Duplicate all the filters with an operator = "eq" to a filter with operator = "contains"
                    for (let filter of event.filter.filters) {
                        if (filter.operator === "eq" && !filter["handled"]) {
                             //Add a handled property to check if the filter has already been duplicated to prevent an endless loop
                            filter["handled"] = true;
                            event.filter.filters.push({ value: filter.value, operator: "contains", field: filter.field });
                        }
                    }
                }
            }
        }

希望这对您有用