0

I am trying to create a "Lock"/"Unlock" button/link that a user can click in a grid listing user accounts using MVC4. In WebForms, this is a relatively simple task of putting an ImageButton into the grid template for the column and connecting it to the Command event for that button and then chaning the "Lock"/"Unlock" text displayed against that user. But I cannot seem to quite figure out how to do this in MVC4. Or at least not without jumping through quite a few hoops to get ajax/jquery to play nice with each user in the grid.

Currently I have the grid listing the users registered on the system and this grid is correctly displaying. The grid displays in a simple view and the controller returns a model with a property of Users. This property in turn is a list of UserInfo objects with basic user details such as UserName, Name and IsActive.

I have tried playing around with using Html.RenderAction to call a dedicated action called Lock that does the task but kept getting errors trying to pass in the user details to the controller (In ASP.NET MVC 2 - How do I get Route Values into my navigation controller so I can highlight the current link? - didn't work for me).

Likewise, I tried creating a partial view but again, kept getting errors (Html.RenderPartial giving me strange overload error? and no, it didn't work for me either).

I've been trawling through SO researching these individual issues and alternative methods of doing what I want to do for a day now and I'm no closer to succeedign in this task.

Is there a simple way of doing what I describe? Do I have to write out individually numbered element tags for each user row to attach jquery functions to?

UPDATE Code generating the grid;

if (Model != null && Model.Users != null && Model.Users.Count > 0)
{
    <table class="table table-striped">
        <tr>
            <th>
                User
            </th>
            <th>
                Name
            </th>
            <th>
                Lock/Unlock
            </th>
        </tr>
        @foreach (UserInfoModel user in Model.Users)
        {
            <tr>
                <td>
                    @Html.ActionLink(user.UserName, "Edit", new { id = user.PersonID })
                </td>
                <td>
                    @Html.DisplayFor(m => user.Name)
                </td>
                <td>
                    @*@Html.Action("Lock", new { personID = user.PersonID, isLocked = null as bool?})*@
                    @*@{ Html.Render("_Lock", new { personID = user.PersonID, isLocked = null as bool? }); }*@
                    @Html.ActionLink("Lock", "Lock", new { personID = user.PersonID, lockAccount = user.IsActive })
                </td>
            </tr>
        }
    </table>

The controller code attempt;

[Authorize(Roles = LMSRoles.Administrators)]
public ActionResult Lock(int personID, bool lockAccount)
{
    return Json(null, JsonRequestBehavior.AllowGet);// PartialView("_Lock");
}
Community
  • 1
  • 1
DiskJunky
  • 4,750
  • 3
  • 37
  • 66
  • how are you creating the grid? show us some code. Usually, I would add a class to each button/links on the grid and use jquery selector to handle the `click` event. Personally, I feel more confirtable with this rather than the traditional approach :-) – NaveenBhat Sep 12 '13 at 14:36
  • @NaveenBhat I have added the code generating the grid. I've left in the two (now commented out), previous attempts to get it to display – DiskJunky Sep 12 '13 at 14:43

1 Answers1

1

Your code looks fine. As soon as you click on the link Lock, it should redirect to the action Lock (if the user is authorized with the role Administrators).

It seem that you would rather want to do an ajax request. In that case, I prefer to use jquery as I said in the comments earlier.

In-order to do that, alter your ActionLink like this:

@Html.ActionLink("Lock", "Lock", 
     new { personID = user.PersonID, lockAccount = user.IsActive }, 
     new { @class="lock" }) // Add a dummy css class 'lock'

Write the below script, inside document's ready event handler:

// Register click handler for any element with the class 'lock' (works only if the element an 'a' tag).
$('.lock').click(function (e) {
    // Prevent the default functionality.
    e.preventDefault();

    // Do the get ajax request (you can do post as well, but not required in this case).
    $.ajax({
        type: "GET",
        url: $(this).attr('href'), // Take the URL from link's href
        contentType: 'application/json',
        async: true,
        beforeSend: function () {
            // Display loading image
        },
        success: function (result) {
            // Handle the response here. Ex: Inform the user that, lock operation is succeeded.
        },
        complete: function () {
            // Hide loading image.
        },
        error: function (jqXHR, textStatus, errorThrown) {
            // Handle error.
        }
    });

});

The code is simple & self-explanatory but still I put detailed comments, assuming that jquery is new for you.

PS: Don't forget to include jquery file, before you use this script.

NaveenBhat
  • 3,248
  • 4
  • 35
  • 48