Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC extra hidden checkbox in forms breaking custom css checkbox

I am trying to customize the look and feel of the checkboxes in my ASP.NET MVC site, using a technique like the one detailed here: http://cssdeck.com/labs/css-checkbox-styles

They work great except when placed in a form. When using the @Html.CheckBoxFor() method, MVC adds an extra hidden checkbox, apparently to make sure that a value is submitted to the form POST when the checkbox is not checked: asp.net mvc: why is Html.CheckBox generating an additional hidden input

When the extra hidden checkbox is on the form, my custom checkbox does not work. I click it but it does not toggle between the states. If I remove the extra hidden checkbox, then it works, but I guess I'll run into problems submitting the POST.

Here is the final html:

<div class="kbcheckbox">
    <input checked="checked" data-val="true" data-val-required="The Approved field is required." id="UserEdit_IsApproved" name="UserEdit.IsApproved" type="checkbox" value="true">
    <input name="UserEdit.IsApproved" type="hidden" value="false">
    <label for="UserEdit_IsApproved"></label></div>
</div>

And here is the css I am using (uses scss)

.kbcheckbox {
    width: $checkbox_size;  
    height: $checkbox_size;
    position: relative;

    input[type="checkbox"]{
        visibility: hidden;
    }

    label {
        cursor: pointer;
        position: absolute;
        width: $checkbox_size;
        height: $checkbox_size;
        top: 0;
        left: 0;
        border-radius: $control_corner_radius;
        border: 1px solid $control_border_color;
        /*@include box-shadow(1px, 1px, 1px, 0, $control_border_color, inset);*/ 
        /*@include box-shadow(0px, 1px, 0px, $control_background);*/
        background: white;
    }

    label:after {
        opacity: 0;
        content: '';
        position: absolute;
        width: $checkbox_size * 0.62;
        height: $checkbox_size * 0.25;
        background: transparent;
        top: $checkbox_size * 0.2;
        left: $checkbox_size * 0.1;
        border: 3px solid black;
        border-top: none;
        border-right: none;

        @include transform(rotate(-45deg));
    } 

    label:hover {
        background: darken($control_background, 10%);
    }

    input[type=checkbox]:checked + label:after {
        opacity: 1;
    }
}

Any ideas?

like image 531
kbmax Avatar asked Feb 01 '13 16:02

kbmax


2 Answers

Use the following in your css. You want all your elements to be modified.

input[type = checkbox]:checked ~ label:after {
    opacity: 1;
}

Here is the fiddle

like image 172
Amit Avatar answered Oct 22 '22 12:10

Amit


You can solve this problem by wiring up an event when the checkbox is checked to change the value on an MVC hidden field instead, essentially doing the same thing without using the MVC helper

@Html.HiddenFor(model => model.UserEdit.IsApproved, new { @id = "chkIsApproved" })

Here is your HTML then

<div class="kbcheckbox">
    <input checked="checked" data-val="true" data-val-required="The Approved field is required." id="UserEdit_IsApproved" name="UserEdit.IsApproved" type="checkbox" value="true">
    <label for="UserEdit_IsApproved"></label></div>
</div>

Then just use some jQuery to wire up the checked property with the hidden field

$('#UserEdit_IsApproved').change(function() {
    $('#chkIsApproved').val($(this).is(':checked'));        
});

As long as the MVC hidden field is somewhere, the value will be posted to the controller. It is a little extra work, but it should get you the result you want.

like image 1
dgarbacz Avatar answered Oct 22 '22 12:10

dgarbacz