I've been struggling all afternoon to understand how to make this work, hopefully someone can help. I have a simple requirement to run through a list of checked check boxes, retrieve some data from the server, fill an element with the data expand it. So far I have the following code;
function opentickedrows() {
$('input[type=checkbox]').each(function () {
if (this.checked) {
tid = $(this).attr('name').replace("t_", "");
$.ajax({
url: '/transfer_list_details_pull.php?id=' + tid,
type: 'GET',
success: function (data) {
$('#r' + tid).html(data);
$("#r" + tid).show();
$("#box" + tid).addClass("row-details-open");
}
});
}
});
}
The problem that I am having is that the ajax calls all seem to happen so fast that 'tid' isn't being updated in the ajax call. From what I have read I believe I need to wrap this up into a couple of functions with a callback but I just can not get my head around how. I'd be really grateful if someone can set me on the right path.
Ajax calls are asynchronous, so when the success callback is invoked, tid has the value of the last item of the $('input[type=checkbox]').
You could use a closure:
function opentickedrows() {
$('input[type=checkbox]').each(function () {
if (this.checked) {
tid = $(this).attr('name').replace("t_", "");
(function(tid) {
$.ajax({
url: '/transfer_list_details_pull.php?id=' + tid,
type: 'GET',
success: function (data) {
$('#r' + tid).html(data);
$("#r" + tid).show();
$("#box" + tid).addClass("row-details-open");
}
});
})(tid)
}
});
}
Related
I have a function in which uses ajax which populate a select element of options from my database, here is the code of the function.
function Filtering_GetRole(roleElement) {
$.ajax({
type: "POST",
url: "IROA_StoredProcedures.asmx/Filtering_GetRole",
data: "",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var roletooldetails = response.d;
var appendItem = "";
$(roleElement).empty();
$.each(roletooldetails, function (index, Filtering_GetRoleInfo) {
var activeappend = "";
var id = Filtering_GetRoleInfo.id;
var role = Filtering_GetRoleInfo.Role;
activeappend = "<option value=" + id + ">" + role + "</option>";
appendItem += activeappend;
});
$(roleElement).prepend('<option disabled="disabled" selected="selected" value="">Select Tool</option>')
$(roleElement).append(appendItem);
},
error: function (XMLHttpRequest) {
console.log(XMLHttpRequest);
alert("error in Filtering_GetTool");
}
});
}
which I call like this
var slcRole = $(this).closest(".td-span-buttons").closest(".tr-span-buttons").find(".slc-role"); var holdRoleId = slcRole.val();
Filtering_GetRole(slcRole);
slcRole.val(holdRoleId);
but the problem is since I use ajax the code slcRole.val(holdRoleId); will execute first resulting to the value not selected on the option element. How can I do that when the ajax code finished this code will execute. Sorry for the bad english
The another way to make sure your ajax request has been processed is to use jQuery.when(), but the best way is to put slcRole.val(holdRoleId) into success callback.
Just put slcRole.val(holdRoleId); into success.
Else, js will execute without waiting ajax done.
I think you need to execute this after success or error so instead putting in any callback or after your Filtering_GetRole put it in the complete callback of ajax have a look here. It will execute code within complete block when ajax is complete. Hope this will help.
You can use complete function. complete executes only after the "success" of ajax. Following code will be helpful to you.
success: function (response) {
// Your code
},
complete: function (response) {
slcRole.val(holdRoleId);
},
error: function (XMLHttpRequest) {
// Your code
}
I have a function where onclick a button will get all the id of selected task from a gantt chart and run a for loop to save each of the selected task i edited in a form using AJAX request.
The problem now on AJAX request success I add a code to clear and load all the data again in the gantt chart but it doesn't goes as intended, load the data several times and start creating duplicate of the same data in my gantt, I tried to execute the gantt.load function outside of the loop and it still not working.
So how can I create a condition where I reload the gantt AFTER the loop is finish executed? Any help is much appreciated thanks.
Below is my code :
HTML
<button type="button" class="btn btn-primary" onclick="editForm()">Edit</button>
javascript
function editForm() {
var selected_task = gantt.getSelectedTasks();
for (var i = 0; i < selected_task.length; i++) {
var task = selected_task[i];
var data = gantt.getTask(task);
$.ajax({
type: 'PUT',
url: '/api/dashboard/workorder_detail/' + data.workorder_id + '/',
data: postData,
success: function () {
$('#edit_form_modal').modal('hide');
gantt.clearAll();
gantt.load("/api/scheduler/{{ selected_project.id }}/?format=json", "json");
},
error: function (err) {
alert("Failed because of " + err);
}
})
}
}
Map selected tasks to a list of promises and use jQuery when to load the gantt after all the promises have resolved.
function editForm() {
var selected_task = gantt.getSelectedTasks();
var saveSelectedTask = selected_task.map(function(task, i) {
var data = gantt.getTask(task);
return $.ajax({
type: 'PUT',
url: '/api/dashboard/workorder_detail/' + data.workorder_id + '/',
data: postData,
});
});
$.when(saveSelectedTask)
.done(function() {
$('#edit_form_modal').modal('hide');
gantt.clearAll();
gantt.load("/api/scheduler/{{ selected_project.id }}/?format=json", "json");
})
.fail(function(err) {
alert("Failed because of " + err);
});
}
in this case, you should use Promise, exactly is Promise.all (I suggest you go to these URLs to learn more about Promise before implement.
The idea is letting the request run parallel, then wait for all finish and do your callback.
I will rewrite your JS to:
function editForm() {
var selected_task = gantt.getSelectedTasks();
Promise.all(selected_task.map(function(task) {
var data = gantt.getTask(task);
return $.ajax({
type: 'PUT',
url: '/api/dashboard/workorder_detail/' + data.workorder_id + '/',
data: postData,
})
}).then(function(results) {
$('#edit_form_modal').modal('hide');
gantt.clearAll();
gantt.load("/api/scheduler/{{ selected_project.id }}/?format=json", "json");
})
}
update: if you'd prefer to use jQuery function, then you can use $.when()
function editForm() {
var selected_task = gantt.getSelectedTasks();
$.when(selected_task.map(function(task) {
var data = gantt.getTask(task);
return $.ajax({
type: 'PUT',
url: '/api/dashboard/workorder_detail/' + data.workorder_id + '/',
data: postData,
})
}).then(function(results) {
$('#edit_form_modal').modal('hide');
gantt.clearAll();
gantt.load("/api/scheduler/{{ selected_project.id }}/?format=json", "json");
})
}
but as I said above, solve the problem doesn't make you better, should dig deep into it and learn how functions works.
I know there are many question like this but i didn't found a proper solution for me.
I am calling API using ajax so my problem is my web page gets unresponsive so some where I have found that this is just because of the improper ajax handling can you please help to know where do I put my ajax.I need ajax to be called on the load of the page.
I have tried calling ajax without any function like..
show('ajax Call start for player');
$('#loading').show();
$.ajax({
url: '/home/getPlayers',
success: function (data) {
data = JSON.parse(data);
playerData = data.Data;
show('data of player');
// show(playerData);
showPlayers(1);
show('ajax Call complete for player');
flag = 1;
}
});
show('ajax Call start for loadplayeronpitch');
$.ajax({
url: '/home/checkUserTeam',
success: function (data) {
while (true) {
if (flag) {
loadUserTeampitch(data);
break;
}
}
show('ajax Call complete for loadplayeronpitch');
}
});
This is not working which cause the unresponsive page.
then from other questions I have tried calling the ajax in following functions
$(document).load(function(){
});
$(function(){
});
$(document).bind("load", function () {
});
but this all are also not working properly can you help me for this?
Thank you.
The unresponsiveness is caused by your while(true) loop, so never ever do this again :-)
What you want to do is: Run the second ajax call only after the first one finishes. So you should put both ajax calls into separate functions, then call the first function on page load.
In the success part of the first ajax (inside the first function), call the second function. Done.
function firstAjax() {
$.ajax({
url: '/home/getPlayers',
success: function (data) {
data = JSON.parse(data);
playerData = data.Data;
show('data of player');
//show(playerData);
showPlayers(1);
show('ajax Call complete for player');
secondAjax();
}
});
}
function secondAjax() {
$.ajax({
url: '/home/checkUserTeam',
success: function (data) {
loadUserTeampitch(data);
}
});
}
$(function() {
firstAjax();
});
This should work like you want to, but I can't test it right now.
$('#loading').show();
var deferedA = $.ajax({
url: '/home/getPlayers',
success: function (data) {
data = JSON.parse(data);
playerData = data.Data;
show('data of player');
// show(playerData);
showPlayers(1);
show('ajax Call complete for player');
}
});
show('ajax Call start for loadplayeronpitch');
var deferedB = $.ajax({
url: '/home/checkUserTeam'
});
//wait until both request are finished
$.when(deferedA, deferedB)
.done( function (dataA, dataB) {
loadUserTeampitch(dataB);
show('ajax Call complete for loadplayeronpitch');
});
EDIT I would suggest to use Promise instead $.when (the Promise like implementation of jQuery is a bit strange), but the problem with Promise is that it is only available with the newer browser, for older one you need a library like bluebird or when
EDIT : If you want to go simple than you can use below approach..
<script type="text/javascript">
$(function() {
var flag = 0;
var data1;
$('#loading').show();
$.ajax({
beforeSend: function() {
show('ajax Call start for player');
},
url: '/home/getPlayers',
success: function(data) {
flag++;
data = JSON.parse(data);
playerData = data.Data;
show('data of player');
showPlayers(1);
show('ajax Call complete for player');
checkFlag();
}
});
$.ajax({
beforeSend: function() {
show('ajax Call start for loadplayeronpitch');
},
url: '/home/checkUserTeam',
success: function(data) {
flag++;
data1 = data;
show('ajax Call complete for loadplayeronpitch');
checkFlag();
}
});
function checkFlag()
{
if (parseInt(flag) == parseInt(2))
{
loadUserTeampitch(data1);
}
}
});
</script>
I've got two multi select list boxes, the first one allows someone to select a team.
The second one shows the members related to the team. When the first list box (the team) is selected I make an ajax call to fill the members of that team. I'm also using the chosen library. This is all working fine however, I needed a way to remove the x from the listbox selected value so that users don't think they can remove a member from the team.
$("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");
The above code works when I throw that in a console window, but if I have it in my if condition it doesnt seem to work:
$("#MainContent_lbTeams").on('change', function() {
//was a value selected?
var latest_value = $("option:selected:last", this).val();
var latest_text = $("option:selected:last", this).text();
if ($("#MainContent_lbTeams :selected").length > 0) {
$("#dTeamNotice").show();
$("#MainContent_lblTeamMembers").text("Members of '" + latest_text + "':");
PopulateMembers(latest_value);
$("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");
$("#trMembers").fadeIn();
} else {
//hide it...
$("#dTeamNotice").css("display", "none");
$("#trMembers").hide();
}
});
Basically the change event grabs the most recently selected text and value. If the length of what is selected > 0 I load the members of my team with PopulateMembers:
function PopulateMembers(buCompanyTeamID) {
$('#<%=lbMembers.ClientID %>').empty().append('<option selected="selected" value="0">Loading...</option>');
$("#<%=lbMembers.ClientID %>").trigger("chosen:updated");
$.ajax({
type: "POST",
url: "/Code/WebServices/Utilities.asmx/GetTeamMembers",
data: '{buCompanyTeamID: ' + buCompanyTeamID + '}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnMembersPopulated,
failure: function (response) {
alert(response.d);
}
});
}
function OnMembersPopulated(response) {
PopulateControl(response.d, $("#<%=lbMembers.ClientID %>"), true);
}
function PopulateControl(list, control, selected) {
if (list.length > 0) {
control.removeAttr("disabled");
control.empty().append('<option selected="selected" value="0"></option>');
$.each(list, function () {
if(selected)
control.append($("<option selected></option>").val(this['Value']).html(this['Text']));
else
control.append($("<option></option>").val(this['Value']).html(this['Text']));
});
}
else {
control.empty().append('<option selected="selected" value="0"><option>');
}
control.trigger("chosen:updated");
}
But I cannot understand why in a console window I can do this:
$("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");
And it removes the x from the chosen selected value so that a user cannot remove an item, but within the if condition this doesnt have any effect.
I even tried disabling like so:
$("#MainContent_lbMembers").attr('disabled', true).trigger("chosen:updated");
This only works in a console as well, is it some timing issue or something else?
PopulateMembers() contains an asynchronous Ajax call. So, if you are expecting:
PopulateMembers(latest_value);
$("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");
to operate on the results of the ajax call in PopulateMembers(), then you do indeed have a timing problem. The Ajax call will complete some time in the future, long after PopulateMembers() has finished and long after you've executed the .removeClass() statement.
To operate on the results of PopulateMembers(), you have to either put your code in the success handler of that ajax call or restructure your code so that PopulateMembers() will call a callback when it's done and you can do the .removeClass() in that callback.
I would suggest using promises like this:
// return the ajax promise from PopulateMembers
function PopulateMembers(buCompanyTeamID) {
$('#<%=lbMembers.ClientID %>').empty().append('<option selected="selected" value="0">Loading...</option>');
$("#<%=lbMembers.ClientID %>").trigger("chosen:updated");
return $.ajax({
type: "POST",
url: "/Code/WebServices/Utilities.asmx/GetTeamMembers",
data: '{buCompanyTeamID: ' + buCompanyTeamID + '}',
contentType: "application/json; charset=utf-8",
dataType: "json"
}).then(onMembersPopulated, function (response) {
alert(response.d);
});
}
$("#MainContent_lbTeams").on('change', function() {
//was a value selected?
var latest_value = $("option:selected:last", this).val();
var latest_text = $("option:selected:last", this).text();
if ($("#MainContent_lbTeams :selected").length > 0) {
$("#dTeamNotice").show();
$("#MainContent_lblTeamMembers").text("Members of '" + latest_text + "':");
// act only when the returned promise is resolved
PopulateMembers(latest_value).then(function() {
$("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");
$("#trMembers").fadeIn();
});
} else {
//hide it...
$("#dTeamNotice").css("display", "none");
$("#trMembers").hide();
}
});
I'm trying to work on a script, that makes ajax request to pull more feeds from the server. Somewhat like pagination.
The problem here is SiteHelper.loadMoreFeeds() function is called once when a "More" link is clicked. But the function's code executes twice. Can't figure out why this is happening.
There's no loop nor recursive calls.
I've tried "alerting" in some points, to verify that function is called only once; which is true but it's code is executed twice.
Thanks in advance
//SiteHelper = {....} has lots of code already
SiteHelper.loadMoreFeeds = function (loaderUri, limit) {
$(".feeds-loadmore .more").hide();
$('.feeds-loadmore').find('.loading-anim').fadeIn();
alert('loadMoreFeeds called');
$.ajax({
type: "GET",
url: SiteHelper.baseUrl(loaderUri),
data: { 'limit': limit },
cache: false,
success: function(result) {
$('.feeds-loadmore').remove();
$("#content").append('<!-- [data] : ' + JSON.stringify(limit) + ' -->');
$("#content").append(result);
$("#content").append('<!-- //[data] -->');
alert('ajax success');
}
});
};
$(function() {
$('#content').on('click', '.feeds-loadmore a.more', function(e) {
var loaderUri = decodeURIComponent( $(this).attr('data-loader') );
var limitData = $(this).attr('data-limit');
if(!loaderUri)
return;
alert('clicked');
SiteHelper.loadMoreFeeds( loaderUri, JSON.parse(limitData) );
e.preventDefault();
})
});