skip to Main Content

I use .NET Framework 4.7 with ASP.NET MVC to generate Forms and for validating I have jQuery Validate, which works for classic input fields, but for @Html.CheckBoxFor it generated 2 inputs with the same name, the first is standard input, the second is hidden, it is default by .NET, but jQuery validate does not work with this.

Only what works for me is adding validation rule for a specific element, but this approach does not delegate message, only apply the CSS class style to add red background to invalid input

What works but is not ideal solution yet

$("input[name='Do[0].IsSelected']:not(:hidden)").rules("add", {
  required: true,
  messages: { required: "field is required." },
});

What does not work for JQuery Validation:

C# code:

<div class="col-lg-7 do-checkbox">
        @Html.CheckBoxFor(m => m.Do[i].IsSelected, isViewModeForCheckBox, new { id = "chb_do" + i, onchange = "RemoveUpload(" + i + ");", @class = "form-check-input" })
        @Model.Do[i].Text
</div>

Which generates this HTML output:

<div class="col-lg-7 do-checkbox">
    <input class="form-check-input" data-val="true" data-val-required="The IsSelected field is required." disabled=""
        id="chb_do0" name="Do[0].IsSelected" onchange="RemoveUpload(0);" readonly="" type="checkbox" value="true"
        aria-invalid="true">
    <label id="Do[0].IsSelected-error" class="border-danger shadow-danger" for="Do[0].IsSelected"
        style="display: none;"></label>
    <input name="Do[0].IsSelected" type="hidden" value="false" class="valid">
    Info text
</div>

JQuery validate:

$("form[name='reg']").validate({
  ignore: ":hidden",
  errorClass: "border-danger shadow-danger",
  errorPlacement: function () {},
  rules: {
    "Reg.Name": "required",
    "Do[0].IsSelected": {
      required: true,
      email: function (element) {
        return $("input[name='Do[0].IsSelected']:not(:hidden)").is(":checked");
      },
    },
  },
  messages: {
    "Reg.Name": "Info error message",
    "Do[0].IsSelected": {
      required: "Enter a username",
      email: "Enter at least {0} characters",
    },
  },
  invalidHandler: function (event, validator) {
    var errors = validator.numberOfInvalids();
    if (errors) {
      var message =
        errors == 1
          ? "Info 1 field missing"
          : "Info  " + errors + " fields missing";

      if (validator.errorList.length > 0) {
        for (x = 0; x < validator.errorList.length; x++) {
          message += "</br>nu25CF " + validator.errorList[x].message;
        }
      }
      $("div.error span").html(message);
      $("div.error").show();
    } else {
      $("div.error").hide();
    }
  },
  submitHandler: function () {
    document.forms["reg"].submit();
  },
});

jQuery validate add CSS class to second hidden input, and not show message
I also use additionals.methods.js extension library, but without success

2

Answers


  1. I think the problem is as you have said being jQuery Validate by default ignores hidden input fields, so it will not validate the hidden checkbox that is generated by the @Html.CheckBoxFor helper.

    One way to possibly work around this is to use the ignore option to the validate() method to specify that the hidden checkbox should be included in the validation. For example, you could use the following code:

    $("form[name='reg']").validate({
        ignore: ":hidden",
        rules: {
            "Reg.Name": "required",
            "Do[0].IsSelected": {
                required: true,
                email: function(element) {
                    return $("input[name='Do[0].IsSelected']:not(:hidden)").is(":checked");
                }
            },
        },
        messages: {
            "Reg.Name": "Info error message",
            "Do[0].IsSelected": {
                required: "Enter a username",
                email: "Enter at least {0} characters",
            },
        },
    });
    

    If you where using .net core >= v5 then you could add this to startup:

     services.Configure<MvcViewOptions>(options =>
     {    
      options.HtmlHelperOptions.CheckBoxHiddenInputRenderMode = 
      CheckBoxHiddenInputRenderMode.None;
     });
    

    another alternative if you cant use core, would be to write a custom html helper that generates checkboxes without the hidden fields, for example:

    public static MvcHtmlString BasicCheckBox<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, object htmlAttributes)
    {
        var cbHidden= htmlHelper.CheckBoxFor(expression, htmlAttributes).ToHtmlString().Trim();
        string basicCheck = cbHidden.Substring(0, cbHidden.IndexOf("<input", 1));
        return new MvcHtmlString(basicCheck);
    }
    

    let me know if this doesn’t work and I can look a little deeper.

    Login or Signup to reply.
  2. To make jQuery Validate work with the hidden input generated by the @Html.CheckBoxFor helper in ASP.NET MVC, you need to make sure that the ignore option of the validation plugin includes the hidden inputs as well. Additionally, you’ll need to modify the errorPlacement function to show the error message correctly. Here’s how you can achieve this:

    $("form[name='reg']").validate({
      // Include hidden inputs in validation
      ignore: [],
    
      errorClass: "border-danger shadow-danger",
    
      // Use the errorPlacement function to show the error message
      errorPlacement: function (error, element) {
        var parent = element.parent();
        if (element.is(":checkbox")) {
          // If the element is a checkbox, find the associated label and show the error message there
          parent.find("label.error").remove();
          error.appendTo(parent);
        } else {
          // For other elements, show the error message next to the input field
          error.insertAfter(element);
        }
      },
    
      rules: {
        "Reg.Name": "required",
        "Do[0].IsSelected": {
          required: true,
        },
      },
      messages: {
        "Reg.Name": "Info error message",
        "Do[0].IsSelected": {
          required: "Enter a username",
        },
      },
      invalidHandler: function (event, validator) {
        // Your error handling code
      },
      submitHandler: function () {
        document.forms["reg"].submit();
      },
    });
    

    With the above modifications, jQuery Validate should work correctly with the hidden input generated by @Html.CheckBoxFor, and it should display the error message correctly according to the errorPlacement function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search