0

I have the following question regarding the MVC and Jquery. I would like to be able to call with JQuery an action serverside and then returned result bind to a drop down list.

At this moment i do have something like that but instead of SelectList i just get back an anonymous type collection.

I have following JQuery:

<script type="text/javascript">

    (function ($) {
        $.fn.cascade = function (options) {
            var defaults = {};
            var opts = $.extend(defaults, options);

            return this.each(function () {
                $(this).change(function () {
                    var selectedValue = $(this).val();
                    var params = {};
                    params[opts.paramName] = selectedValue;
                    $.getJSON(opts.url, params, function (items) {
                        opts.childSelect.empty();
                        $.each(items, function (index, item) {
                            opts.childSelect.append(
                                $('<option/>')
                                    .attr('value', item.Id)
                                    .text(item.Name)
                            );
                        });
                    });
                });
            });
        };
    })(jQuery);

    $(function () {
        $('#Location_CountryId').cascade({
            url: '@Url.Action("Regions")',
            paramName: 'countryId',
            childSelect: $('#Location_RegionId')
        });

        $('#Location_RegionId').cascade({
            url: '@Url.Action("Cities")',
            paramName: 'regionId',
            childSelect: $('#Location_CityId')
        });
    });

</script>

Which calls this action in mvc 3:

public ActionResult Cities(int regionId)
{
    IList cities;
    using (DatingEntities context = new DatingEntities())
    {
        cities = (from c in context.cities
                   where c.RegionID == regionId
                   select new
                   {
                       Id = c.CityId,
                       Name = c.Name
                   }).ToList();
    };

    return Json(cities, JsonRequestBehavior.AllowGet);
}

My question, can i then return SelectList instead of IList and bind it properly?

Could you provide an example with my code please? I have more complex behavriou just for simpleness i posted only part of.

Thanks

2
  • How about using Ajax.Begin instead of JQuery because in case of Jquery, you will have to bind it by Iteration. Commented Jun 1, 2013 at 13:00
  • oh really? hmm maybe it is also a good idea ... sec ill post all my jquery for this matter, if you can help me with ajax.Begin ... i would really be greatefull Commented Jun 1, 2013 at 13:17

3 Answers 3

2

What about creating a partial that renders the html for the selectlist options and returing that?

_SelectList.cshtml:

@model IList<SelectListItem>

@{
  foreach (var item in Model)
  {
  <option [email protected]>@item.Text</option>
  }
}

And from your controller:

public ActionResult Cities(int regionId)
{
  IList<SelectListItem> cities;
  using (DatingEntities context = new DatingEntities())
  {
    cities = (from c in context.cities
              where c.RegionID == regionId
              select new SelectListItem()
              {
                Value = c.CityId,
                Text = c.Name
              }).ToList();
  };

  return PartialView("_SelectList", cities);
}

Your js can then look like this:

<script type="text/javascript">

  (function ($) {
      $.fn.cascade = function (options) {
          var defaults = {};
          var opts = $.extend(defaults, options);

          return this.each(function () {
              $(this).change(function () {
                  var selectedValue = $(this).val();
                  var params = {};
                  params[opts.paramName] = selectedValue;
                  $.get(opts.url, params, function (items) {
                    opts.childSelect.empty();
                    opts.childSelect.html(items);
                  }
              });
          });
      };
  })(jQuery);

  $(function () {
      $('#Location_CountryId').cascade({
          url: '@Url.Action("Regions")',
          paramName: 'countryId',
          childSelect: $('#Location_RegionId')
      });

      $('#Location_RegionId').cascade({
          url: '@Url.Action("Cities")',
          paramName: 'regionId',
          childSelect: $('#Location_CityId')
      });
  });

</script>

Although - I normally do something similar to your JSON code above :-)

HTH

Sign up to request clarification or add additional context in comments.

10 Comments

no, because it should be dynamically on previous selecte value ... from another ddl, so basically, i have to use something to retrieve data from sql on change of ddl value
Not sure I get you - the js above is just to replace the $.getJSON part in your example. All the rest of your JS stays the same. The controller still receives the dynamic regionid and returns the <option> elements for the cities for that region.
hmm, ill try and how does the view looks like for the main which calls that partial? And have do i retrieve the selected value then?
Ok so the partial is only used by the Cities controller action. If the Region selectlist changes, it triggers the ajax request and we send the selected region id to the Cities action. This gets all the cities, calls the _SelectList partial which outputs a string '<option value="1">London</option><option value="2">Dublin</option>'. We simply pop this into the cities selectlist DOM element using the opts.childSelect.html() call. I'll update the stuff above to be a bit clearer...
It is ok, it is almost working but not fully, the thing is, that everything is called perfectly, and it returns good list and partial seems to be working, but the results do not appear. Maybe is something wrong with my drop down list, it looks like this: @Html.DropDownListFor(m => m.Location.RegionId, new SelectList(Enumerable.Empty<SelectListItem>()), "---select--", null)
|
0

How about just using some simple jQuery to iterate through the JSON object your Cities method returns. eg

<script>
    $('#Location_RegionId').change(function () {

    $.get('@Url.Action("Cities", "[ControllerName]")/' + $('#Location_RegionId').val(), function (data) {
        $('#Location_CityId').empty();
        $.each(data, function() {
                $('#Location_CityId').append($('<option />').val(this.CityId).text(this.Name));
                });
        });
   });

   $('#Location_RegionId').change();
<script/>

Assuming that your select with the regions in is called Location_RegionId and your select with cities has an id of Location_CityId.

For this to work as above it will need to be at the bottom of your view file, so the @Url.Action is rendered into the appropriate URL. Otherwise you can hard code it into a .js file and surround it with document.ready.

Comments

0

in the controller after getting list of cities convert it to a select list item as below

var list=new List<SelectListItem>(); 
list.AddRange(cities.Select(o => new SelectListItem
            {
                Text = o.Name,
                Value = o.CityId.ToString()
            }));
        }
return Json(list);

Comments

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.