Make DropDownList Selection Mandatory Only If Data Exists

Environment

Product ProgressĀ® Kendo UIĀ® DropDownList for ASP.NET MVC

Description

In some cases, the DropDownList has to be mandatory only when it presents some data. If it contains no data, it does not have to be a required field.

Solution

Use the dataBound event of the DropDownList to toggle the required or data-val-required attribute that triggers the required field validation depending on the data source of the DropDownList.

The attributes that will be used depend on the validation mode you use. For example, the required attribute works in a generic HTML page and the data-val-required attribute works with the Unobtrusive Validation used in ASP.NET.

<form id="myForm" action="someAction" method="post">
    <input id="ddl" />
</form>
<script>
    var blankData = [];
    var data = [
      { text: "Black", value: "1" },
      { text: "Orange", value: "2" },
      { text: "Grey", value: "3" }
    ];

    $("#ddl").kendoDropDownList({
      dataTextField: "text",
      dataValueField: "value",
      dataSource: data, //to test, swap for blankData.
      // In a real case, this will probably be a remote data source
      optionLabel: "select an option",
      dataBound: setRequiredAttr
    });

    function setRequiredAttr(evt) {
        if (evt.sender.dataSource.data().length < 1) {
            evt.sender.element.removeAttr("required");
        }
        else {
            evt.sender.element.attr("required", "required");
        }
    }
</script>

<!-- a sample way of using a Kendo Validator to show a user friendly message -->

<div id="result"></div>
<input id="submitBtn" type="submit" value="Create" class="btn btn-default" />
<script>
    $("#submitBtn").click(function () {
        var validator = $("#myForm").kendoValidator().data('kendoValidator');
        if (validator.validate()) {
            $("#result").text("");
        } else {
            $("#result").text("fill in the form");
        }
    });
</script>

The following example demonstrates how to implement the suggested approach in MVC.

@(Html.Kendo().DropDownListFor(model => model.ClassId)
                                  .DataTextField("Name")
                                  .DataValueField("ClassId")
                                  .DataSource(source =>
                                  {
                                      source.Read(read =>
                                      {
                                          read.Action("Questions_GetClasses", "Questions");
                                      });
                                  })
                                  .Events(ev => ev.DataBound("setRequiredAttr"))
)

<script>
    function setRequiredAttr(evt) {
        if (evt.sender.dataSource.data().length < 1) {
            evt.sender.element.removeAttr("data-val-required");
        }
        else {
            evt.sender.element.attr("data-val-required", "This field is required, please choose an option.");
        }
    }
</script>

@* a sample way of using a Kendo Validator to show a user friendly message *@

<div id="result"></div>
<input id="submitBtn" type="submit" value="Create" class="btn btn-default" />
<script>
    $("#submitBtn").click(function () {
        var validator = $("#myForm").kendoValidator().data('kendoValidator');
        if (validator.validate()) {
            $("#result").text("");
        } else {
            $("#result").text("fill in the form");
        }
    });
</script>

The following example demonstrates how to implement the suggested approach with a controller and which you can toggle to see how it behaves with and without data.

[HttpGet]
public JsonResult Questions_GetClasses(string text)
{
    var data = Enumerable.Range(0, 30).Select(p => new MyClassModel
    {
        ClassId = p + 0.5f,
        Name = "Name " + p
    }
    );

    // Remove the declaration above and uncomment the empty list below.
    // Then build to test without data.

    // List<MyClassModel> data = new List<MyClassModel>();

    return Json(data, JsonRequestBehavior.AllowGet);
}

The following code implements the simple model on which the previous example is based.

namespace SampleMvcApp.Models
{
    public class MyClassModel
    {
        public float ClassId { get; set; }
        public string Name { get; set; }
    }
}
In this article
Not finding the help you need? Improve this article