Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's a nice way to do it :</p> <p>Suppose that we have two drop lists, country and city ,, the city drop down is disabled by default and when a country is selected the following happens :</p> <pre><code>1. city drop down list gets enabled. 2. An AJAX call is made to an action method with the selected country and a list of cities is returned. 3. the city drop down list is populated with the JSON data sent back. </code></pre> <p><strong>Credits for the original code goes to <a href="http://www.kingwilder.com/" rel="nofollow noreferrer">King Wilder</a> from <a href="http://www.mvccentral.net/" rel="nofollow noreferrer">MVC Central</a>. This example is a simplified version that was extracted from his code in the <a href="http://www.mvccentral.net/Article/Details/3/Golf_Tracker_-_Pt_1_-_Overview" rel="nofollow noreferrer">Golf Tracker Series</a>.</strong></p> <p><strong>HTML</strong></p> <pre><code>&lt;select id="Country"&gt; // a List of Countries Options Goes Here. &lt;/select&gt;&lt;/div&gt; &lt;select id="City" name="City" disabled="disabled"&gt; // To be populated by an ajax call &lt;/select&gt; </code></pre> <hr> <p><strong>JavaScript</strong></p> <pre><code>// Change event handler to the first drop down ( Country List ) $("#Country").change(function() { var countryVal = $(this).val(); var citySet = $("#City"); // Country need to be selected for City to be enabled and populated. if (countryVal.length &gt; 0) { citySet.attr("disabled", false); adjustCityDropDown(); } else { citySet.attr("disabled", true); citySet.emptySelect(); } }); // Method used to populate the second drop down ( City List ) function adjustCityDropDown() { var countryVal = $("#Country").val(); var citySet = $("#City"); if (countryVal.length &gt; 0) { // 1. Retrieve Cities that are in country ... // 2. OnSelect - enable city drop down list and retrieve data $.getJSON("/City/GetCities/" + countryVal , function(data) { // loadSelect - see Note 2 bellow citySet.loadSelect(data); }); } } </code></pre> <hr> <p><strong>Action Method</strong></p> <pre><code>[HttpGet] public ActionResult GetCities(string country) { Check.Require(!string.IsNullOrEmpty(country), "State is missing"); var query = // get the cities for the selected country. // Convert the results to a list of JsonSelectObjects to // be used easily later in the loadSelect Javascript method. List&lt;JsonSelectObject&gt; citiesList = new List&lt;JsonSelectObject&gt;(); foreach (var item in query) { citiesList.Add(new JsonSelectObject { value = item.ID.ToString(), caption = item.CityName }); } return Json(citiesList, JsonRequestBehavior.AllowGet); } </code></pre> <hr> <p><strong>Important Notes:</strong></p> <p><strong>1.</strong> The <code>JsonSelectObject</code> help make things easier when converting the results to an option tag as it will be used in the javascript <code>loadSelect</code> method below. it's basically a class with the two properties value and caption :</p> <pre><code>public class JsonSelectObject { public string value { get; set; } public string caption { get; set; } } </code></pre> <p><strong>2.</strong> The function <code>loadSelect</code> is a helper method that takes a list of json objects originally of type<code>JsonSelectObject</code> , converts it to a list of options to be injected in calling drop down list. it's a cool trick from the "jQuery In Action" book as referenced in the original code, it's included in a <code>jquery.jqia.selects.js</code> file that you will need to reference. Here's the code in that js file :</p> <pre><code>(function($) { $.fn.emptySelect = function() { return this.each(function() { if (this.tagName == 'SELECT') this.options.length = 0; }); } $.fn.loadSelect = function(optionsDataArray) { return this.emptySelect().each(function() { if (this.tagName == 'SELECT') { var selectElement = this; selectElement.add(new Option("[Select]", ""), null); $.each(optionsDataArray, function(index, optionData) { var option = new Option(optionData.caption, optionData.value); if ($.browser.msie) { selectElement.add(option); } else { selectElement.add(option, null); } }); } }); } })(jQuery); </code></pre> <p>This method might be complex ,,, but at the end you will have a clean &amp; compact code that you can use everywhere else.</p> <p>I hope this was helpful ,,,</p> <hr> <p><strong>Update</strong></p> <p><strong>Using POST instead of GET in the AJAX call</strong></p> <p>You can replace the <code>$.getJSON</code> call with the following code to make the ajax call using POST instead of GET.</p> <pre><code>$.post("/City/GetCities/", { country: countryVal }, function(data) { citySet.loadSelect(data); }); </code></pre> <p>also remember to change your Action method to accept POST requests by changing the [HttpGet] annotation with [HttpPost] and remove the <code>JsonRequestBehavior.AllowGet</code> when returning the result in the Action Method.</p> <p><strong>Important Note</strong></p> <p>Note that we are using the value of the selected item rather than the name. for example if the user selected the following option. </p> <pre><code>&lt;option value="US"&gt;United States&lt;/option&gt; </code></pre> <p>then "US" is sent to the Action method and not "United States"</p> <p><strong>Update 2: Accessing the Selected Values In The Controller</strong></p> <p>suppose that you have the following two properties in your <code>Vehicle</code> viewmodel:</p> <pre><code>public string Maker { get; set; } public string Model { get; set; } </code></pre> <p>and you name your select elements with the same name as your ViewModel properties.</p> <pre><code>&lt;select id="Maker" name="Maker"&gt; // a List of Countries Options Goes Here. &lt;/select&gt;&lt;/div&gt; &lt;select id="Model" name="Model" disabled="disabled"&gt; // To be populated by an ajax call &lt;/select&gt; </code></pre> <p>Then the selected values will be automatically Bound to your ViewModel and you can access them directly in you Action Method.</p> <p><strong>This will work if the page is Strongly Typed to that ViewModel.</strong></p> <hr> <p>Note: For the first list ( The Makes List ) you can create a MakersList of type SelectList in your ViewModel and use the HTML helper to automatically populate your Makers Drop Down with the list in your ViewModel. the code will look something like this :</p> <pre><code>&lt;%= Html.DropDownListFor(model =&gt; model.Maker, Model.MakersList) %&gt; </code></pre> <p>In that case the generated name for this select will be also "Maker" (the name of the property in the ViewModel).</p> <p>I hope this is the answer you are looking for.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload