Skip to content
Leonid Gordo edited this page May 5, 2012 · 2 revisions

#Model Binders

MvcBlanketLib provides the following additional model binders:

  • GroupEntityActionModelBinder

##GroupEntityActionModelBinder

This model binders allows to bind to the model the postback from the pages with entities list which allow the group action with these entities.

To use this model binder first of all you should register the model binder. Add the following method to your global.asax.cs file:

private void RegisterModelBinders()
{
    ModelBinderProviders.BinderProviders.Add(new GroupEntityActionModelBinderProvider());
}

Add method call to the Application_Start method:

protected void Application_Start()
{
        AreaRegistration.RegisterAllAreas();
        RegisterRoutes(RouteTable.Routes);
        RegisterModelBinders();
}

From now on, you can use the new functionality. Append the checkbox column to the grid you use to display entries list. Insert the grid inside the action form.

@Html.BeginActionForm()

@Html.Grid(Model.Users.PagedList).Columns(
    column =>
    {
        column.For(x => x.Login);
        column.For(x => x.EMail);
        column.For(x => Html.RawCheckBox("chk", x.Id, "chk")).Named("").Sortable(false).Header(@<input
            type='checkbox' id='chkHeader' />).InsertAt(0);
    }
)

@Html.EndActionForm()

Look at the last column.For line, you can see it insert at the beginning of the grid the column with checkboxes and header with the checkbox that allows to select/deselect all rows at once.

To enable `select/deselect all' add the following javascript code:

(function ($, undefined) {
$(function () {
    $("#chkHeader").change(function () {
        if ($(this).is(":checked"))
            $(".chk").attr("checked", "checked");
        else
            $(".chk").removeAttr("checked");
    });

    $(".chkHeader").change(function () {
        if ($(this).is(":checked"))
            $(".chk").attr("checked", "checked");
        else
            $(".chk").removeAttr("checked");
    });
});
})(jQuery);

Add command buttons to submit the actions:

@Html.ActionButton(this.GetActionEnumString(UserActions.Activate), "Activate users", "Select users to activate")
@Html.ActionButton(this.GetActionEnumString(UserActions.Deactivate), "Deactivate users", "Select users to deacticate")
@Html.ActionButton(this.GetActionEnumString(UserActions.Delete), "Delete users", "Select users to delete", "Are you sure you want to delete these users?")

This is done using additional HtmlHelper extension method ActionButton. It accepts four parameters:

  • Name - action key, you can set here a simple string like 'activate' or something like this, or you can use special WebPage extension method GetActionEnumString to retrieve this string from the annotated enumeration.
  • Text - text that will be displayed onto the command button
  • IfNothingSelectedText - optional parameter, defines the text that will be displayed in the alert popup in the case if user press the button with no entries selected.
  • ConfirmText - optional parameter, defines the text that will be displayed in the alert popup to demand user confirmation of the dangerous action.

Create enumeration like this:

public enum UserActions
{
    Activate,
    Deactivate,
    Delete
}

where you enumerate all possible actions user can do. Now annotate each entry with FlagString attribute where you can set string representation of each entry.

public enum UserActions
{
    [FlagString(StringRepresentation = "activate")]
    Activate,
    [FlagString(StringRepresentation = "deactivate")]
    Deactivate,
    [FlagString(StringRepresentation = "delete")]
    Delete
}

GetActionEnumString eject this annotated information from the enumeration you provided and return its string representation.

To action buttons properly operate add the following javascript code:

(function ($, undefined) {
$(function () {
     $(".cmdbtn").click(function () {
        if ($("#chk:checked").length == 0) {
            alert($(this).data("empty"));
            return;
        }
        var confirmMsg = $(this).data("confirm");
        if (confirmMsg != undefined) {
            if (!confirm(confirmMsg))
                return;
        }
        $("#action").val($(this).attr("id"));
        $("#mform").submit();
    });
});
})(jQuery);

Now create the action method that will process the postback from the user.

[HttpPost]
public ActionResult Index(GroupAction<UserActions, int> action)
{
        switch (action.Action)
        {
            case UserActions.Activate:
                UsersRepository.ActivateUsers(action.Identifiers, true);
                break;
            case UserActions.Deactivate:
                UsersRepository.ActivateUsers(action.Identifiers, false);
                break;
            case UserActions.Delete:
                UsersRepository.DeleteUsers(action.Identifiers, false);
                break
        }
        UsersRepository.Save();

        return RedirectToAction("Index");
}

Your action method accepts the model of type GroupAction<,> or GroupAction<> which is shortcut for GroupAction<string,>. First generic parameter defines the type of action key (your previously annotated via enumeration). It can be an enumeration member like in the example above or any other simple type (like string, int, float, etc.). Second generic parameter defines the type of entities identifiers user selected.

Clone this wiki locally