2

My end goal is to be able to select a value in one DropDownList, and after having made that selection, I want another DropDownList to be populated based on the selection made in the first one. My form should have a DropDownList full of a list of provinces and a DropDownList full of cities for the selected province.

I am new to ASP MVC so I am not sure how this will be accomplished. If this had to be done in Winforms or WPF I would be able to implement it since i know how data is propagated from my Business logic to the controls displayed to the user - however in MVC I am not comfortable enough to know how to do this correctly and effectively. I am also in the process of learning javascript and associated helpers(eg. jQuery), so I need some assistance in using things like ajax to accomplish my goal.

Here is what I have already and what I know I should have to achieve my goal :

My Model(To capture the input from user):

    public class CaptureCreateTrip
    {
        [Required]
        [Display(Name = "Trip ID")]
        public string TripID { get; set; }

        [Required]
        public string StartPointProvince { get; set; }

        [Required]
        public string StartPointCity { get; set; }

        [Required]
        public string EndPointProvince { get; set; }

        [Required]
        public string EndPointCity { get; set; }
    }

My Form:

Keep in mind that I just inserted the ViewBag reference to act as a place holder till I can replace it with dynamic data.

@using (Html.BeginForm("CreateOneWayTrip", "Trips"))
        {
            @Html.ValidationSummary(false);
            <fieldset>
                <legend>Enter Your Trip Details</legend>

                <label>Start Point</label>
                @Html.DropDownListFor(m => m.StartPointProvince, (SelectList)ViewBag.Provinces);
                @Html.DropDownListFor(m => m.StartPointCity, (SelectList)ViewBag.Cities);

                <label>End Point</label>
                @Html.DropDownListFor(m => m.EndPointProvince, (SelectList)ViewBag.Provinces);
                @Html.DropDownListFor(m => m.EndPointCity, (SelectList)ViewBag.Cities);

                <p style="float: none; text-align: center;">
                    <button type="submit" value="Create" class="btn btn-info btn-circle btn-lg">
                        <i class="fa fa-check"></i>
                    </button>

                    <button type="submit" value="Create" class="btn btn-warning btn-circle btn-lg">
                        <i class="fa fa-times"></i>
                    </button>
                </p>
            </fieldset>
        }

The controller:

        //To Show Create Page
        public ActionResult Create()
        {
            return View();
        }

        // To Get Data after post
        [HttpPost]
        public ActionResult Create(Models.CaptureCreateTrip trip)
        {
            Models.CaptureCreateTrip t = trip;

            return Redirect("~/Trips/Index");
        }

        //Will I need a controller to get json data?

Also, what javascript do I have to include in my page to (1) Trigger an event on the dropdownlist Selection Changed event and (2) fetch appropriate data(list of cities for selected province).

UPDATE:

Here is a snippet of the page source that is generated:

<select Id="province_dll" class="form-control" data-val="true" data-val-required="The StartPointProvince field is required." id="StartPointProvince" name="StartPointProvince"><option value="NC">Northern Cape</option>
<option value="FS">Free State</option>
<option value="WC">Western Cape</option>
</select>
                <select Id="city_dll" class="form-control" data-val="true" data-val-required="The StartPointCity field is required." id="StartPointCity" name="StartPointCity"><option value="NC">Kimberley</option>
<option value="FS">Boshof</option>
<option value="WC">Barkley</option>
</select>

Here is the javascript I wrote:

$("province_dll").change(function () {
        $.ajax({
            url: 'getCities/Trips',
            type: 'post',
            data: {
                provinceId: $("province_dll").val()
            }
        }).done(function (response) {
            $("cities_dll").html(response);
        });
    });

And here is my controller(ps. Data is just test data, will connect with db later):

    [HttpPost]
    public ActionResult getCicites(int provinceId)
    {
        var lstCities = new SelectList(new[] { "City1", "City2", "City3" });

        return Content(String.Join("", lstCities));
    }

However it's still not working - When I select a different value in the first DropDownList, nothing happens.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Marnus Steyn
  • 1,053
  • 2
  • 16
  • 44

2 Answers2

2

You should create a ajax call in the change event of the province ddl. This call will request to an action and return the cities of selected province.

$("province_dll").change(function(){
    $.ajax({
         url: 'getCitiesController/getCitiesAction',
         type: 'post',
         data: {
               provinceId: provinceIdVar
         }
    }).done(function(response){
         $("cities_dll").html(response);
    }); 
});

In the action:

[HttpPost]
public ActionResult getCicitesAction(int provinceId)
{
     var cities = db.cities.Where(a => a.provinceId == provinceId).Select(a => "<option value='" + a.cityId + "'>" + a.cityName + "'</option>'";

     return Content(String.Join("", cities));
}
Márcio Gonzalez
  • 1,020
  • 1
  • 8
  • 20
  • Just a quick question - What is the 'provinceIdVar' variable and where do I get it? – Marnus Steyn Apr 25 '15 at 17:43
  • 1
    @MarnusSteyn provinceIdVar is the value of the province dropdownlist. You can get it like this: $("province_dll").val(); – Márcio Gonzalez Apr 27 '15 at 13:02
  • I updated my post, if you can just give it a look. Just look the content after the 'UPDATED' Text. – Marnus Steyn Apr 28 '15 at 15:55
  • I inserted an 'alert("response)' in the .done of the ajax code to confirm that the data is being fetched and see what is returned, and when I Choose an item in the DropDownList the event fires because the alert indeed does pop up, but the values returned in the 'response' field are equal to "System.Web.Mvc.SelectListItemSystem.Web.Mvc.SelectListItemSystem.Web.Mvc.Select‌​ListItem" – Marnus Steyn May 02 '15 at 09:25
0

So I'm assuming that the first dropdown is passed in the ViewBag as is, but the second drop down you need to be populated based on whatever item is selected in the first list. Is that correct?

Basically, that amounts to making an AJAX call from the view on dropbox1 selection, grabbing the returnded data from a JsonResult action in your controller, and building the second dropdown from that.

With a bit of connecting the dots, you may find that the following post provides most of what you need.

From that post:

View:

<script type="text/javascript">
$('body').on('change', '.combo', function () {
   var selectedValue = $(this).val();
   alert(selectedValue);
   $.get("/Home/getcity", { country: selectedValue }, function (data) {
       $("#tese").html(data);
       $(".combo2").html("<option value = \"\"></option>")
       $.each(data, function (index, value) {
          $(".combo2").append("<option value = \"" + value + "\">" + value + "</option>");
       });
       $(".combo2").html()
   });
});
</script>

And Controller:

public JsonResult getCity(string country)
{
    var temp = (from cntry in db.Table3.OrderBy(s => s.country)
                where (string.Compare(cntry.country, country) == 0)
                select cntry.city).ToList();
    return Json(temp, JsonRequestBehavior.AllowGet);
}

Of course, the example varies a bit but the general approach is the same: find the selected value and make an AJAX request; using Linq, grab the necessary data for the second select list; return the results to the view in a Json object.

Community
  • 1
  • 1
sukotto1
  • 190
  • 9