2

Below is my code, I am not sure what i am doing wrong?

Ajax json jquery code

function FillCity() {
    var countryid = $("select[name$='.countryid']").val();     //<---- this is dynamic
    $.ajax({
        url: "Controller/FillMyCity",
        type: "POST",
        dataType: "json",           
        data: { country: countryid } ,           
        success: function (city) {
            $("select[name$='.cityid']").html(""); // <--- this is dynamic
            $.each(city, function (i, pp) {
                $("select[name$='.cityid']").append(
                    $('<option></option>').val(pp.cityid).html(pp.name));
            });               
        },
        error: function (err) {                
            alert(err);
        }
    });
}

Controller method

public JsonResult FillMyCity(int country)
{

    var cities = db.Cities.Where(x => x.countryid == country).ToList().Select(item => new City
    {
        cityid = item.cityid,
        name = item.name
    }).AsQueryable();
    return Json(cities, JsonRequestBehavior.AllowGet);
}

View

@Html.DropDownList("Country[" + i + "].countryid", (SelectList)ViewData[countries], string.Empty, new { @class = "form-control countries", @id = "mycountry" + i + "", @onchange = "FillCity()" })
@Html.DropDownList("City[" + i + "].cityid", new SelectList(Enumerable.Empty<SelectListItem>(), "cityid", "name"), "Select city", new { @class = "form-control cities", @id = "mycity" + i + "" })      

Output

EmployeeName  Country                       City
Jenny         ddl of countries              ddl of cities     
John          ddl of countries              ddl of cities

Problem 1: When I select country for Jenny, the cities ddl for both Jenny + John both get populated with Jenny's Country's cities, but it should only just applied for Jenny. When I select country for John the cities ddl list doesn't get populate So only Jenny's works, John doesn't

Problem 2: Since it is a dynamic json jquery appended html, I am unable to save the cities value, this is due to the fact that it is dynamic and doesn't appear in the view source.

NULL
  • 1,559
  • 5
  • 34
  • 60
  • you should clear yourself more specifically... What's you exact problem ? – Md. Mostafizur Rahman Apr 17 '16 at 03:02
  • @Md.MostafizurRahman my problem which i have stated above states, when i select a country for Jenny, the cities for that country also get populate for John's cities' ddl? it should only apply for Jenny. another problem which i stated was not able to save "cities" to the db since it is dynamic. thanks – NULL Apr 17 '16 at 03:05

1 Answers1

0

Your use of $("select[name$='.countryid']").val(); will only ever select the value of the first element that has a name attribute ending with .countryid.

In addition, you use of DropDownList("Country[" + i + "].countryid", ...) is not the correct way to generate controls for a collection and its unlikely that will ever bind correctly to your model, however you have not shown the model so that cannot be fixed, so based on your current code, your view should be

<div class="container">
    @Html.DropDownList("Country[" + i + "].countryid", (SelectList)ViewData[countries], string.Empty, new { @class = "form-control countries" })
    @Html.DropDownList("City[" + i + "].cityid", Enumerable.Empty<SelectListItem>(), new { @class = "form-control cities" })
</div>

and the script

$('.countries').change(function() {
    var country = $(this).val();
    var cities = $(this).next('.cities'); // get the associated cities dropdownlist
    cities.empty(); // clear existing options
    $.ajax({
        url: '@Url.Action("FillMyCity")', // do not hard code url's
        type: "POST",
        dataType: "json",           
        data: { country: country } ,           
        success: function (data) {
            if (data) {
                cities.append($('<option></option>').val('').text('Select city'));
                $.each(data, function (index, item) {
                    cities.append($('<option</option>').val(item.cityid).html(item.name));
                });
             } else {
                 // oops
             }            
        },
        error: function (err) {                
            alert(err);
        }
    });
});

and finally, return a collection of anonymous objects containing only the data you need in the view to avoid sending extra data that will not be used

public JsonResult FillMyCity(int country)
{
    // No need for .ToList()
    var cities = db.Cities.Where(x => x.countryid == country).Select(item => new
    {
        cityid = item.cityid,
        name = item.name
    });
    return Json(cities); // its a POST so no need for JsonRequestBehavior.AllowGet
}
  • thanks for your response however it doesn't work, and i am getting [object object]. also regarding the names of the ddl "Country[" + i + "].countryid" and "City[" + i + "].cityid". I did this because I can then loop through the collection for each individual selection, it does work for countries, but not for the position. one last thing, how do I select the selected positions back to json? many thanks – NULL Apr 18 '16 at 12:57
  • It does work. You have not used the code correctly. And to see a working example of a cascading dropdownlist, refer [this DotNetFiddle](https://dotnetfiddle.net/1bPZym). And you need to learn the basics of mdoel binding to a collection - you bind to a collection using a `for` loop or `EditorTemplate` - refer [this answer](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943) for an example –  Apr 18 '16 at 13:03
  • thanks for your fast response. the model binding is fine, it is the [object object] that i can't seem to pass. btw, i wasn't able to use enumerable as i was getting this error too: "system linq iqueryable anonymous type 1 does not contain a definition for enumerable" – NULL Apr 18 '16 at 13:05
  • Sorry, that should be removed. And despite what you think, your model binding will not work fine. Study the fiddle I linked to. –  Apr 18 '16 at 13:09
  • What do you mean _doesn't append the html to the position_? `var cities = $(this).next('.cities');` will get the the next dropdown immediately following the one you made the selection in - the one with `class="cities"`) so it will append the options to that one. –  Apr 18 '16 at 13:17
  • i think this is the problem $(this).next('.cities'); when i hard code cities, it appends to that position. – NULL Apr 18 '16 at 13:18
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/109447/discussion-between-stephen-muecke-and-menew). –  Apr 18 '16 at 13:18