1

I'm creating a website with ASP.NET MVC5 and I'm using MaterializeCSS for the first time, which looks like a very exciting framework.

However, the checkboxes generated by CheckBoxFor helper become hidden !
When I write :

@Html.CheckBoxFor(m => m.IsAgreeTerms)

The generated HTML is :

<input name="IsAgreeTerms" type="hidden" value="false">

Why does Materialize change my type=checkbox into type=hidden ?
I tried to add type="checkbox" in the CheckboxFor helper, but it doesnt change anything. The only way is to modify in in my browser's console.

The only solution I found is this SO thread. However, the accepted answer doesn't change anything for me.
The other answer works, but I think it's ugly to add some JS script to modify what Materialize modifies without my consent.

Is there any way to say "Hey, I ask for a type=checkbox, so just let my type=checkbox in the generated HTML" ?

Thank you


UPDATE :
My full ASP.NET MVC code is :

@Html.CheckBoxFor(m => m.IsAgreeTerms, new { @type = "checkbox" })
@Html.LabelFor(m => m.IsAgreeTerms, new { @class = "login-label" })

The full generated HTML is

<input data-val="true" data-val-required="Le champ IsAgreeTerms est requis." id="IsAgreeTerms" name="IsAgreeTerms" type="checkbox" value="true"
<input name="IsAgreeTerms" type="hidden" value="false">
<label class="login-label" for="IsAgreeTerms">IsAgreeTerms</label>
Community
  • 1
  • 1
user2687153
  • 427
  • 5
  • 24

3 Answers3

1

Here's a solution in the form of a html helper. It constructs a checkbox and label in the correct order:

public static IHtmlString CheckBoxWithLabelFor<TModel>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, bool>> expression,
        string labelText,
        object htmlAttributes = null
    )
{
    if (expression == null)
    {
        throw new ArgumentNullException(nameof(expression));
    }

    var checkBoxWithHidden = htmlHelper.CheckBoxFor(expression, htmlAttributes).ToHtmlString().Trim();
    var pureCheckBox = checkBoxWithHidden.Substring(0, checkBoxWithHidden.IndexOf("<input", 1, StringComparison.Ordinal));
    var labelHtml = htmlHelper.LabelFor(expression, labelText).ToHtmlString().Trim();
    var result = pureCheckBox + Environment.NewLine + labelHtml + Environment.NewLine + $"<input type=\"hidden\" name=\"{ExpressionHelper.GetExpressionText(expression)}\" value=\"false\" />";

    return new MvcHtmlString(result);
}
Dave de Jong
  • 859
  • 7
  • 13
0

Is there other html generated by materialize.css? I think this happens because it is not possible apply a custom CSS to element input of type checkbox.

So, the checkbox becomes hidden and other html component represents visually the checkbox. Many components work like that.

UPDATE: Why is Html checkbox generating an additional hidden input

Community
  • 1
  • 1
  • Thank you for your answer. I updated my question. I'm not a CSS specialist but he main problem here is that all my checkboxes generated by Razor became hidden. Even if I don't want to style them... Here, if I manually change `type="hidden"` by `type="checkbox"` in the 2nd generated input in my browser's console, it's perfectly working. – user2687153 Nov 12 '16 at 15:08
  • Ok. I got it. Here, is the best answer to your question: http://stackoverflow.com/questions/2697299/asp-net-mvc-why-is-html-checkbox-generating-an-additional-hidden-input – Claudio Cavalcante Tonha Nov 12 '16 at 15:17
0

OP here. Problem looks like more complex.

Actually, when using @Html.CheckBoxFor, MVC5 generates 3 fields, in that order :

  • Your input, with type="checkbox", binded to your model property
  • An hidden field (see the Claudio's link for an explaination)
  • Your label, generated by @Html.LabelFor

Problem is Materialize expects that in another order to work.
In your browser's console, just move the <label> element between the input and the hidden field, and everything works fine !

I found this very useful link, where, basically, it is said that the order of the generated fields by @Html.checkBoxFor will change ... In MVC6 !

As I'm working with MVC5, I use this very ugly solution in my _Layout:

$(":checkbox").each(function () {
    $(this).nextAll("label").before($(this))
})

If anyone has a better idea, please feel free to post an elegant solution.

user2687153
  • 427
  • 5
  • 24