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.

2
  • you should clear yourself more specifically... What's you exact problem ? Commented Apr 17, 2016 at 3: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 Commented Apr 17, 2016 at 3:05

1 Answer 1

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
}
Sign up to request clarification or add additional context in comments.

7 Comments

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
It does work. You have not used the code correctly. And to see a working example of a cascading dropdownlist, refer this DotNetFiddle. 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 for an example
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"
Sorry, that should be removed. And despite what you think, your model binding will not work fine. Study the fiddle I linked to.
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.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.