javascriptjqueryasp.net-coremodel-view-controllerasp.net-core-3.1

Enable client side validation on disabled select element


I got a project using asp.net core 3.1 MVC. It contains a form with a selection that is disabled.

    <div class="col-12 mb-3">
        <select asp-for="SelectableItem" class="multi-select form-control" id="selectedItem" disabled="disabled" required="required">
            <option value="">-- Select Item --</option>
        </select>
        <span asp-validation-for="SelectableItems" class="text-danger"></span>
    </div>

The fully rendered html

<select class="multi-select form-control" id="selectedItem" disabled="" required="required" 
    data-val="true" data-val-required="Selected Item is required" 
    name="SelectedItem">          
     <option value="">-- Select Item --</option>
</select>

This selection is disabled until the user checks a box, which then populates the select element and enables it, as the content depens on wat checkbox has been selected.

When the user tries to submit the form the validation of JQuery.Validation.Unobtrusive validates everything except that disabled field, as the field is required however i would like for it to be validated as well.

I only want it to be enabled for that one form, so not all disabled elements throughout the application, but can't seem to get it to work.

I tried the following and some variants of it.

$('form').validator.setDefaults({ignore: null})

$('form').data('validator').settings.ignore = "";

$('form').validator.setDefaults({ignore: []})

$('#selectableItem').Validate().settings.not('[disabled]')

Non of these seem to do anything, the disabled select refuses to get validated, and all other suggestions like readonly doesn't work on select elements, nor do i want it to be globally allowed, as that would mess up some other forms.


Solution

  • If you really want to validate all disabled form fields, the relevant line in the plugin is:

    .not( ":submit, :reset, :image, :disabled" )
    

    Follow the steps:

    1. Find the jquery.validate.js in your project and open it.

      enter image description here

    2. Press Ctrl+F to find the line that contains disabled, then comment on this line (or you could remove the :disabled in this line):

      enter image description here

    3. If you use the default ASP.NET Core project, remember to change the _ValidationScriptsPartial.cshtml file, Because this view adds a reference for jquery.validate.min.js, but you modify the jquery.validate.js (if you still want to use min.js, please read the docs and learn how to bundle and minify static assets):

      <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script> //change here...
      <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
      

    Here is a working demo:

    Model (add the [Required] attribute):

    public class Test
    {
        [Required]       //add this
        public string SelectableItem { get; set; }
    }
    

    View (remove the required="required" attribute-value pair):

    @model Test
    <form method="post">
        <input type="checkbox" />
        <div class="col-12 mb-3">
            <select asp-for="SelectableItem" class="multi-select form-control" id="selectedItem" disabled="disabled">
                <option value="">-- Select Item --</option>
            </select>
            <span asp-validation-for="SelectableItem" class="text-danger"></span>
        </div>
        <input type="submit" value="Create" />
    </form>
    
    @section Scripts
    {
        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    
        <script>
            $(document).ready(function () {
                $('input:checkbox').change(function () {
                    if (this.checked) {
                        //add to select list
                        $("#selectedItem").append($("<option></option>")
                            .attr("value", "1")
                            .text("aa"));
                        $("#selectedItem").append($("<option></option>")
                            .attr("value", "2")
                            .text("bb"));
                        $("#selectedItem").append($("<option></option>")
                            .attr("value", "3")
                            .text("cc"));
                        // $("selectedItem").prop('required', true);
                        $("#selectedItem").removeAttr('disabled');
                    }
                    else {
                        //remove item from select list
                        $("#selectedItem").empty().append($("<option></option>")
                            .attr("value", "")
                            .text("-- Select Item --"));
                        $("#selectedItem").prop('disabled', true);
                    }
                });
            });
        </script>
    } 
    

    Result:

    enter image description here