I have a set of cascading-option dropdown boxes that I'm trying to populate via javascript & jquery. In the $(document).ready section I'm trying to implement the jquery .done() function to ensure that each prior function is completed before the next run starts running, but it doesn't seem to be working:
$(document).ready(function () {
$.when(getSchoolYears()).done(function () {
$.when(getDistricts()).done(function () {
$.when(getAreas()).done(function () {
$.when(getSchoolTypes()).done(function () {
$.when(getSchoolLevels()).done(function () {
$.when(getGrades()).done(function () {
$.when(getEvents()).done(function () {
$.when(getResolutions()).done(function () {
$.when(getSchools()).done(function () {
loadCharts();
})
})
})
})
})
})
})
})
})
})
Focusing on the first two functions, getSchoolYears() & getDistricts(), I put consle.log statements into these functions, and the message for getDistricts() gets logged before the message for getSchoolYears()
function getSchoolYears() {
var data = [];
var param = {};
$.ajax({
type: "POST",
contentType: "application/json; charset=UTF-8",
url: "../WebServices/myLocations.asmx/get_SchoolYears",
data: JSON.stringify(param),
dataType: "json",
success: function (msg) {
var data = [];
data.push(msg.d);
$('#ddSchoolYear li').remove();
for (var i = 0; i <= data.length; i++) {
$('#ddSchoolYear').append(data[i]);
}
$('#hidSchoolYear').val(ddSubmitted('#ddSchoolYear input', '#lblYear'));
console.log('finished');
}
});
}
function getDistricts() {
console.log($('#hidSchoolYear').val());
var param = { "endYear": $('#hidSchoolYear').val() };
return $.ajax({
type: "POST",
contentType: "application/json; charset=UTF-8",
url: "../WebServices/myLocations.asmx/get_Districts",
data: JSON.stringify(param),
dataType: "json",
success: function (msg) {
var data = [];
data.push(msg.d);
$('#ddDistrict li').remove();
for (var i = 0; i <= data.length; i++) {
$('#ddDistrict').append(data[i]);
}
}
});
}
Am I not understanding how the .done() function works? Is there a way to ensure that one functions completes before the next one begins?
Related
I'm currently working on a project with javascript and jquery.
I'm using a $.ajax call to ask the server for some data. This call is being made within an object I created.
On success, I want to update the data members of such object with the data recieved. It looks something like so:
function Caller() {
this.data1 = 0;
this.data2 = 1;
this.makeRequest = function () {
$.ajax({
url: "some url",
data: somedata,
dataType: "json",
success: function ( data ) {
// update data
}
});
};
};
For passing the original object (Caller) to the succes function, I've tried the following:
function Caller() {
this.data1 = 0;
this.data2 = 1;
this.makeRequest = function () {
var _this = this;
$.ajax({
url: "some url",
data: somedata,
dataType: "json",
success: function ( data ) {
// update data
_this.data1 = data.data1;
_this.data2 = data.data2;
}
});
};
};
Then I tried:
function Caller() {
this.data1 = 0;
this.data2 = 1;
this.makeRequest = function () {
$.ajax({
url: "some url",
data: somedata,
dataType: "json",
_this: this,
success: function ( data ) {
// update data
var _this = this._this
_this.data1 = data.data1;
_this.data2 = data.data2;
}
});
};
};
And then:
function Caller() {
this.data1 = 0;
this.data2 = 1;
this.makeRequest = function () {
$.ajax({
url: "some url",
data: somedata,
dataType: "json",
context: this,
success: function ( data ) {
// update data
this.data1 = data.data1;
this.data2 = data.data2;
}
});
};
};
In all the cases above, it seems that a copy of the object, rather than the original one, is being pass to the function, so the original values are not
changed.
Is there a way to change the originals values of the object or pass the original one? I hope you can help me, i've stuck with this for a while.
If you send a request to another site, you must do
crossDomain: true
or
If you want to do data return, you must do
async: true
Example:
var data_1 = 0;
ajax success function data_1 = data.data_1
return data_1;
I am trying to use bootstrap typeahead.
I am having trouble handling which item has been selected.
Below is the code I have so for
var bindto = $(".search.typeahead");
bindto.typeahead({
source: function (query, response) {
var map = {};
var advicesearchList = [];
return $.ajax({
url: "/Advice/AutoComplete",
type: "GET",
cache: false,
data: { querystring: query },
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$.each(data, function (i, result) {
map[result.Title] = result;
advicesearchList.push(result.Title);
});
response(advicesearchList);
}
});
}
}).on("typeahead:selected", function (e, o) {
console.log("item selected");
});
What would be the correct way to detect what the user has selected from one of the items in the list
thanks
Try using the afterSelected option:
var bindto = $(".search.typeahead");
bindto.typeahead({
source: function (query, response) {
//your code...
}, afterSelect: function (data) {
//print the data to developer tool's console
console.log(data);
}
});
Docs
I have a simple ajax call which returns a serialised list of strings. This is great and I can get the data back. However I'm simply trying to perform an alert on each item in the list. However, I just keep getting back single characters from the list instead. For example if it returned a list with one item in it called "Hello". It would alert "H", "E", "L" etc. Can someone help me change this so it alerts the full string?
The response received back is very similar to the text above. If the c# variable userList returns a list of strings with just "Andrew" in it. The JQuery will alert "A", "N", "D" etc. If that isn't clear, just let me know.
Thanks
C#
[HttpPost]
public string GetUserList(string Role) {
List<string> UserList = new List<string>();
UserList = Roles.GetUsersInRole(Role).ToList();
return JsonConvert.SerializeObject(UserList);
}
JQuery
$('#allRolesDD').change(function () {
$.ajax({
method: "POST",
url: "./GetUserList",
data: { Role: $(this).val() }
})
.done(function (data) {
$('.roleDD').empty();
for (i = 0; i < data.length; i++) {
alert(data[i]);
}
console.log("Passed 4");
})
.fail(function () {
console.log("Failed 4");
})
});
you can change c# code and jquery like below:
C#
[HttpPost]
public JsonResult GetUserList(string Role) {
List<string> UserList = new List<string>();
UserList = Roles.GetUsersInRole(Role).ToList();
return Json(UserList, JsonRequestBehavior.AllowGet);
}
JQuery
$('#allRolesDD').change(function () {
$.ajax({
method: "POST",
url: "./GetUserList",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: { Role: $(this).val() }
})
.done(function (data) {
$('.roleDD').empty();
for (i = 0; i < data.length; i++) {
alert(data[i]);
}
console.log("Passed 4");
})
.fail(function () {
console.log("Failed 4");
})
});
Try jquery each:
$.ajax({
method: "POST",
url: "./GetUserList",
data: { Role: $(this).val() },
success:function (data) {
$.each(data,function(i,v){
console.log(v);
});
}
});
Why don't you return the list as it is instead of a string, the web API will automaticly convert it to json and you can read it as an array in your request?
You just have to add
$('#allRolesDD').change(function () {
$.ajax({
method: "POST",
url: "./GetUserList",
data: { Role: $(this).val() },
headers: {
'Content-Type': 'application/json'
}
})
.done(function (data) {
$('.roleDD').empty();
for (i = 0; i < data.length; i++) {
alert(data[i]);
}
console.log("Passed 4");
})
.fail(function () {
console.log("Failed 4");
})
});
You need to add dataType: "json" into the ajax call because it doesn't know that your response is a json. It assumes that it is a string.
$("#allRolesDD").change(function () {
$.ajax({
method: "POST",
url: "./GetUserList",
data: { Role: $(this).val() },
dataType: "json"
})
.done(function (data) {
$('.roleDD').empty();
$.each(data, function (i, v) {
alert(v);
});
// or you could also iterate using for
//for (i = 0; i < data.length; i++) {
// alert(data[i]);
//}
console.log("Passed");
})
.fail(function () {
console.log("Failed");
})
});
I am loading 2 XML documents that both run functions on success, although the function for the 2nd XML document is dependant on the 1st being complete.
If I have async:true:
1st XML
function XmlDataTypes() {
var result = null;
var scriptUrl = "http://domain.com/xml/test.XmlDataTypes?AccountId=" + AccountId;
$.ajax(
{
url: scriptUrl,
type: 'get',
dataType: 'xml',
async: true,
success: function (data) {
//create array to be used in second XML
for (var i = 0; i < xmlRows.length; i++) {
var dataType = xmlRows[i];
var dataTypeId = nodeValue(dataType.getElementsByTagName("DataTypeId")[0]);
var dataTypeName = nodeValue(dataType.getElementsByTagName("DataTypeName")[0]);
dataTypeArray.push({ dataTypeId: dataTypeId, dataTypeName: dataTypeName, position: i, markerArray: [] });
}
},
error: function onXmlError() {
alert("An Error has occurred.");
}
});
return result;
}
2nd XML
function XmlAmenityData() {
var result = null;
var scriptUrl = "http://domain.com/xml/test.XmlAmenityData?AccountId=" + AccountId;
$.ajax(
{
url: scriptUrl,
type: 'get',
dataType: 'xml',
async: true,
success: function (data) {
//store this info in markerArray in dataTypeArray
},
error: function onXmlError() {
alert("An Error has occurred.");
}
});
return result;
}
The XML data can loaded in a random order so the function for the second document will error if the 1st hasn't completed.
If I set:
async: false
It works correctly but I get a warning:
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.
Is there a way around this without using:
async: false
Since the 2nd xml is dependent on the 1st, you can define a callback on success.
Also since ajax is async, you must assign the result when the callback is called. You can define a variable ourside of your function (in this case an array) and put the data there.
var result = [];
function XmlDataTypes(url, accountId, callback) {
var scriptUrl = url + accountId;
$.ajax({
url: scriptUrl,
type: 'get',
dataType: 'xml',
async: true,
success: function (data) {
// do something
result.push(data);
if(typeof callback == 'function') {
callback();
}
},
error: function onXmlError() {
alert("An Error has occurred.");
}
});
}
function doSomething() {
// Do something to store this info in markerArray in dataTypeArray
// XmlAmenityData is in results var.
}
And you can use it like so
var _callback = XmlDataTypes("http://domain.com/xml/test.XmlAmenityData?AccountId=", "1234", doSomething);
XmlDataTypes("http://domain.com/xml/test.XmlDataTypes?AccountId=", "1234", _callback);
EDIT: Updated script based on given scenario.
You could try to return the $.ajax as a promise:
function XmlDataTypes() {
// note domain.com was changes to example.com - this should be changed back
var scriptUrl = "http://example.com/xml/test.XmlDataTypes?AccountId=" + AccountId;
return $.ajax(
{
url: scriptUrl,
type: 'get',
dataType: 'xml',
async: true,
success: function (data) {
//create array to be used in second XML
for (var i = 0; i < xmlRows.length; i++) {
var dataType = xmlRows[i];
var dataTypeId = nodeValue(dataType.getElementsByTagName("DataTypeId")[0]);
var dataTypeName = nodeValue(dataType.getElementsByTagName("DataTypeName")[0]);
dataTypeArray.push({ dataTypeId: dataTypeId, dataTypeName: dataTypeName, position: i, markerArray: [] });
}
},
error: function onXmlError() {
alert("An Error has occurred.");
}
});
}
Then calling them in sequence :
XmlDataTypes.done(XmlAmenityData);
Here is some more documentation :
http://www.htmlgoodies.com/beyond/javascript/making-promises-with-jquery-deferred.html
I want to compare a set of days in an array with all the dates in the calendar.
This is my code what I have written. How should I pass the array to dayrender function?
Method for getting the dates
function GetFoodDetails() {
$.ajax({
url: 'Food/getFoodDetails',
data: {},
dataType: 'json',
contentType: "application/json; charset=utf-8",
type: 'GET',
success: function (result) {
myArray = new Array(result.length);
for (var index = 0; index < result.length; index++) {
debugger;
// myArray[index] = Date(result[index].Date.split('(')[1].split(')')[0].toString());
var date = new Date(parseInt(result[index].Date.substr(6)));
myArray[index] = date;
} //end of loop
},
error: function (response) {
alert('eror');
console.log(response);
}
});
}
in Fullcalendar plugin
dayRender: function (date, cell) {
myArray.forEach(function (item) {
if (date._d.getDate() == item.getDate() && date._d.getMonth() == item.getMonth())
{
$(cell).toggleClass('selected');
}
});
}
Well, jquery Data Method can help you here:
Add, $('body').data( "date_global", myArray); to store your date array.
You can try this technique like:
function GetFoodDetails() {
$.ajax({
url: 'Food/getFoodDetails',
data: {},
dataType: 'json',
contentType: "application/json; charset=utf-8",
type: 'GET',
success: function (result) {
myArray = new Array(result.length);
for (var index = 0; index < result.length; index++) {
debugger;
// myArray[index] = Date(result[index].Date.split('(')[1].split(')')[0].toString());
var date = new Date(parseInt(result[index].Date.substr(6)));
myArray[index] = date;
} //end of loop
$('body').data( "date_global", myArray);
},
error: function (response) {
alert('eror');
console.log(response);
}
});
}
For, fetching this array anywhere in the code write: $('body').data( "date_global" )
dayRender: function (date, cell) {
console.log($('body').data( "date_global" ));
myArray.forEach(function (item) {
if (date._d.getDate() == item.getDate() && date._d.getMonth() == item.getMonth())
{
$(cell).toggleClass('selected');
}
});
}