How to create an EditorTemplate for bootstrap checkbox?
Asked Answered
A

1

4

I am working with a bootstrap template and its checkbox template is like this:

<div class="checkbox">
    <label>
        <input type="checkbox" class="checkbox style-1" checked="checked">
        <span>Checkbox 1</span>
    </label>
</div>

I need an MVC EditorTemplate for boolean values to use this template. MVC CheckBoxFor default template is not like this template, it has another hidden input field to hold data and there is no span to show checkbox icon (it uses a default icon not stylable by css).

MVC CheckBoxFor default template :

<input checked="checked" data-val="true" data-val-required="required." id="IsActive" 
       name="IsActive" type="checkbox" value="true">
<input name="IsActive" type="hidden" value="false">

I tried many ways to do this with no success. For example if I use a conditional template like below, it does not return value after submit.

My Boolean EditorTemplate:

@model Boolean?
<div class="checkbox">
    <label>
        @if (Model.Value)
        {
            <input id="@ViewData.TemplateInfo.GetFullHtmlFieldId("")" name="@ViewData.TemplateInfo.GetFullHtmlFieldId("")"
                   type="checkbox" class="checkbox style-1" checked="checked" value="true" />
        }
        else
        {
            <input id="@ViewData.TemplateInfo.GetFullHtmlFieldId("")" name="@ViewData.TemplateInfo.GetFullHtmlFieldId("")"
                   type="checkbox" class="checkbox style-1" value="false" />
        }
        <span>@Html.LabelFor(m => m)</span>
    </label>
</div>

Can anyone help please?

Update:

A part of css codes relevent to checkbox icon :

label input[type=checkbox].checkbox + span:before {
    font-family: FontAwesome;
    font-size: 12px;
    border-radius: 0;
    content: " ";
    display: inline-block;
    text-align: center;
    vertical-align: middle;
    padding: 1px;
    height: 12px;
    line-height: 12px;
    min-width: 12px;
    margin-right: 5px;
    border: 1px solid #bfbfbf;
    background-color: #f4f4f4;
    font-weight: 400;
    margin-top: -1px;
}

label input[type=checkbox].checkbox + span:before {
    content: " ";
}

label input[type=checkbox].checkbox:checked + span:before {
    content: "";
    color: #2e7bcc;
}

label input[type=checkbox].checkbox:checked + span {
    font-weight: 700;
}
Adenoid answered 22/2, 2016 at 9:33 Comment(6)
I think all you will need is a custom html helperTangerine
What makes you think you need to change it. You can add the class="checkbox style-1" using the CheckBoxFor() method. But its clear your not understanding the CheckBoxFor() method. Firstly it generates the hidden input so a value is always posted back (unchecked checkboxes do not submit a value). Second you cannot bind a checkbox to a nullable bool - a checkbox has 2 states but bool? has 3 states and your EditorTemplate makes no sense - your else block generates a checkbox which will always submit a value of false no matter what if its checked or not.Sybaris
@StephenMuecke : Do you mean this way : <div class="checkbox"> <label> @Html.CheckBoxFor(m => m.EmaiToCustomer, new { @class = "checkbox style-1" }) <span> @Html.LabelFor(m => m.EmaiToCustomer)</span> </label> </div> If yes, when the hidden input comes after checkbox input it causes checkbox icon not visible anymore!Adenoid
Then I guess you are using a plugin. You need to show the relevant code including the css you using for the 'icon'! (its just a matter of changing the css selectors which best guess is currently something like .checkbox + label)Sybaris
@Tangerine Do you think it make any different about getting value in controller. The problem is the additional hidden input needed to get value in controller and it must come before span.Adenoid
@StephenMuecke Ok I will add css selectors to the question shortly.Adenoid
S
5

The CheckBoxFor() method generate 2 inputs to ensure a value is posted back (unchecked checkboxes to not submit a value so the hidden input ensures false is submitted), and you should not attempt to change this behavior. Your attempt at an EditorTempate could not work for a number of reasons including a checkbox (which has 2 states) cannot bind to a nullable bool (which has 3 states) and your else block means that a vale of false will always be submitted, even if the checkbox is checked.

Instead, use the CheckBoxFor() method, but adjust your css selectors

<div class="checkbox">
    <label>
        @Html.CheckBoxFor(m => m.IsActive, new { @class = "checkbox style-1" })
        <span>Checkbox 1</span>
    </label>
</div>

will generate

<div class="checkbox">
    <label>
        <input type="checkbox" name="IsActive" class="checkbox style-1" ... value="true">
        <input type="hidden" name="IsActive" value="false">
        <span>Checkbox 1</span>
    </label>
</div>

So your current selector

label input[type=checkbox].checkbox + span:before {

which gets the span element placed immediately after the checkbox element needs to be changed to

label input[type=checkbox].checkbox ~ span:before {

And ditto for the other selectors (i.e. change + to ~). The ~ selector matches the second element if it is preceded by the first, and both share a common parent (refer General sibling selectors)

Sybaris answered 22/2, 2016 at 11:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.