0

I have a DropDownList that gives me an output of:

<select name="MyFilter">
    <option value="">Choose an option</option>
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
    <option value="3">Option 3</option>
    <option value="4">Option 4</option>
</select>

I want to force users to select one of the options with a value.

How do I do this? And what are the best ways of doing this? I know MVC has attributes like [Required], but you are not creating a new row in the database, rather you are updating one, so required could not work here (I think, I am not so familiar with attributes). Do I need a custom attribute?

I'm kinda just looking to be pointed in the right direction here as my googling has been fruitless so far...

Edit:

I have added:

[Required]
public SelectList MyFilter  { get; set; }

to the ViewModel, but it has not changed functionality. It still allows the form to go through. Could this be due to me adding in the "Choose an option" option in the view like this?

@Html.DropDownList("MyFilter", ((SelectList)Model.MyFilter), "Choose an option"
Alan Schapira
  • 1,053
  • 4
  • 17
  • 32
  • `[Required]` attribute on the `viewmodel` has no impact on the database (depending on how you transfer between viewmodel-dto-database etc. What happened when you added `[Required]` to the model property? – freedomn-m Nov 13 '15 at 10:03
  • It makes no difference if you are creating or editing. Adding `[Required]` to your `MyFilter` property will ensure that a value must be selected by checking `ModelState` in the POST metod. And if you include `@Html.ValidationMessageFor(m => m.MyFilter)` and the relevant scripts you will also get client side validation. –  Nov 13 '15 at 10:03
  • take a look at [this post](http://stackoverflow.com/questions/9447134/html-select-how-to-set-default-text-which-wont-be-shown-in-drop-down-list) and see if it helps – Paulo Lima Nov 13 '15 at 10:12
  • add a class attribute to your select box.. And write a javascript function to make it mandatory. – Narayanaswamy Nov 13 '15 at 10:12
  • yes, "Choose an option" is an option of dropdownlist and thus the field have a value!!! So, the efficient way is to write a javascript function for the dropdownlist . – Narayanaswamy Nov 13 '15 at 10:27
  • DO NOT add a class attribute and DO NOT add a javascript function. MVC handles all this out of the box. And the value of the `"Choose an option"` option will post back as `null` if its selected, hence you will get a validation error. –  Nov 13 '15 at 10:30
  • Sorry Stephen, do you mind elaborating? What should I do to get the validation error? I seem to be able to submit the form without a validation error. – Alan Schapira Nov 13 '15 at 10:47
  • If you include the relevant scripts (`jquery`, `jquery.validate` and `jquery.validate.unobtrusive` and include `@Html.ValidationMessageFor(m => m.MyFilter )` then you will get a client side error message if you attempt to submit and the first option is selected. –  Nov 13 '15 at 10:50
  • But you have another major error. You cannot bind a dropdown to a complex object (ie. `SelectList`). You need a property `[Required] public int MyFilter { get; set; }` and another property for the collection - `public SelectList MyFilterList { get; set; }` –  Nov 13 '15 at 10:52
  • @Alan, would it not have been easier to have created your DDL through your database? By this I mean create a table for your DDL values, attach this to your model and then use @Html.DropDownList("MyFilter", String.Empty). This is what I do and it allows me to place the Required attribute to my ViewModel for custom validation. – Scanner Nov 13 '15 at 11:17

1 Answers1

3

You need Required attribute applied to the property that will hold the selected value and not to the select list itself:

public class ViewModel
{
    public IList<SelectListItem> MyFilterValues  { get; set; }

    [Required]
    public int MyFilter  { get; set; }
}

Usage in the view:

@Html.DropDownListFor(m=>m.MyFilter, Model.MyFilterValues, "Choose an option")
@Html.ValidationMessageFor(m => m.MyFilter) 
Alex Art.
  • 8,711
  • 3
  • 29
  • 47