Фильтр теряется в WebGrid + Пейджинг + Сортировка + Фильтрация в.NET 4.0

Я реализовал WebGrid. Сортировка, разбиение по страницам и фильтрация не работают вместе. Они работают, когда вы используете их в одиночку. Когда вы объединяете три элемента одновременно, фильтрация не работает.

Симптом:
Фильтруйте набор результатов, затем сортируйте.

или же

Отфильтруйте набор результатов, затем перейдите на следующую страницу.

В обоих случаях фильтр теряется. Но это делает страницу и сортировку.

В следующем коде: Когда метод действия вызывается с помощью сортировки или разбиения на страницы, для каждого из параметров фильтра отображаются значения NULL.

Когда метод действия вызывается через фильтр, параметры фильтра проходят через него.

Это говорит мне, что когда вы запускаете сортировку или нумерацию страниц, она не отправляет форму.

public ActionResult MyPage(int? page, int? rowsPerPage, 
              string sort, string sortdir, 
              string orderNumber, string person, string product)

Я посмотрел вокруг на SO и в других местах. Есть множество примеров, и люди спрашивают, как сделать то или иное или все три. Но я видел только один с моей проблемой, поэтому я публикую ее здесь. (его тоже не удалось решить)

Моя страница реализована следующим образом:

@using (Ajax.BeginForm("MyPage", null, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid" }, new { id = "filter" }))
{
    <div class="right">
        <select id="rowsPerPage" name="rowsPerPage">
            <option>15</option>
            <option>25</option>
            <option>50</option>
            <option>75</option>
            <option>100</option>
        </select>
    </div>  

    <div class="table">
        <div class="tableRow">
            <div class="tableCell">
                Order Number
            </div>
            <div class="tableCell">
                Person
            </div>
            <div class="tableCell">
                Product
            </div>
        </div>
        <div class="tableRow">
            <div class="tableCell">
                <input type="text" id="orderNumber" name="orderNumber" />
            </div>
            <div class="tableCell">
                <input type="text" id="person" name="person" />
            </div>
            <div class="tableCell">
                <input type="text" id="product" name="product" />
            </div>          
            <div class="tableCell">
                <input type="submit" class="button" value="Search" />
            </div>  
        </div>
    </div>

<br/>

<div id="myGrid">
    @Html.Partial("_MyPage", Model)
</div>

}

Сетка реализована в виде частичного вида следующим образом:

<script type="text/javascript">
    $(document).ready(function () {
        resetUI();
    });
</script>

@{
    var grid = new WebGrid(canPage: true, rowsPerPage: Model.rowsPerPage, canSort: true, ajaxUpdateContainerId: "grid", ajaxUpdateCallback: "resetUI");
    grid.Bind(Model.rows, rowCount: Model.TotalRecords, autoSortAndPage: false);
    @grid.GetHtml(
        tableStyle: "fancyTable",
        headerStyle: "header",
        footerStyle: "footer",
        rowStyle: "row",
        alternatingRowStyle: "alt",
        mode: WebGridPagerModes.Numeric | WebGridPagerModes.NextPrevious,
        nextText: "Next",
        previousText: "Previous",
        htmlAttributes: new { id = "grid" },
        columns: grid.Columns(
            grid.Column("OrderDate", "Order Date", format: @<text>@((item.OrderDate != null) && (item.OrderDate.ToString("MM/dd/yyyy") != "01/01/0001") ? item.OrderDate.ToString("MM/dd/yyyy") : "")</text>),
            grid.Column("OrderNumber", "Order Number"),
            grid.Column("Field1, "Field 1"),
            grid.Column("Field2", "Field 2"),
            grid.Column("Person", "Person"),
            grid.Column("Product", "Product"),
            grid.Column(format: (item) => Html.ActionLink("View", "Details", new { id = item.orderNumber }))
            )
        );
}

3 ответа

Решение

При создании ссылок на страницы и сортировку помощник WebGrid учитывает все параметры строки запроса, присутствующие в текущем URL. Он игнорирует значения POSTed и route. А так как ваша форма поиска POSTs, значения, введенные пользователем в этой форме, не присутствуют в строке запроса, поэтому они не являются частью ссылок на страницы и сортировку, и когда вы нажимаете одну из этих ссылок, значения потерял. Это по замыслу.

Итак, один из способов исправить это заменить ваш AjaxForm:

@using (Ajax.BeginForm("MyPage", null, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid" }, new { id = "filter" }))

со стандартной HTML-формой с использованием глагола GET:

@using (Html.BeginForm("MyPage", null, FormMethod.Get))

или AJAX-форма, использующая глагол GET:

@using (Ajax.BeginForm("MyPage", null, new AjaxOptions { HttpMethod = "Get", InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid" }, new { id = "filter" }))

Теперь, когда пользователь захочет что-то отфильтровать и нажмет кнопку "Отправить", значения, введенные им в форму поиска, окажутся в строке запроса и при рендеринге помощник WebGrid будет использовать их для генерации ссылок на сортировку и страницу и, конечно же, когда Вы нажимаете на эти ссылки, значения будут отправлены на сервер.

Если вы хотите больше контроля над этим, вы можете рассмотреть более продвинутые элементы управления сеткой, такие как MvcContrib.Grid или Telerik Grid для ASP.NET MVC.

Отправьте форму по URL-адресу, на который указывает пейджинговая ссылка:

<script type="text/javascript">
     $(function () {
        $('th a, tfoot a').click(function () {
            $('form').attr('action', $(this).attr('href')).submit();
            return false;
        });
    });
</script>

Это не помогает мне, но может помочь вам

Просто создайте GET для вашего метода действия, всякий раз, когда сортировка или пейджинг запускаются из сетки, она попадает в метод GET вместе с большим количеством параметров (Вы можете увидеть, указывая на номер подкачки или сортировать заголовок сетки, используя инструменты веб-разработчика из ваш браузер), там вы можете отфильтровать ваш набор данных, а затем передать модель в представление:

[HttpGet]
public ActionResult MyPage()

Каждый раз, когда вы выполняете Sort или Paging, этот метод срабатывает, затем вы можете выполнить фильтрацию, вы можете добавить несколько статических флагов, которые можно назначать в зависимости от того, что вы хотите отфильтровать.

Другие вопросы по тегам