Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MvcContrib grid and checkboxes

Lets say I render a Checkbox:

@Html.CheckboxFor(x => x.Checked) // Checked is true by default

ASP will turn that as:

<input checked="checked" data-val="true" data-val-required="The field is required." id="Checked" name="Checked" type="checkbox" value="true" />
<input name="Checked" type="hidden" value="false" />

Since ASP outputs two inputs with the same name for a Checkbox, we also get two GET parameters in the URL when submitting the form with the checkbox:

http://...?Checked=true&Checked=false

Lets say I'm also using MvcContrib for displaying a table with sorting.

When I sort a column, MvcContrib is unable to understand the duplicate GET parameters, and instead of writing ?Checked=true&Checked=false, it writes ?Checked=true%2Cfalse, which can't be parsed to a bool by MVC3. The error message after sorting is:

String was not recognized as a valid Boolean.

Has anyone else experienced this problem with the MvcContrib grid?

like image 342
Sheldor the conqueror Avatar asked Oct 12 '12 06:10

Sheldor the conqueror


People also ask

How do you add a checkbox to a grid?

From the GridView s smart tag, click on the Edit Templates link and then drag a CheckBox Web control from the Toolbox into the ItemTemplate . Set this CheckBox s ID property to ProductSelector . With the TemplateField and CheckBox Web control added, each row now includes a checkbox.

How to add checkbox in MVC grid?

There is no direct way to add a CheckBox to the Header Row of WebGrid and hence, using jQuery a dynamic CheckBox is created and it is appended to the first cell of the Header row of the WebGrid. The Header Row CheckBox is assigned a jQuery Click event handler.

How do I set a checkbox in kendo grid?

To set the checked property to true , set it on the dataBound event. $("#grid tbody input:checkbox"). prop("checked", true); To select the checkboxes and the rows they belong to, trigger their click in the dataBound event.

What is MVC grid?

The grid control for ASP.NET MVC is an efficient display engine for tabular data. It will pull from a datasource, such as List of collections, OData web services, or DataManager, binding data fields to columns and displaying a column header to identify the field.


1 Answers

Okay, think I have come up with the solution:

Create your own HtmlTableGridRenderer:

public class CustomTableGridRenderer<TViewModel> : HtmlTableGridRenderer<TViewModel> where TViewModel : class
{
    protected override void RenderHeaderText(GridColumn<TViewModel> column)
    {
        if (IsSortingEnabled && column.Sortable)
        {
            string sortColumnName = GenerateSortColumnName(column);

            bool isSortedByThisColumn = GridModel.SortOptions.Column == sortColumnName;

            var sortOptions = new GridSortOptions
            {
                Column = sortColumnName
            };

            if (isSortedByThisColumn)
            {
                sortOptions.Direction = (GridModel.SortOptions.Direction == SortDirection.Ascending)
                    ? SortDirection.Descending
                    : SortDirection.Ascending;
            }
            else //default sort order
            {
                sortOptions.Direction = column.InitialDirection ?? GridModel.SortOptions.Direction;
            }

            var routeValues = CreateRouteValuesForSortOptions(sortOptions, GridModel.SortPrefix);

            //Re-add existing querystring
            foreach (var key in Context.RequestContext.HttpContext.Request.QueryString.AllKeys.Where(key => key != null))
            {
                if (!routeValues.ContainsKey(key))
                {
                    routeValues[key] = Context.RequestContext.HttpContext.Request.QueryString[key];
                }
            }

            var link = HtmlHelper.GenerateLink(Context.RequestContext, RouteTable.Routes, column.DisplayName, null, null, null, routeValues, null);
            RenderText(link);
        }
        else
        {
            base.RenderHeaderText(column);
        }
    }
}

... and just replace

                if(! routeValues.ContainsKey(key))
                {
                    routeValues[key] = Context.RequestContext.HttpContext.Request.QueryString[key];
                }

... with routeValues[key] = Context.RequestContext.HttpContext.Request.QueryString[key];

And use your new rendering like so:

@Html.Grid()...RenderUsing(new CustomTableGridRenderer())

like image 162
Sheldor the conqueror Avatar answered Sep 20 '22 03:09

Sheldor the conqueror