Quite often you have a scenario whereby a parent dropdown causes another element to be updated based on what is selected, but not on the value selected directly but rather another piece of information related to the option selected.
For example, you want to show a country name in a textbox based on the city a user has selected in a dropdown, but the option value of each city is its primary key, not its associated parent country name so you have no direct link between option selected and a country name.
There are a number of ways to proceed including hitting the server via Ajax on city dropdown change to get the associated country and outputting a client side lookup table of sorts. A simple approach however is just to output the secondary information (in the form of a data-* attribute) to each dropdown option along with its primary value which will give you a select box whose HTML is similar to below:
After this, extracting country name from the selected option is easy.
In MVC how we’d commonly output a select box would be using a DropDownListFor HTML helper control, however if you want to add data attributes to each option when using a DropDownListFor control…well, you can’t but you can ditch the DropDownListFor helper and just output your select box manually using a foreach in razor code. Sample Razor code which will allow you to do this is below, followed by JQuery which helps you to extract the data attribute from the selected dropdown item (source code is available below).
Overview of steps to add data-* annotations
- Manually output the select tag, with an id/class/name which you can use to hook a change event to using JQuery
- Output an option for each of your collection items, to include one or more data attributes (in this case data-country) and a test to check if something should be selected.
- In jQuery, add a change event to your dropdown and extract the value by using the :selected pseudo class and the data function for getting data-* attribute values.
- Note that even though you are manually outputting your select, you can still use strongly typed LabelFor, ValidationMessageFor (assuming the names match) etc. controls around your manually outputted dropdown.
- Note the use of @Html.NameFor when generating the name of the dropdown. You’ll want to use the name which matches the viewmodel property so binding occurs correctly. This helper avoids the need for hard coding.
- Watch out for the razor syntax to output text from within an if block. You will likely need the text tag or it’s alternative :@
WordPress messes up code so I just put the images in above, but you can see the source for a sample manually outputted dropdown on .Net Fiddle