jQuery mobile cascading dropdown list do not update properly - asp.net-mvc-3

I'm using cascading drop down lists in my MVC application, and it works fine.
I have added the jQuery mobile library to make it look better in mobile devices browser and I have kind of bug.
An example:
if I choose first time Chevrolet it populate child drop down with Chevrolet models. - as expected
if I choose second time another make I still see the models from previous make, but if I select it I see the new model. It looks like it cashing the models from previous make.
Here is my code:
$(document).ready(function () {
$('select#Makes').change(function () {
getModels();
});
});
function getModels() {
var make = $('#Makes').val();
var myselect2 = $("select#Models");
myselect2[0].selectedIndex = 3;
myselect2.selectmenu("refresh");
$.ajax({
type: "POST",
url: "/Services/CarService.asmx/Models",
data: "{makeId: '" + make + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var models = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
$('#Models').attr('disabled', false).removeOption(/./); //.addOption('', ' -- Select Model -- ');
var select = document.getElementById("Models");
for (var i = 0; i < models.length; i++) {
var val = models[i];
var text = models[i];
$('select#Models').addOption(val, text, true);
}
var myselect = $("select#Models");
myselect[0].selectedIndex = 3;
myselect.selectmenu("refresh");
}
});
}
#Html.DropDownList("Makes", "Please select make")
#Html.DropDownListFor(x => x.Models, new SelectList(Enumerable.Empty<SelectListItem>(), "value", "text"), "Select a Model", new { id = "Models" })

Related

Populate One Dropdown on selection of other -MVC

I am trying to populate one dropdown list based on the selection of other dropdown list. This is what I have till now.
My Controller:
[HttpPost]
public JsonResult LoadReasonsByCategory(string resId)
{
var queryy = from item in db.T_SD_CD_GROUP
where resId.Contains(item.SCG_CD_TYPE)
select new
{
item.SCG_CD_TYPE,
item.SCG_CD_DESC
};
var ObjList = new List<SelectListItem>();
foreach (var item in queryy)
{
ObjList.Add(new SelectListItem() { Text = item.SCG_CD_DESC.ToString(), Value = (item.SCG_CD_TYPE) });
}
return Json(ObjList, JsonRequestBehavior.AllowGet);
}
JS
$("#ddlReasonCategory").on('change', function () {
var item = $(this).find("option:selected");
var value = $("#ddlReasonCategory").val(); //get the selected option value
//var text = item.html(); //get the selected option text
//alert(item.val());
$.ajax({
url: '/CRActual/LoadReasonsByCategory',
type: 'POST',
datatype: 'application/json',
contentType: 'application/json',
data: JSON.stringify({ resId: value}),
success: function (data) {
alert("sUccess");
$("#ddlReasonType").html("");
ddlReasonType.append($('<option></option>').val("").html("Please select a City"));
for (var i = 0; i < data.length; i++) {
ddlReasonType.append($('<option></option>').val(data[i].Text).html(data[i].Text));
}
},
error: function () {
alert("Fail")
},
});
View:
#Html.DropDownList("ddlReasonCategory", (IEnumerable<SelectListItem>)ViewBag.ddlReasonCategory, new { #class = "chosen-select col-md-3", #data_placeholder = "Please select" })
#Html.DropDownList("ddlReasonType", new SelectList(string.Empty, "Value", "Text"), "Please select a Reason", new { #class = "chosen-select col-md-3", #data_placeholder = "Please select" })
The codes runs absolutely without any errors, but the second drop down binding fails. Where am I going Wrong?
If your LoadReasonsByCategory method returns data correctly then write the success function code in the Ajax as follows:
success: function (data) {
var ddlResonTypeSelector = $("#ddlReasonType");
ddlResonTypeSelector.empty();
if (data.length > 0) {
ddlResonTypeSelector.append($("<option>").val("").text("Please select a Reason Type"));
$(data).each(function(index, item) {
ddlResonTypeSelector.append($("<option>").val(item.value).text(item.text));
});
} else {
ddlResonTypeSelector.append($("<option>").val("").text("Reason Type List is empty!"));
}
},

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);
}

css Property for jquery ajax success function

I'm working with MVC3, using the following jQuery AJAX call:
function Displaymaingrid () {
var Geo = $('#ddlGeo').val();
var Vertical = $('#ddlVertical').val();
var Month = $('#ddlMonth').val();
if(Vertical == "All")
{
var Flag = 1;
}
else
{
var Flag = 2;
}
$.ajax({
url: "#Url.Action("TRUnutilizedOwnershipChange", "TravelReady")",
datatype: "html",
type: "post",
data: {strGeo:Geo, strVertical:Vertical, intMonth:Month, intFlag:Flag},
error: function(){},
success: function(data){
$('.travTableContent').empty();
var text3 = data.data.lstunutilizedownershipentities;
for( var item in text3)
{
$('<tr />').html(text3[item]).appendTo('.travTableContent');
$('<td />').html(text3[item].CurrentOwnership).appendTo('.travTableContent');
$('<td />').html('' + text3[item].cnt + '').appendTo('.travTableContent');
}
}
});
}
I want to set the CSS property for success function:
$('<tr />').html(text3[item]).appendTo('.travTableContent');
I want to add the following CSS property in the above line:
("tr:odd").css("background-color", "#d0d1e2")
Where do I need to insert this line?
Add it after the "for" statement.
for( var item in text3){
$('<tr />').html(text3[item]).appendTo('.travTableContent');
$('<td />').html(text3[item].CurrentOwnership).appendTo('.travTableContent');
$('<td />').html('' + text3[item].cnt + '').appendTo('.travTableContent');
}
$("tr:odd").css("background-color", "#d0d1e2");

Synchronised Ajax requests with JQuery in a loop

I have the following situation: I need to make synchronized Ajax requests within a loop and display the returned result after each iteration in a div-element (appended on top with the previous results at the bottom). The response time of each request can be different but the order in which it should be displayed should be the same as issued. Here is an example with 3 requests. Lets say request "A" needs 3 seconds, "B" needs 1 second and "C" needs 5 seconds. The order I want to display the result is A, B, C as the requests were issued but the code I use shows the results in B, A, C.
Here is the code (JQuery Ajax request):
$(document).ready(function(){
var json = document.getElementById("hCategories").value;
var categories = eval( '(' + json + ')' );
for(curCat in categories) {
curCatKey = categories[curCat]['grKey'];
$.ajax({
type: "POST",
url: "get_results.php",
data: "category=" + escape(curCatKey) +
"&search=" + escape($("#hQuery").val()),
timeout: 8000,
async: false,
success: function(data) {
$("#content").append(data);
}
});
});
I thought it would work with "async:false" but then it waits until every Ajax call is finished and presents the results after the loop. I hope some of you can point out some different solutions, I am pretty much stuck.
Thanks in advance,
Cheers Chris
EDIT: Thanks for all the possible solutions, I will try these now one by one and come back with that one that fits my problem.
I have two solution proposals for this problem:
Populate generated divs
You could generate divs with ids in the loop and populate them when the request finishes:
$(document).ready(function() {
var json = document.getElementById("hCategories").value;
var categories = eval('(' + json + ')');
for (curCat in categories) {
(function(curCat) {
var curCatKey = categories[curCat]['grKey'];
$('#content').append('<div id="category-"' + escape(curCat) + '/>');
$.ajax({
type: "POST",
url: "get_results.php",
data: "category=" + escape(curCatKey) + "&search=" + escape($("#hQuery").val()),
success: function(data) {
$("#category-" + escape(curCat)).html(data);
}
});
})(curCat);
}
});
Or use a deferred
You can store jqXHR objects in an array and use a deferred to call the success functions in order, when all calls have finished.
$(document).ready(function() {
var json = document.getElementById("hCategories").value;
var categories = eval('(' + json + ')');
var requests;
for (curCat in categories) {
var curCatKey = categories[curCat]['grKey'];
requests.push($.ajax({
type: "POST",
url: "get_results.php",
data: "category=" + escape(curCatKey) + "&search=" + escape($("#hQuery").val())
}));
}
$.when.apply(requests).done(function() {
for (i in requests) {
requests[i].success(function(data) {
$("#content").append(data);
});
}
});
});
The first method has the advantage that it populates the containers continuously. I have not tested either of these function, but the logic should work the way I described it.
This would do the trick
var results = [];
var idx = 0;
for(curCat in categories) {
curCatKey = categories[curCat]['grKey'];
(function( i ) {
$.ajax({
type: "POST",
url: "get_results.php",
data: "category=" + escape(curCatKey) +
"&search=" + escape($("#hQuery").val()),
timeout: 8000,
async: false,
success: function(data) {
results[i] = data;
if (i == idx - 1) { // last one
for (var j=0; j < results.length; j++) {
$("#content").append(results[j]);
}
}
}
});
})(idx++);
I think something like this is what you're looking for. Might need some tweaking, I'm a little rusty on Deferred. Read up on it though, mighty powerful
deferred = $.Deferred()
for(curCat in categories) {
deferred.pipe(
function(resp){
postData = {} // set up your data...
return $.post("get_results.php", {data: postData, timeout: 8000})
.done(function(content){ $("#content").append(content) })
})
)
}
// Trigger the whole chain of requests
deferred.resolve()

google maps call within a For Loop not returning distance

I am calling google maps within a for loop in my javascript as I have mulitple routes that need to be costed separately based on distances.
Everything works great except that the distance is only returned for one of the routes.
I have a feeling that it is something to do with the way I have the items declared within the ajax call for the maps. Any ideas what could be the issue from the code below?
for (var i = 1; i <= numJourneys; i++) {
var mapContainer = 'directionsMap' + i;
var directionContainer = $('#getDistance' + i);
$.ajax({
async: false,
type: "POST",
url: "Journey/LoadWayPoints",
data: "{'args': '" + i + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
if (msg.d != '[]') {
var map = new GMap2(document.getElementById(mapContainer));
var distance = directionContainer;
var wp = new Array();
//routes
var counter = 0;
$.each(content, function () {
wp[counter] = new GLatLng(this['Lat'], this['Long']);
counter = counter + 1;
});
map.clearOverlays();
map.setCenter(wp[0], 14);
// load directions
directions = new GDirections(map);
GEvent.addListener(directions, "load", function () {
alert(directions.getDistance());
//directionContainer.html(directions.getDistance().html);
});
directions.loadFromWaypoints(wp, { getSteps: true });
}
}
});
}
The issue was down to a non declared variable. Just before the GEvent call there is a variable called 'directions' but this was never actually declared with a var so it wasn't being cleared out.
var directions = new GDirections(map);
Doing the above worked for me.

Resources