ASP.net cascading dropdown list - model-view-controller

trying to implement country state dropdown in mvc but couldn't..
conotroller :-
[HttpGet]
public ActionResult GetCities(int StateId)
{
Business.Services.City cityService = new Business.Services.City();
List<Business.Models.City> stateList = cityService.GetCityByStateId(StateId);
//var jsonSerialiser = new JavaScriptSerializer();
//var json = jsonSerialiser.Serialize(stateList);
return Json(new { stateList }, JsonRequestBehavior.AllowGet);
}
method:
public List<Models.City> GetCityByStateId(int StateId)
{
try
{
var list = new List<SelectListItem>();
Collection<DBParameters> parameters = new Collection<DBParameters>();
parameters.Add(new DBParameters() { Name = "StateId", DBType = DbType.Int32, Value = StateId });
var city = this.ExecuteProcedure<Models.City>("GetCityByState", parameters).ToList();
//if (city != null && city.Count > 0)
//{
// list = city.Select(x => new SelectListItem { Text = x.CityName, Value = x.StateId.ToString() }).ToList();
//}
return city;
}
catch (Exception ex)
{
throw;
}
}
change event:
$('.ddlstate').change(function () {
debugger;
$.ajax({
url: '#Url.Action("GetCities", "User")',
type: "GET",
data: { StateId: $(this).val() },
dataType: "json",
success: function (result) {
debugger;
//alert(result.stateList[0].CityId);
$.each(result.stateList, function () {
debugger;
$('.cityddl').append($("<option></option>").val(CityId).html(CityName));
});
},
error: function (result, status, jQxhr) {
alert("Error: " + result + "-" + status + "-" + jQxhr);
}
});
});
i get count of the citites in method and controller but when i run project and change state dropdown i got blank city dropdown. what is wrong?

It looks like you're missing a couple of things in the $.each() call.
You should pass the JSON result from the ajax call to the $.each
You also need to provide a parameter to the callback function so that the callback function has something to work with
It could look something like this:
$.each(result.stateList, function(index, city) {
$('.cityddl').append($("<option></option>").val(city.CityId).html(city.CityName));
});

Related

how to use cascading dropdownlist in mvc

am using asp.net mvc3, i have 2 tables in that i want to get data from dropdown based on this another dropdown has to perform.for example if i select country it has to show states belonging to that country,am using the following code in the controller.
ViewBag.country= new SelectList(db.country, "ID", "Name", "--Select--");
ViewBag.state= new SelectList("", "stateID", "Name");
#Html.DropDownListFor(model => model.Country, (IEnumerable<SelectListItem>)ViewBag.country, "-Select-")
#Html.DropDownListFor(model => model.state, (IEnumerable<SelectListItem>)ViewBag.state, "-Select-")
but by using this am able to get only the countries.
There is a good jQuery plugin that can help with this...
You don't want to refresh the whole page everytime someone changes the country drop down - an ajax call to simply update the state drop down is far more user-friendly.
Jquery Ajax is the best Option for these kind of questions.
Script Code Is Given below
<script type="text/javascript">
$(function() {
$("##Html.FieldIdFor(model => model.Country)").change(function() {
var selectedItem = $(this).val();
var ddlStates = $("##Html.FieldIdFor(model => model.state)");
$.ajax({
cache:false,
type: "GET",
url: "#(Url.Action("GetStatesByCountryId", "Country"))",
data: "countryId=" ,
success: function (data) {
ddlStates.html('');
$.each(data, function(id, option) {
ddlStates.append($('<option></option>').val(option.id).html(option.name));//Append all states to state dropdown through returned result
});
statesProgress.hide();
},
error:function (xhr, ajaxOptions, thrownError){
alert('Failed to retrieve states.');
statesProgress.hide();
}
});
});
});
</script>
Controller:
public ActionResult GetStatesByCountryId(string countryId)
{
// This action method gets called via an ajax request
if (String.IsNullOrEmpty(countryId))
throw new ArgumentNullException("countryId");
var country = GetCountryById(Convert.ToInt32(countryId));
var states = country != null ? GetStatesByConutryId(country.Id).ToList() : new List<StateProvince>();//Get all states by countryid
var result = (from s in states
select new { id = s.Id, name = s.Name }).ToList();
return Json(result, JsonRequestBehavior.AllowGet);
}
Try this,
<script type="text/javascript">
$(document).ready(function () {
$("#Country").change(function () {
var Id = $("#Country").val();
$.ajax({
url: '#Url.Action("GetCustomerNameWithId", "Test")',
type: "Post",
data: { Country: Id },
success: function (listItems) {
var STSelectBox = jQuery('#state');
STSelectBox.empty();
if (listItems.length > 0) {
for (var i = 0; i < listItems.length; i++) {
if (i == 0) {
STSelectBox.append('<option value="' + i + '">--Select--</option>');
}
STSelectBox.append('<option value="' + listItems[i].Value + '">' + listItems[i].Text + '</option>');
}
}
else {
for (var i = 0; i < listItems.length; i++) {
STSelectBox.append('<option value="' + listItems[i].Value + '">' + listItems[i].Text + '</option>');
}
}
}
});
});
});
</script>
View
#Html.DropDownList("Country", (SelectList)ViewBag.country, "--Select--")
#Html.DropDownList("state", new SelectList(Enumerable.Empty<SelectListItem>(), "Value", "Text"), "-- Select --")
Controller
public JsonResult GetCustomerNameWithId(string Country)
{
int _Country = 0;
int.TryParse(Country, out _Country);
var listItems = GetCustomerNameId(_Country).Select(s => new SelectListItem { Value = s.CountryID.ToString(), Text = s.CountryName }).ToList<SelectListItem>();
return Json(listItems, JsonRequestBehavior.AllowGet);
}

jquery $.ajax call for MVC actionresult which returns JSON triggers .error block

I have the following $.ajax post call. It would go through the action being called but then it would trigger the "error" block of the function even before the actionresult finishes. Also, it seems to reload the whole page after every pass.
var pnameVal = '<%: this.ModelCodeValueHelper().ModelCode%>';
var eidVal = '<%: ViewBag.EventId %>';
var dataV = $('input[ name = "__RequestVerificationToken"]').val();
var urlVal = '<%: Url.Action("New") %>';
alert('url > ' + urlVal);
alert('pname - ' + pnameVal + ' eid - ' + eidVal + ' dataV = ' + dataV);
$.ajax({
url: urlVal,
//dataType: "JSONP",
//contentType: "application/json; charset=utf-8",
type: "POST",
async: true,
data: { __RequestVerificationToken: dataV, pname: pnameVal, eId: eidVal },
success: function (data) {
alert('successssesss');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest);
alert(textStatus);
alert(errorThrown);
alert('dammit');
}
})
.done(function (result) {
if (result.Success) {
alert(result.Message);
}
else if (result.Message) {
alert(' alert' + result.Message);
}
alert('done final');
//$('#search-btn').text('SEARCH');
waitOff();
});
This is the action
[HttpPost]
public ActionResult New(string pname, int eid)
{
var response = new ChangeResults { }; // this is a viewmodel class
Mat newMat = new Mat { "some stuff properties" };
Event eve = context.Events.FirstOrDefault(e => e.Id == eid);
List<Mat> mats = new List<Mat>();
try
{
eve.Mats.Add(newMat);
icdb.SaveChanges();
mats = icdb.Mats.Where(m => m.EventId == eid).ToList();
response.Success = true;
response.Message = "YES! Success!";
response.Content = mats; // this is an object type
}
catch (Exception ex)
{
response.Success = false;
response.Message = ex.Message;
response.Content = ex.Message; // this is an object type
}
return Json(response);
}
Btw, on fiddler the raw data would return the following message:
{"Success":true,"Message":"Added new Mat.","Content":[]}
And then it would reload the whole page again. I want to do an ajax call to just show added mats without having to load the whole thing. But it's not happening atm.
Thoughts?
You probably need to add e.preventDefault() in your handler, at the beginning (I am guessing that this ajax call is made on click, which is handled somewhere, that is the handler I am talking about).

how to bind the dropdownlist using ajax

I need to bind the ddl values from another dropdownlist(ddl) result using ajax and mvc3
Related: how to get the result from controller in ajax json
Better try the below approach for cascading dropdownlist.
[Script]
function SetdropDownData(sender, args) {
$('#ShipCountry').live('change', function () {
$.ajax({
type: 'POST',
url: 'Home/GetCities',
data: { Country: $('#ShipCountry').val() },
dataType: 'json',
success: function (data) {
$('#ShipCity option').remove();
$.each(data, function (index, val) {
var optionTag = $('<option></option>');
$(optionTag).val(val.Value).text(val.Text);
$('#ShipCity').append(optionTag);
});
}
});
});
}
[Controller]
public IEnumerable<SelectListItem> Cities(string Country) // ShipCity is filtered based on the ShipCountry value
{
var Cities = new NorthwindDataContext().Orders.Where(c=>c.ShipCountry == Country).Select(s => s.ShipCity).Distinct().ToList();
List<SelectListItem> type = new List<SelectListItem>();
foreach (var city in Cities)
{
if (city != null)
{
SelectListItem item = new SelectListItem() { Text = city.ToString(), Value = city.ToString() };
type.Add(item);
}
}
return type;
}
public ActionResult GetCities(string Country)
{
return Json(Cities(Country), JsonRequestBehavior.AllowGet);
}

returning different javascript object from controller

my controller action:
[HttpPost]
public ActionResult AddPointAndCopyOtherSongToPlaylist(int id)
{
if (CheckIfAddPointToSelf(User.Identity.Name, id))
{
var song = repository.GetSong(id);
foreach (var item in song.Points)
{
if (User.Identity.Name == item.UsernameGavePoint)
{
var data1 = 1;
return Json(new {data1}, JsonRequestBehavior.AllowGet);
}
}
var originalSong = repository.GetSong(id);
var newSong = new Song();
newSong.UserName = User.Identity.Name;
newSong.Title = originalSong.Title;
newSong.YoutubeLink = originalSong.YoutubeLink;
newSong.GenreId = 38;
newSong.Date = DateTime.Now;
repository.AddSong(newSong);
var point = new Point();
point.UsernameGotPoint = originalSong.UserName;
point.UsernameGavePoint = User.Identity.Name;
point.Date = DateTime.Now;
point.Score = 1;
point.OtherSongId = id;
repository.AddPoint(point);
repository.Save();
int data = 2;
//process here
return Json(new { data }, JsonRequestBehavior.AllowGet);
}
else
{
return null;
}
}
based on different scenarios I want to return a javascript and somehow notify the client of what was returned and based in the result do something in the success part of my ajax call:
$.ajax({
beforeSend: function () { ShowAjaxLoader(); },
url: "/Home/AddPointAndCopyOtherSongToPlaylist/",
type: "POST",
data: { id: songId },
success: function (data,one) {
if (data && !one) {
HideAjaxLoader(), ShowMsg("Song Added Successfully");
}
else if(!data) {
HideAjaxLoader(), ShowMsg("you cannot add your own songs");
}
else if (data && one) {
HideAjaxLoader(), ShowMsg("You cannot add the same song twice");
}
},
error: function () { HideAjaxLoader(), ShowMsg("Song could not be added, please try again") }
});
});
I tried many different variations but I think i need something like data.property1 returned and in the client to check if that property exists or soemthing like that.. please help
You need to return your status code within the object.
return Json( new { data1 = "Some Other Data", status = 1} );
Then in your success handler check data.status.
if (data.status === 1) {
alert(data.data1);
}

sending multiple parameters asp.net mvc jquery ajax

I get server error:status of 500 when I try to send 2 parameters to my action in a controller with jquery ajax, dont know why?
this is the jquery code:
$(".genreLinks").click(function () {
var genreId = $(this).attr("name");
var songId = $("#hiddenRank").val();
$.ajax({
beforeSend: function () { ShowAjaxLoader(); },
url: "/Home/AddPointAndCopyTopTenFavToPlaylist/",
type: "POST",
data: { id: songId, genre: genreId },
success: function (data) {
if (data.status === 1) {
HideAjaxLoader(), ShowMsg("Song Added Successfully")
}
else if (data.status === 4) {
HideAjaxLoader(), ShowMsg("you cannot add your own songs");
}
else if (data.status === 3) {
HideAjaxLoader(), ShowMsg("Cannot add the song. The song was most likely modified or Deleted, we advise you to refresh the page");
}
else if (data.status === 2) {
HideAjaxLoader(), ShowMsg("You cannot add the same song twice");
}
},
error: function () { HideAjaxLoader(), ShowMsg("Song could not be added, please try again") }
});
});
controller's action code that accepts two parameters from my request:
[HttpPost]
public ActionResult AddPointAndCopyTopTenFavToPlaylist(int id, int genre)
{
var song = repository.GetTopTenFav(id);
if (song != null)
{
if (!(song.UserName.ToLower() == User.Identity.Name.ToLower()))
{
foreach (var item in song.Points)
{
if (User.Identity.Name.ToLower() == item.UsernameGavePoint.ToLower())
{
return Json(new { status = 2 }, JsonRequestBehavior.AllowGet);
}
}
var newSong = new Song();
newSong.UserName = User.Identity.Name;
newSong.Title = song.Title;
newSong.YoutubeLink = song.YoutubeLink;
newSong.GenreId = genre;
newSong.Date = DateTime.Now;
repository.AddSong(newSong);
var point = new Point();
point.UsernameGotPoint = song.UserName;
point.UsernameGavePoint = User.Identity.Name;
point.Date = DateTime.Now;
point.Score = 1;
point.TopTenFavId = id;
repository.AddPoint(point);
repository.Save();
return Json(new { status = 1 }, JsonRequestBehavior.AllowGet);
}
else
{
return Json(new { status = 4 }, JsonRequestBehavior.AllowGet);
}
}
else
{
return Json(new { status = 3 }, JsonRequestBehavior.AllowGet);
}
}
I have also registered my new route:
routes.MapRoute(
"AddPoint", // Route name
"{controller}/{action}/{songId},{genreId}", // URL with parameters
new { controller = "Home", action = "", songId = UrlParameter.Optional, genreId = UrlParameter.Optional } // Parameter defaults
);

Resources