2

I have a drop down list for departmentID that populates based on what is selected in DepartmentCategoryID, however I can;t get the validation working if it is left empty. It works or all others but this is done differently.

<div style="display: table-row;">
  <div class="div-label-text-mandatory" , style="display: table-cell">
    @Html.LabelFor(model => model.DepartmentCategoryID)
  </div>
  <div class="div-dropdown-menu" , style="display: table-cell">
    @Html.DropDownListFor(model => model.DepartmentCategoryID (SelectList)ViewBag.DepartmentCategory, "Please select a Staff category", new { @id = "txtDepCatID", @onchange = "javascript:GetCity(this.value);" })
  </div>
  <div class="div-val-cell" , style="display: table-cell">
    @Html.ValidationMessageFor(model => model.DepartmentCategoryID, "", new { @class = "text-danger" })
  </div>
</div>              

<div id="DepartmentDiv" style="display: none;">
  <div class="div-label-text-mandatory" , style="display: table-cell"></div>
  <div class="div-dropdown-menu" , style="display: table-cell">
    @Html.LabelFor(model => model.DepartmentID): 
    <select id="txtDepartment" name="txtDepartmentID"></select>
  </div>
  <div class="div-val-cell" , style="display: table-cell">
    @Html.ValidationMessageFor(model => model.DepartmentID, "", new { @class = "text-danger" })
  </div>
</div>

I tried adding a hidden for section i would set in jquery but this doesn't work either - not sure if hidden for can have missing validation?

<div style="display: table-row;">
  <div class="div-label-text-mandatory" , style="display: table-cell"></div>
    <div class="div-dropdown-menu" , style="display: table-cell">
      @Html.HiddenFor(model => model.DepartmentID)
    </div>
    <div class="div-val-cell" , style="display: table-cell">
      @Html.ValidationMessageFor(model => model.DepartmentID, "", new { @class = "text-danger" })
    </div>
</div>  

Jquery to populate the list:

<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script language="javascript" type="text/javascript">
    function GetCity(_GetSubDepartment) {
        var procemessage = "<option value='0'> Please wait...</option>";
        $("#txtDepartment").html(procemessage).show();
        var url = "@Url.Content("~/Employee/_GetSubDepartment")";

        $.ajax({
            url: url,
            data: { DepartmentCategoryID: _GetSubDepartment },
            cache: false,
            type: "POST",
            success: function (data) {
                console.log("Data length: "+data.length)
                if ((data.length) == 0) {
                    $('#DepartmentDiv').hide();
                }
                if ((data.length) > 0) {
                    var markup = "<option value='0'>Select department</option>";
                    for (var x = 0; x < data.length; x++) {
                        markup += "<option value=" + data[x].Value + ">" + data[x].Text + "</option>";
                        $("#txtDepartment").html(markup).show();
                        //$('#DepartmentDiv').css('display', 'table-row').animate("slow");
                        $('#DepartmentDiv').css('display', 'table-row').show();
                    }

                }
            },
            error: function (reponse) {
                alert("error : " + reponse);

            }
        });

    }
</script>

model

[DisplayName("Staff category")]
[Required(AllowEmptyStrings = false, ErrorMessage = " * is mandatory")]
public int DepartmentCategoryID { get; set; }

[DisplayName("Departments")]
[Required(AllowEmptyStrings = false, ErrorMessage = " * is mandatory")]
public int DepartmentID { get; set; }

controller:

[HttpPost]
public ActionResult _GetSubDepartment(int? DepartmentCategoryID)
{
    ViewBag.Department = new SelectList(db.vwDimDepartments.Where(m => m.DepartmentCategoryID == DepartmentCategoryID).ToList(), "DepartmentID", "DepartmentName");

    return Json(ViewBag.Department);
}

Is this because of the markup in Jquery to populate the list and that it is coming from a view bag?

Does anyone have a solution for this?

JQuery
  • 889
  • 3
  • 13
  • 35
  • Possibly because the dynamically-created selectlist isn't bound. [http://stackoverflow.com/questions/2031826/jquery-change-function-not-working-with-dynamically-populated-select-list](http://stackoverflow.com/questions/2031826/jquery-change-function-not-working-with-dynamically-populated-select-list) – markpsmith Sep 08 '15 at 15:27
  • Is it because your "select department" option has a value of `0` instead of `''`? – stephen.vakil Sep 08 '15 at 18:38

1 Answers1

4

Your adding the first option in the second dropdownlist as

var markup = "<option value='0'>Select department</option>";

which has a value of 0 which is valid for typeof int so there will never be a validation error. Change it to

var markup = "<option value=''>Select department</option>";

In addition your manually creating the html for the second <select> element

<select id="txtDepartment" name="txtDepartmentID"></select>

which has a name attribute that does not relate to your model. Instead, strongly bind to your model using

@Html.DropDownListFor(m => m.DepartmentID, Enumerable.Empty<SelectListItem>())

and adjust your script so it references $('#DepartmentID') (not $('#txtDepartment'))

Side notes:

  1. AllowEmptyStrings = false is pointless for type of int (and its the default anyway) so you can remove it.
  2. Your _GetSubDepartment() method should not be returning SelectList (you just returning unnecessary extra data that degrades performance.

Instead it should be

[HttpGet] // Its a get,  not a post (change the ajax option)
public ActionResult _GetSubDepartment(int? DepartmentCategoryID) // The parameter should be int (not nullable) or test for null
{
  var data = db.vwDimDepartments.Where(m => m.DepartmentCategoryID == DepartmentCategoryID).Select(d => new
  {
    Value = d.DepartmentID,
    Text = d.DepartmentName
  };
  return Json(data, JsonRequestBehavior.AllowGet);
}
  • Thanks for the info, I'm still not getting a validation message when it isn't selected though. Is this because I don't have any input option for the model field in the razor? The drop down is being populated but it isn't really assigned to the model.DepartmentID in the razor for it to know i guess that it needs a validation. I created a textboxfor that field with a display of none, the validation outside of that though, but still doesn't work, guessing the display none overrides the validation also. – JQuery Sep 09 '15 at 09:21
  • 1
    No your problem is you have manually created your control using `` - your model does not have a property named `txtDepartmentID`. Use `@Html.DropDownListFor(m => m.DepartmentID, Enumerable.Empty()` –  Sep 09 '15 at 09:26
  • That's brilliant thanks! works perfectly. Really appreciate your help. – JQuery Sep 09 '15 at 09:41