Grid Custom Filter for Columns Not In Grid

2019-08-05 17:58发布

I have a grid which is filtered by another area on the page. I've already figured out how to pass the filter arguments to filter grid columns via javascript/ajax. However, I want to pass custom filter arguments (that don't have a column) to do additional filtering server-side.

In my case, a user can have 0:M roles. I'm not showing the roles in the KendoUI Grid, however I want to select 0:M roles in a multiselct box and pass the selections to the grid's filter call so that I can use the values server side in my stored proc. Anyone know how to do this? This is my current setup.

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)

<fieldset>
    <legend>Account Filter</legend>

    <table>
        <tr>
            <td style="vertical-align: top;">
                <div class="editor-label">
                    <label>User Name:</label>
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.UserName)
                    @Html.ValidationMessageFor(model => model.UserName)
                </div>

                <div class="editor-label">
                    <label>Email:</label>
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.PrimaryEmailAddress)
                    @Html.ValidationMessageFor(model => model.PrimaryEmailAddress)
                </div>

                <p>
                    <input type="button" id="btnFilter" value="Filter" />
                </p>
            </td>
            <td>&nbsp;</td>
            <td style="vertical-align: top;">
                <div class="editor-label">
                    <label>Role(s):</label>
                </div>
                <div class="editor-field">
                    @Html.DropDownListFor(model => model.RolesList, Model.RolesList, null, htmlAttributes: new { id="ddlTimeZones", multiple="multiple" })
                    @Html.ValidationMessageFor(model => model.RolesList)
                </div>
            </td>
        </tr>

    </table>
</fieldset>
}

<div style="margin-top: 10px;">
@(Html.Kendo().Grid<AccountGridModel>()    
    .Name("grdAccounts")
    .Columns(columns =>
    {
        columns.Bound(m => m.UserId);
        columns.Bound(m => m.UserName);
        columns.Bound(m => m.FirstName);
        columns.Bound(m => m.LastName);
        columns.Bound(m => m.PrimaryEmailAddress);
    })
    .Groupable(grouping => grouping
        .Enabled(true))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model => model.Id(m => m.UserId))
        .Events(events => events.Error("error_handler"))
        .Read(read => read.Action("Index", "Accounts"))
        .Sort(sort => sort.Add(m => m.UserName).Ascending())
        .PageSize(20))
    .Filterable(filtering => filtering
        .Enabled(false))
    .Pageable(paging => paging
        .Enabled(true)
        .Info(true)
        .PageSizes(false)
        .Refresh(true))
    .Scrollable(scrolling => scrolling
        .Enabled(false)
        .Height(400)
        .Virtual(false))
    .Sortable(sorting => sorting
        .Enabled(true)
        .AllowUnsort(false)
        .SortMode(GridSortMode.SingleColumn)))
</div>

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")

<script type="text/javascript">
    $("#btnFilter").click(function () {
        //var dateFrom = $("#dpDateFrom").data("kendoDatePicker").value();
        var userName = $("#UserName").val();
        var primaryEmail = $("#PrimaryEmailAddress").val();

        var grid = $("#grdAccounts").data("kendoGrid");

        grid.dataSource.filter({
            logic: "and",
            filters: [
                { field: 'UserName', operator: 'contains', value: userName },
                { field: 'PrimaryEmailAddress', operator: 'contains', value: primaryEmail },
                { field: 'RoleIdList', operator: 'contains', value: '1,2,3,4' } //this errors... no column
            ]
        });
    });
</script>
}

标签: kendo-ui
2条回答
何必那么认真
2楼-- · 2019-08-05 18:22

Thanks to Pechka for starting me in the right direction. You can pass additional values to your controller via the Read.Data javascript function shown below.

<div style="margin-top: 10px;">
@(Html.Kendo().Grid<AccountGridModel>()    
    .Name("grdAccounts")
    .Columns(columns =>
    {
        columns.Bound(m => m.UserId);
        columns.Bound(m => m.UserName).Filterable(false);
        columns.Bound(m => m.FirstName);
        columns.Bound(m => m.LastName);
        columns.Bound(m => m.PrimaryEmailAddress).Filterable(false);
    })
    .Groupable(grouping => grouping
        .Enabled(true))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model => model.Id(m => m.UserId))
        .Events(events => events.Error("error_handler"))
        .Read(read => read.Action("Index", "Accounts").Data("additionalData"))
        .Sort(sort => sort.Add(m => m.UserName).Ascending())
        .PageSize(20))
    .Filterable(filtering => filtering
        .Enabled(true))
    .Pageable(paging => paging
        .Enabled(true)
        .Info(true)
        .PageSizes(false)
        .Refresh(true))
    .Scrollable(scrolling => scrolling
        .Enabled(false)
        .Height(400)
        .Virtual(false))
    .Sortable(sorting => sorting
        .Enabled(true)
        .AllowUnsort(false)
        .SortMode(GridSortMode.SingleColumn)))
</div>

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")

<script type="text/javascript">
    function additionalData() {
        var userName = $("#UserName").val();
        var primaryEmailAddress = $("#PrimaryEmailAddress").val();
        var roleIdList = "";

        var selMulti = $.map($("#RolesList option:selected"), function (el, i) {
            return $(el).val();
        });
        roleIdList = selMulti.join(",");

        return {
            userName: userName,
            primaryEmailAddress: primaryEmailAddress,
            roleIdList: roleIdList
        };
    }

    $("#btnFilter").click(function () {
        var grid = $("#grdAccounts").data("kendoGrid");
        grid.dataSource.read();
    });
</script>
}

Then, in your controller, add variables to your POST function like so:

        //
    // POST: /Admin/Accounts/

    [HttpPost]
    public ActionResult Index([DataSourceRequest] DataSourceRequest request, string userName, string primaryEmailAddress, string roleIdList)
    {
    }
查看更多
贪生不怕死
3楼-- · 2019-08-05 18:25

You should use the function called data on the dataSource.read configuration.

查看更多
登录 后发表回答