Disabling Client Side Validation For Disabled Input Controls In ASP.NET MVC

   Introduction:

          Client side validation always saves a lot of time and bandwidth, because it take place on the client side and the user is immediately informed that they've gone wrong in filling out the form before the form is posted back to the server. ASP.NET includes a set of server validation controls for web form since it's first version. On the other hand in ASP.NET MVC 1 not have any built-in support for client side validation. ASP.NET MVC 2 fills this gap by supporting client side validation via Data Annotation. This work's very nicely. By default client side validation in ASP.NET MVC 2 validate all input controls including disabled controls. This may be good for some one but may be not good for some one else. Therefore in this article I just shows how to tell ASP.NET MVC 2 client library to not validate disabled controls.

 

   Description:

          By default ASP.NET MVC 2 framework uses MicrosoftMvcValidation.js script file to validate client inputs. To see how to set up client side validation in ASP.NET MVC 2 see this.

           So let's create a new ASP.NET MVC 2 Project. After creating the project just add a new class Product.cs inside Model folder and add the following code.

 

    public class Product
    {
        [Required]
        [StringLength(10, ErrorMessage = "Name max length is 10")]
        public string Name { get; set; }

        [Required(ErrorMessage = "Description is required")]
        public string Description { get; set; }

        [Required(ErrorMessage = "Unit Price is required")]
        [RegularExpression(@"^\$?\d+(\.(\d{2}))?$", ErrorMessage = "Unit Price Format is wrong")]
        public decimal UnitPrice { get; set; }
    }


           This simply add a Product class with three properties and decorate these properties with Data Annotation validation attributes. Next, open your HomeController.cs and add action methods for Product which simply returns the Product view (note that I am not intended to show server validation here, but keep in mind that server validation is necessary).

 

        public ActionResult Product()
        {
            return View();
        }
        [HttpPost]
        public ActionResult Product(Product a)
        {
            return View();
        }


            And here is the Product's view 

 

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Mvc.Models.Product>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Product
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% Html.EnableClientValidation(); %>
    <%using (Html.BeginForm()){ %>
      <table>
        <tr>
            <td>
                Name
            </td>
            <td>
                <%=Html.TextBoxFor(a => a.Name)%>
            </td>
            <td>
                <%=Html.ValidationMessageFor(a => a.Name)%>
            </td>
            <td>
                <input type="checkbox" onclick="$get('Name').disabled=this.checked" />
            </td>
        </tr>
        <tr>
            <td>
                Description
            </td>
            <td>
                <%=Html.TextBoxFor(a => a.Description)%>
            </td>
            <td>
                <%=Html.ValidationMessageFor(a => a.Description)%>
            </td>
            <td>
                <input type="checkbox" onclick="$get('Description').disabled=this.checked" />
            </td>
        </tr>
        <tr>
            <td>
                UnitPrice
            </td>
            <td>
                <%=Html.TextBoxFor(a => a.UnitPrice)%>
            </td>
            <td>
                <%=Html.ValidationMessageFor(a => a.UnitPrice)%>
            </td>
            <td>
                <input type="checkbox" onclick="$get('UnitPrice').disabled=this.checked" />
            </td>
        </tr>
        
        <tr>
            <td colspan="3" align="center">
                <input type="submit" name="A"/>
            </td>
        </tr>
    </table>
    <%} %>

</asp:Content>

  
            Product view simply enable client side validation and add the necessary controls needed to show the product data and thier validation as well as a checkbox for every input control to enable or disable their corresponding input control.


             Note that all the script files needed to enable client side validation is added in Site.Master file. Now, when you run your application you will see that client side validation will always validate a input control whether you enable or disable this input control. To validate only enable controls just open MicrosoftMvcValidation.debug.js(I had referenced the debug version in Site.Master) and then replace the following text,

 

            if (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(errorMessage)) {
                Array.add(errors, errorMessage);
            }

with this,

 

            var inptEl = $get(context.fieldContext.elements[0].id);
            if (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(errorMessage) && !inptEl.disabled) {
                Array.add(errors, errorMessage);
            }
            else
                Sys.UI.DomElement.removeCssClass(inptEl, Sys.Mvc.FieldContext._inputElementErrorCss);

   
             It is not doing any thing special, just checking whether the control is disabled and if yes then removes the input-validation-error CSS class and not add current errorMessage into errors array.   

             Just save the script file and run your application again you will see that it only validate those input controls which are enabled.


                        Client Side Validation 

and not validate those input controls which are disabled.  

                         Client Side Validation


   Summary:

          There are lot of occasions in which developers allow the users to enable or disable input controls. In such situation there is a need to not validate those input controls which are disabled. In this article I just modified 2-3 lines of  MicrosoftMvcValidation.debug.js script file to make it only validate enabled controls. I hope you may find this useful for some specific scenarios.

14 Comments

  • 1. Must add that you should not try validating on the server with ModelState.IsValid - but the tryupdate with a object retrieved from database
    2. You have in ASP.NET forums a more shorter version - putting the name of disable controls at '' - I liked very much that version! Please put here also as reference!

  • @ignatandrei
    1) I had clearly state in this article that my intention is not server side validation thats why i skip serverside validation. As written above

    >>(note that I am not intended to show server validation here, but keep >>in mind that server validation is necessary).
    2) I don't understand what do you mean.

  • HI Friend,

    Really nice post. I want to use syntax highlighter in my asp.net blog how i can use can you guide me on that.

  • @Jalpesh P. Vadgama
    See
    http://alexgorbatchev.com/wiki/SyntaxHighlighter

  • 3 W – Interracial //Searching.com C -O- M}) Interracial dateing or relationship is not a problem there, but a great merit to cherish!
    You are guaranteed to be your r the one of them.

  • Instead of using "<%@ Page Title="" am using "<%@ Control".
    and through above code , validation on my disabled fields is still being not disabled. what should i do if am using a control instead of page.

  • @Faizoo.
    This will work both in View and Partial View. Make sure to change the script(as described above) and reference correct scripts.

  • thnx. i still have an issue, that..Above code replacement is for the condition to not to validate as 'required' the disable fields. But what if i have not to validate the fields for regular expression.

  • @Faizoo,
    Can you provide me a sample application?

  • thnx, i have done it, it was so simple.
    i simply changed the following lines in MicrosoftMVCJqueryValidation.js
    in function "function __MVC_CreateRulesForField(validationField)"
    and in case case "regularExpression": i replaced it with the following.

    case "regularExpression":

    if (!$("#" + validationField.FieldName).get(0).disabled) {
    __MVC_ApplyValidator_RegularExpression(rulesObj,
    thisRule.ValidationParameters["pattern"]);
    }
    break;

    instead of default,

    case "regularExpression":
    __MVC_ApplyValidator_RegularExpression(rulesObj,
    thisRule.ValidationParameters["pattern"]);
    break;

    and it works.

    your post helped me a lot. Great sharing.. keep it up.

  • Salaam Imran,

    I have tried the above but I get an error dialog stating the following:

    ----------------

    'A Runtime Error has occured.
    Do you wish to Debug?

    Line: 554
    Error: 'fieldContext.elements.0.id.id' is null or not an object'

    ----------------

    I am using MVC2 and in my site.master I have the following:

    ...



    ...

    Any help appreciated in why i am getting this error and subsequently can not get what you have done above to work...

    THanks.

  • Thanks for your reply Imran.

    I have put this line in:

    if (context.fieldContext.elements[0] != null) {
    ...

    and its worked for me.

  • still not working for me using MicrosoftMVCJqueryValidation.js

  • @danial,
    Download the sample project

Comments have been disabled for this content.