Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Creating a disableable dropdownlist in ASP.NET MVC3

4.43/5 (3 votes)
5 Sep 2012CPOL4 min read 35.6K   746  
How to create a disableable dropdown list control in ASP.NET MVC3.

Introduction

In this article I describe a way to create an HTML helper method using ASP.NET MVC3 to make a select element that can be dynamically enabled or disabled without using the "disabled" attribute. 

Background

What is the purpose of writing this article? For your understanding I will describe why it isn't feasible to use the "disabled" attribute in ASP.NET MVC. Disabling the HTML element by the "disabled" attribute makes the HTTP POST request to ignore that value altogether and not send it back to the server which would be required in certain cases. Other possibilities to make the element unselectable would be to intercept certain mouse events but I couldn't make that work.

A possible solution to the problem is to hide the element by another element that is invisible to the user by making the original select element uncontrollable by the user. For this I used a span element that I positioned with the "position:relative" CSS value and encapsulated all the logic and template generation code in an HTML helper method so it can be used with ease anytime it is needed.

The demo application

For the purpose of this article I created a demo application that will demonstrate a hypothetical usage of the solution presented. The application will be a very simple one containing a single view page with a dropdown list of genders, a checkbox that toggles the status of the dropdown, and a submit button. Our page will use a view model class called PersonViewModel that will contain a property for the selected gender and a list of the possible genders.

C#
public class PersonViewModel
{
   [Required]
   public String Gender {get; set;}

   public IEnumerable<SelectListItem> GendersList
   {
      get {…}
      set {…}
   ...
}

Image 1

The selection of a concrete gender is required to submit the form to the server, therefore the user has to select one of the two values from the dropdown list. By unchecking the checkbox the dropdown list gets disabled but only visually, and disabling it doesn’t prevent the selected value from being sent to the server. Hence, the purpose of this article is fulfilled.

To design the above form we can use the following HTML, JavaScript, and Razor statements:

C#
@using (Html.BeginForm())
{   
   Select gender: 

   @Html.DisableableDropDownListFor(x => x.Gender, Model.GendersList, 
     "Please  select", new { id = "cbGender", style = "color: green;width:120px;"})
 
   @Html.ValidationMessageFor(x => x.Gender)

   <input type="submit" value="Submit" />
}
Enable/disable gender dropdown list 

<input type="checkbox" id="cb_Toggle" checked="true" />

<script type="text/javascript">
   $("#cb_Toggle").click(function () {
      var $Gender = $("#cbGender");

      if ($(this).attr("checked"))
         $Gender.enableDropDownList();
      else
         $Gender.disableDropDownList();
    });
</script>

As you can see, we call the DisableableDropDownListFor helper method to generate us the markup for the dropdown list and we have a fairly simple JavaScript code that makes the actual enabling and disabling possible. All the user of this method needs to know is the ID of the generated element on which to invoke the two JavaScript methods:

  • enableDropDownList()
  • disableDropDownList()

In case the ID is omitted, the generated ID in markup will be the name of the property for which the dropdown list is created. In the case of this view model that would be Gender, but because we defined it explicitly (to cbGender), this won’t be taken into account. If a valid value is selected from the dropdown list and the form is submitted, the action method invoked simply returns some JavaScript code that pops up an alert message with the selected value.

The HTML helper methods are defined in a separate class library called MvcUtilities; the HtmlControlHelper class contains two variants that can be used for generating a markup for a disableable dropdown list. The first variant uses a string parameter to define the name of the property of the view model class that holds the selected value, the other variant uses an expression parameter to define the property. To avoid code repetition I created the DropDownList method that gets invoked by each of the variants:

C#
static IHtmlString DropDownList(
            String name,
            Object htmlAttributes,
            Func<dictionary<string,>, String> generator)

This is the main method that creates the markup for a disableable dropdown list. Before we get down to business let’s review the markup generated by the invocation of this method for the current Gender parameter defined by our view model class.

XML
<select id="ddl_cbGender" class="valid" 
                 style="color: green; width: 120px;" name="Gender" 
                 data-val-required="The Gender field is required." data-val="true">
  <option>Please select</option>
  <option value="male" selected="true">male</option>
  <option value="female">female</option>
</select>

As you can see, the actual dropdown list is encapsulated in a span element and this element contains another span element having the ID of span_Hider that serves the purpose of hiding our actual dropdown list.

The actual dropdown list will have an ID pre-pended by “ddl_” (ddl_cbGender in this case) while the outer span element will have the id provided by the user or the name of the property for which the dropdown list is generated otherwise.

The hiding of the element is accomplished by the JavaScript code that gets emitted by this helper method:

JavaScript
<script type="text/javascript">
   $(document).ready(function () {
      $.fn.extend({
         disableDropDownList: function () {
            var $ddl = $(this);

            $ddl.find('#span_Hider').css('z-index', '1');
         },
         enableDropDownList: function () {
            var $ddl = $(this);

            $ddl.find('#span_Hider').css('z-index', '-1');
         }
      });
   });
</script>

By this code we create two global methods using jQuery that toggle the status of the span_Hider element by increasing or decreasing the z-index of it.

History

  • 9 March 2012: Initial release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)