Checkbox inputs badly aligned when there's no accompanying label using Bootstrap and MVC5

33,445

Solution 1

I implemented an Html Helper CheckBoxForBootstrap that puts the checkbox in a label but without any label text so there is no redundant label but you still get the desired formatting. The hidden field needed by mvc model binder is added after the label to it should be valid html.

public static MvcHtmlString CheckBoxForBootstrap(this HtmlHelper htmlHelper, 
        string name, 
        bool isChecked)
{

    TagBuilder checkbox = new TagBuilder("input");
    checkbox.Attributes.Add("type", "checkbox");
    checkbox.Attributes.Add("name", name);
    checkbox.Attributes.Add("id", name);
    checkbox.Attributes.Add("data-val", "true");
    checkbox.Attributes.Add("value", "true");
    if (isChecked)
        checkbox.Attributes.Add("checked", "checked");

    TagBuilder label = new TagBuilder("label");
    //nest the checkbox inside the label
    label.InnerHtml = checkbox.ToString(TagRenderMode.Normal);

    TagBuilder hidden = new TagBuilder("input");
    hidden.Attributes.Add("type", "hidden");
    hidden.Attributes.Add("name", name);
    hidden.Attributes.Add("value", "false");

    return MvcHtmlString.Create(
    label.ToString(TagRenderMode.Normal) 
    + hidden.ToString(TagRenderMode.Normal)
    );
}

Solution 2

<div class="checkbox">
    <label>
        @Html.CheckBoxFor(model => model.IsUrgent)
        @Html.DisplayNameFor(model => model.IsUrgent)
    </label>
</div>

Solution 3

Instead of @Html.EditorFor(model => model.IsUrgent) add following code. You can put the hidden field outside the label tag.

<div class="checkbox">
    <label>
        <input class="check-box" data-val="true" id="IsUrgent" name="IsUrgent" value="true" type="checkbox"> &nbsp;
    </label>
    <input name="IsUrgent" type="hidden" value="false">
</div>

DEMO

Thanks!

Solution 4

I had the same issue, and just changed the class on the div immediately surrounding the checkbox. Try:

    <div class="form-control-static">
        @Html.EditorFor(model => model.IsUrgent)
     </div>

Solution 5

<div class="checkbox" style="margin: 5px 0 0 0;">
    <label for="remember" style="margin: 0;">
        <input name="remember" id="remember" type="checkbox" style="margin-top: 2px;">
        Remember me
    </label>
</div>

DEMO

Share:
33,445

Related videos on Youtube

janv8000
Author by

janv8000

Updated on July 05, 2022

Comments

  • janv8000
    janv8000 almost 2 years

    Bootply to play with

    Visual Studio 2013 generates the following CSHTML when scaffolding an edit view for a model with a boolean:

    <div class="form-group">
        @Html.LabelFor(model => model.IsUrgent, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <div class="checkbox">
                @Html.EditorFor(model => model.IsUrgent)
             </div>
        </div>
    </div>
    

    After passing through Razor you get this:

    <div class="form-group">
      <label class="control-label col-md-2" for="IsUrgent">Is bad :(</label>
       <div class="col-md-10">
        <div class="checkbox">
          <input class="check-box" data-val="true" id="IsUrgent" name="IsUrgent" type="checkbox" value="true">
          <input name="IsUrgent" type="hidden" value="false">
        </div>
      </div>
    </div>
    

    Twitter Bootstrap 3.2 however doesn't like this way of using labels because this is the result:

    Screenshot

    Note that the checkbox is positioned too much to the left.

    If I wrap my input in a dummy label with some whitespace, ie.

    <div class="form-group">
        <label class="control-label col-md-2" for="IsUrgent">Is good!</label>
    
        <div class="col-md-10">
          <div class="checkbox">
            <label><input class="check-box" data-val="true" id="IsUrgent" name="IsUrgent" type="checkbox" value="true">
            <input name="IsUrgent" type="hidden" value="false">&nbsp;</label>
          </div>
        </div>
    </div>
    

    I get this:

    Second screenshot

    which looks nice but it's not valid HTML:

    The label element may contain at most one input, button, select, textarea, or keygen descendant.

    Am I doing something wrong with my CSS classes?

    Edit

    If I move the second input outside of the label as @Saranga suggests I'm still left with the redundant label that serves no semantic function ...

    • Brent
      Brent almost 9 years
      Is there a problem with including a rule on the site.css file: .checkbox > input[type=checkbox]{ margin-left:0; } ?
  • janv8000
    janv8000 almost 10 years
    Sadly that hidden field is required by the MVC model binder :(. That's why @Html.EditorFor(model => model.IsUrgent) outputs both of them
  • janv8000
    janv8000 almost 10 years
    True, but then I'm still stuck with the superfluous label
  • Saranga
    Saranga almost 10 years
    I think it's not superfluous one, because in bootstrap we define the text at the end of the check-box (getbootstrap.com/css/#forms), but in your case you need to keep the label in front. So we need that label with &nbsp; to get the bootstrap styles work. So we can use this method as a alternative. Thanks!
  • janv8000
    janv8000 over 7 years
    This will produce invalid HTML, ie. The label element may contain at most one input, button, select, textarea, or keygen descendant.
  • janv8000
    janv8000 over 7 years
    A label when clicked will move the focus to the input field, this solution does not
  • janv8000
    janv8000 over 7 years
    This will produce invalid HTML, ie. The label element may contain at most one input, button, select, textarea, or keygen descendant.
  • janv8000
    janv8000 over 7 years
    This solution puts the label to the right of the checkbox
  • janv8000
    janv8000 over 7 years
    The css you link to is over 24KB