Search code examples
asp.net-mvcrazorasp.net-mvc-5webgrid

Updating a Partial View From A Link In Its Own WebGrid


This is pretty much my third day developing MVC and I have what I hope will be a simple question. Basically I have a WebGrid within a partial view, which has a column that performs an update via a controller.

The controller then returns the updated partial view successfully, but the it replaces the whole page with the results instead of just the partial view.

Here's the partial view:

@model Site.Models.UsersForCompanyModel

@{
    ViewBag.Title = "Admin User Management Grid";
}

    @{
        var grid = new WebGrid(

        Model.Users,
        ajaxUpdateContainerId: "divUserGrid",
        fieldNamePrefix: "gridItems_",
        pageFieldName: "paging",
        sortFieldName: "sortField"
        );

        grid.Pager(WebGridPagerModes.All);

        var userColumns = new List<WebGridColumn>
        {
            new WebGridColumn {ColumnName = "Email", Header = "E-Mail", CanSort = true},
            new WebGridColumn {Header = "Lock", Format = user => user.isAdmin ? Html.Raw("n/a") :  Html.ActionLink(user.IsLocked ? "Unlock" : "Lock", "ToggleLock", new {userId = user.Id, companyId = Model.CompanyId}) },
        };

        <div id="divUserGrid">
            @grid.GetHtml(
             htmlAttributes: new { id = "userGrid" },
             tableStyle: "table table-striped table-bordered",
             columns: userColumns
             )
        </div>
    }

...and here's the controller code:

    public ActionResult GetUsersForCompany(string companyId)
    {
        using (var service = new ManagementService())
        {
            var model = GetUsersForCompany(companyId, service);
            return PartialView("AdminUserManagement_Grid", model);
        }
    }

    public ActionResult ToggleLock(string companyId, string userId)
    {
        using (var service = new ManagementService())
        {
            var user = service.GetUserById(userId);
            service.LockUser(userId, !user.IsLocked);
            return GetUsersForCompany(companyId);
        }
    }

What's the easiest way to go about updating the partial view with the results returned from ToggleLock()?

Is there a way to do it declaratively via Html.ActionLink or Ajax.ActionLink?


Solution

  • Thanks, Kartikeya. Partial credit for the answer, though I found a declarative way that didn't require manual HTML/event wiring and custom javascript.

    The key was simply switching to an Ajax.ActionLink (instead of using Html.ActionLink), then setting my partial view placeholder ID (I had a div setup similar to Kartikeya's example) and a few other parameters in the AjaxOptions of the control, like this:

    new WebGridColumn {Header = "Lock", 
        Format = user => user.isAdmin ? Html.Raw("n/a") : 
                Ajax.ActionLink( user.IsLocked ? "Unlock" : "Lock",
                     "ToggleLock",
                      new{userId = user.Id, companyId = Model.CompanyId },
                     new AjaxOptions
                     {
                         UpdateTargetId="userGridPlaceholder", // <-- my grid placeholder
                         InsertionMode = InsertionMode.Replace, 
                         HttpMethod = "GET" 
                     })