0

I have two linked combo, Year and Week.

Im sending the list of year and empty data set for week to the View

ViewBag.YearID = new SelectList(db.years, "YearID", "Name");
ViewBag.WeekID = new SelectList(db.week_list.Where(x => x.Name == ""), "WeekID", "Name");

In the View I have

@Html.DropDownList("YearID", null, "Seleccione Año", htmlAttributes: new { @class = "form-control" })
@Html.DropDownList("WeekID", null, htmlAttributes: new { @class = "form-control" })

Right now when start Year have a help message Select Year without value.

<select class="form-control" id="YearID" name="YearID">
    <option value="">Seleccione Año</option>
    <option value="7">2016</option>
    <option value="8">2017</option>
    <option value="9">2018</option>
</select>

So because not year has been selected I pass an empty list for weeks and result on this:

<select class="form-control" id="WeekID" name="WeekID">
</select>

Starting State:

enter image description here

The problem is when I hit Create button to send the form. The action controller get the wrong value for WeekID

 YearID = null  -- as I espect
 WeekID = 0     -- dont know why. I expect null

Then the validation show Year is required, but doesnt show anything for Week because already received 0

Validation State:

enter image description here

Juan Carlos Oropeza
  • 47,252
  • 12
  • 78
  • 118
  • The selection of Year dropdown has nothing to do with your Week dropdown. Your current code `db.week_list.Where(x => x.Name == "")` is returning 0 results, hence the razor view renders an empty SELECT element. Remove the where clause from the linq expression and see what happens. – Shyju Apr 18 '18 at 23:45
  • You need to make both properties nullable and with the `[Required]` attribute. And that is possibly the worst way to generate you ` –  Apr 19 '18 at 00:14
  • @StephenMuecke Both are already `[Required]` but dont allow null, because they are Required. The problem isnt with the Year, is with the Week dropdown. If I create an empty list return value 0 when should return NULL – Juan Carlos Oropeza Apr 19 '18 at 04:37
  • It need to be nullable and `[Required]`! When you submit the form, no value is posted for `Week` therefore its set to the default (i.e. `0` for an `int`). Refer also [this answer](https://stackoverflow.com/questions/43688968/what-does-it-mean-for-a-property-to-be-required-and-nullable/43689575#43689575) –  Apr 19 '18 at 04:38
  • @Shyju There is a javascript code populating Week when Year change. But when page load and no year has been selected the Weeks is empty – Juan Carlos Oropeza Apr 19 '18 at 04:39
  • @StephenMuecke I can try. But I dont understand why have different behaviour. Right now both are required and dont allow null, and as you can see the behaviour is different. Because by default the Year has `` and that option return null But because Week have empty list return 0. – Juan Carlos Oropeza Apr 19 '18 at 04:46

2 Answers2

1

You need to make the property nullable and add the [Required] attribute.

When you submit your form, the DefaultModelBinder initializes your model, and at that point, the value of YearID and WeekID are both 0 (the default value for int)

The name/value pairs are then read from the request. Because there is a name/value pair for YearID which is null, the DefaultModelBinder attempts to set YearID = null which fails, and a ModelState error is added for YearID (the actualValue of the property is 0 and the attemptedValue is null)

Because the dropdownlist for WeekID does not contain any <option> elements, no name/value pair is sent in the request, so no attempt is made to set the value, and the value of WeekID remains a 0. Because 0 is valid for int, there is no ModelState error for WeekID, which is why no error message is displayed.

In addition, your use of DropDownList() means that no matter what you select in the first dropdownlist, when you return the view, the first option (Seleccione Año) will be selected (what the user previously selected is lost)

You are editing data so you should always be using a view model which will include

public class YourVM
{
    [Required(ErrorMessage = "...")]
    public int? SelectedYear { get; set; } // nullable
    [Required(ErrorMessage = "...")]
    public int? SelectedWeek { get; set; } // nullable
    public IEnumerable<SelectListItem> YearList { get; set; }
    public IEnumerable<SelectListItem> WeekList { get; set; }
}

and in the view, strongly bind to your model

@Html.DropDownListFor(m => m.SelectedYear, Model.YearList, "Seleccione Año", new { @class = "form-control" })
@Html.ValidatinMessageFor(m => m.SelectedYear)

@Html.DropDownListFor(m => m.SelectedWeek, Model.WeekList, "Seleccione Año", new { @class = "form-control" })
@Html.ValidatinMessageFor(m => m.SelectedWeek)
  • The nullable property work perfect. The key was understand the model is initialize with the default values. But I can't use the strongly bind for Week because that is a cascade combo. So depend on what you have selected from Year. Unless there is a way to do that without javascript? Can you encapsulate a method in YourVM class to return the filter IEnumerable for Weeks? Right now Im using getJson from JQuery – Juan Carlos Oropeza Apr 19 '18 at 14:34
  • Yes you can, and absolutely should use the strongly bound `HtmlHelper` methods (always). And if you want to understand how to generate cascading dropdownlists, refer [this DotNetFiddle](https://dotnetfiddle.net/1bPZym) –  Apr 19 '18 at 21:40
  • Is me or that .Net fiddle have issue with the scroll botton of the mouse? – Juan Carlos Oropeza Apr 20 '18 at 02:16
  • What issue are you having with the mouse? –  Apr 20 '18 at 03:11
  • I try to scroll down but jump back up. Have to use arrow instead – Juan Carlos Oropeza Apr 20 '18 at 03:25
  • Works fine for me –  Apr 20 '18 at 03:26
  • Thanks for the sample anyway that is just what I need. There is a minor issue not sure if can be solved. https://i.stack.imgur.com/xm51Q.png if you press save with everything empty. You get all the error message. If you start filling the combos the error go away. But if you deselect the combo the error is back, but only for that combo – Juan Carlos Oropeza Apr 20 '18 at 03:59
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/169391/discussion-between-stephen-muecke-and-juan-carlos-oropeza). –  Apr 20 '18 at 04:01
  • Hey stephen, could you take a look to the fiddle? Or should I start a new question to try to get help about it? – Juan Carlos Oropeza Apr 30 '18 at 14:52
0

I know it is not the answer you asked but the pattern I use to handle the dependent control issue is to show the second only after the first is valid. From experience, this pattern saves me a lot of headaches.

Siraj K
  • 158
  • 1
  • 8