0

I'm having an issue getting my filtered results to post back into the paged, sorted webgrid properly. For example, my grid is limited to 5 items per page, but if the filter search returns 9 items, all 9 items are displayed on one page instead of broken over two pages but I'll still have "next" and "prev" page links like the grid doesn't even know that it's displaying the filtered results.

Then if I try to sort the filtered results I lose the filter altogether and am returned to non-filtered webgrid data.

Can you help me understand why the filtered results aren't posting into the webgrid properly?

Here's my controller:

using System.Linq;
using System.Web.Mvc;
using SchedulerManager.Models;

namespace SchedulerManager.Controllers
{
    public class ScheduleController : Controller
    {
         readonly ModelServices _mobjModel = new ModelServices();

         public ActionResult Index()
         {
             var schedules = _mobjModel.GetSchedules();
             return View(schedules);
         }

        [HttpPost]
        public ActionResult Index(string description)
        {
            var schedules = _mobjModel.GetSchedules();

            if (!string.IsNullOrEmpty(description))
                schedules = schedules.Where(s => s.Description.ToLower().Contains(description.ToLower())).ToList();

            return PartialView("_grid", schedules);
        }
    }
}

Here is my model:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Scheduler;

namespace SchedulerManager.Models
{
    public class ModelServices : IDisposable
    {
        private readonly Entities _entities = new Entities();

        public IEnumerable<Schedule> GetSchedules()
        {
            return _entities.Schedules.ToList();
        }

        public void Dispose()
        {
            _entities.Dispose();
        }
    }
}

Here is my index.cshtml:

@model IEnumerable<Schedule>
@using Scheduler
@using System.Globalization
@{
    ViewBag.Title = "Schedules";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<script src="../../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
@using (Ajax.BeginForm(new AjaxOptions 
    { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid" }))
{
    <fieldset>
        <legend>Schedules</legend>
        <div>
            Description: 
            <input type="text" id="description" name="description" /> 
            <input type="submit" value="Search" />
        </div>
    </fieldset>
}

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

And here is my _grid.cshtml:

@model IEnumerable<Schedule>
@using Scheduler

@{
    var grid = new WebGrid(Model, rowsPerPage: 5, ajaxUpdateContainerId: "grid");

    @grid.GetHtml(htmlAttributes: new { id = "grid" },
                  fillEmptyRows: false,
                  alternatingRowStyle: "alternate-row",
                  headerStyle: "grid-header",
                  footerStyle: "grid-footer",
                  mode: WebGridPagerModes.All,
                  firstText: "<< First",
                  previousText: "< Prev",
                  nextText: "Next >",
                  lastText: "Last >>",
        columns: new[] {
        grid.Column("Description", style: "description"),
        grid.Column("ScheduleType", "Type", style: "scheduletype"),
        grid.Column("EnableDate", "Enable Date", s=>s.EnableDate.ToShortDateString(), style: "enabledate"),
        grid.Column("DisableDate", "Disable Date", s=>s.DisableDate != null ? s.DisableDate.ToShortDateString() : "", style: "disabledate"),
        grid.Column("", "", 
                @<text>
                    @(Html.ActionLink("Edit", "Edit", new { id = item.ScheduleId }, new { @class = "actionlink" }))
                    |
                    @(Html.ActionLink("Delete", "Delete", new { id = item.ScheduleId }, new { @class = "actionlink" }))
                </text>)
        })
}
4

1 回答 1

1

First make sure that you have included the jquery.unobtrusive-ajax.js script to your page (after jquery) or your Ajax.BeginForm won't do what you think it will:

<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
<script type="text/javascript" src="@Url.Content("~/scripts/jquery.unobtrusive-ajax.js")"></script>

then you could use a GET request for the Search form so that the search criteria gets properly rendered as query string in the pagination anchors that will be generated after the search:

@using (Ajax.BeginForm("filter", new AjaxOptions { HttpMethod = "GET", InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid" }))
{
    <fieldset>
        <legend>Schedules</legend>
        <div>
            Description: 
            <input type="text" id="description" name="description" /> 
            <input type="submit" value="Search" />
        </div>
    </fieldset>
}

Finally rename your controller action and enable it to GET requests:

public class ScheduleController : Controller
{
    readonly ModelServices _mobjModel = new ModelServices();

    public ActionResult Index()
    {
        var schedules = _mobjModel.GetSchedules();
        return View(schedules);
    }

    public ActionResult Filter(string description)
    {
        var schedules = _mobjModel.GetSchedules();

        if (!string.IsNullOrEmpty(description))
        {
            schedules = schedules.Where(s => s.Description.ToLower().Contains(description.ToLower())).ToList();
        }

        return PartialView("_grid", schedules);
    }
}
于 2013-03-29T16:15:53.370 回答