Search code examples
asp.net-mvc-4razor-2

Html.CheckBox not being set [asp.net mvc 4]


I am having a bit of a headache with a thing (I know something like has been asked before, but I'm pretty sure it's not quite the same thing). To the point: I have a View with a Telerik grid. On that grid I show some stuff from the model that I pass to the View BUT I want in the final column to put a CheckBox that is checked/unchecked based on some things in the Controller (the checks have nothing to do with the model that is being passed). In my ActionResult function that takes care of the View I store some Boolean values in the ViewData, and then I set the isChecked value in the CheckBox based on the values stored in the ViewData.

The code for the ActionResult is as follows:

    [SecureThis(Roles = "User")]
    public ActionResult Index()
    {
        //get bucket ids
        var buckets = db.Buckets.ToList();
        int i=1;
        string cb = "checkbox" + i.ToString();
        foreach (Bucket b in buckets)
        {
            var payByInvoice = db.PaymentOptions.Where(p => p.BucketId == b.Id).Select(p => p.CanPayByInvoice).SingleOrDefault();
            if (payByInvoice == (int)PayByInvoiceState.Accepted)
                ViewData["checkbox" + i.ToString()] = true;
            else ViewData["checkbox" + i.ToString()] = false;
                i++;
                cb = "checkbox" + i.ToString();
        }
        return View(db.Buckets);
    }

And the grid that should show all the stuff is this:

@{
int i=1;
string cb = "checkbox" + i.ToString();
 }
@(Html.Telerik().Grid(Model)
        .Name("BucketsGrid")
        .DataKeys(keys => keys.Add(bucket => bucket.Id))
        .Columns(
            columns =>
            {
                columns.Template(model => ViewData[model.Id.ToString()])
                    .HeaderTemplate(
                    @<b>@Strings.Title_Customer</b>
                    );
                columns.Bound(model => model.CreditFacility);
                columns.Bound(model => model.Minimum);
                columns.Bound(model => model.RefillLevel);
                columns.Bound(model => model.NotificationEmail);
                columns.Bound(model => model.NotificationSms);
                columns.Template(model => Html.ActionLink(Strings.Edit, "Edit", new { id = model.Id }));
                columns.Template(model => Html.ActionLink(Strings.NotificationOptions, "Bucket", "NotificationOptions", new { id = model.Id }, null));
                columns.Template(model => Html.ActionLink("Refill", "Refill", "Payment", new { id = model.Id }, null));
                columns.Template(model => Html.ActionLink(Strings.Details, "Details", new { id = model.Id }));
                columns.Template(model => Html.ActionLink(Strings.Delete, "Delete", new { id = model.Id }));
                columns.Template(model => Html.CheckBox("invoice", (Boolean)ViewData[@cb])).HeaderTemplate("Invoice Option");                                
                @i++;
                @cb = "checkbox" + i.ToString();
            }
        )
        .Pageable(paging =>
                paging.Enabled(true)
                      .PageSize(UserSettings.GridPageSize)
                      .Style(GridPagerStyles.NextPrevious)
                      .Position(GridPagerPosition.Bottom)
            )
        .Sortable()
        .Scrollable()
        .Resizable(resize=> resize.Columns(true))
)

The problem with this whole thing is that the checkboxes remain unchecked, no matter the data stored in the ViewData. I went with the debugger and the values are se accordingly in the ViewData, but for some reason (that I cannot yet tell) the checkboxes still remain unchcked.

Any ideas on this matter would be much appreciated.


Solution

  • I have found out the problem of all this. As expected, it was my own doing (or so to say). The problem was that I incremented the @i variable inside the Telerik grid declaration, thinking that it would happen for all the rows in the grid, but that thing is only triggered once. Hence, the ViewData[@cb] value would always have the 2nd value set in the Controller (which in my case was false) and all the checkboxes would then be unchecked.

    The fix:

    I used the ViewBag and set it up with a Dictionary<Guid, bool> to hold my values, and iterate through it using the model.Id property. For anyone who might be interested I'll post the code below.

    Controller:

            ViewBag.Dict = new Dictionary<Guid, bool>();
            Dictionary<Guid, bool> dict = new Dictionary<Guid, bool>();
    
            foreach (Bucket b in buckets)
            {
                var payByInvoice = db.PaymentOptions.Where(p => p.BucketId == b.Id).Select(p => p.CanPayByInvoice).SingleOrDefault();
                if (payByInvoice != (int)PayByInvoiceState.Accepted)
                {
                    dict.Add(b.Id, false);
                }
                if (payByInvoice == (int)PayByInvoiceState.Accepted)
                { 
                    dict.Add(b.Id, true);
                }
            }
            ViewBag.Dict = dict; 
    

    View:

    columns.Template(model => Html.CheckBox("invoice", (bool)ViewBag.Dict[model.Id])).HeaderTemplate("Invoice option");