DOM timing or wrong code? - javascript

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

Related

Adding to JSON array by HTML button

I have an AJAX call, as below. This posts data from a form to JSON. I then take the values and put them back into the div called response so as to not refresh the page.
$("form").on("submit", function(event) { $targetElement = $('#response'); event.preventDefault(); // Perform ajax call // console.log("Sending data: " + $(this).serialize()); $.ajax({
url: '/OAH',
data: $('form').serialize(),
datatype: 'json',
type: 'POST',
success: function(response) {
// Success handler
var TableTing = response["table"];
$("#RearPillarNS").empty();
$("#RearPillarNS").append("Rear Pillar Assembly Part No: " + response["RearPillarNS"]);
$("#TableThing").empty();
$("#TableThing").append(TableTing);
for (key in response) {
if (key == 'myList') {
// Add the new elements from 'myList' to the form
$targetElement.empty();
select = $('<select id="mySelect" class="form-control" onchange="myFunction()"></select>');
response[key].forEach(function(item) {
select.append($('<option>').text(item));
});
$targetElement.html(select);
} else {
// Update existing controls to those of the response.
$(':input[name="' + key + '"]').val(response[key]);
}
}
return myFunction()
// End handler
}
// Proceed with normal submission or new ajax call }) });
This generates a new <select id="mySelect">
I need to now extract the value that has been selected by the newly generated select and amend my JSON array. Again, without refreshing the page.
I was thinking of doing this via a button called CreateDrawing
The JS function for this would be:
> $(function() {
$('a#CreateDrawing').bind('click', function() {
$.getJSON('/Printit',
function(data) {
//do nothing
});
return false;
});
});
This is because I will be using the data from the JSON array in a Python function, via Flask that'll be using the value from the select.
My question is, what is the best way (if someone could do a working example too that'd help me A LOT) to get the value from the select as above, and bring into Python Flask/JSON.

how to execute a specific code after a ajax

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
}

Why does the dropdown displays options one by one on first click when using append()

$(document).on('focus', '.resource_person', function() {
var topic_code = $(this).attr('id');
var rp_reference = $(this).attr('selected-rp');
var option = '';
$.ajax({
type: 'POST',
url: siteUrl + 'course_management/Training_courses/topic_rp',
data: {topic_code: topic_code},
dataType: 'json',
success: function(source) {
$('.resource_person[id="'+topic_code+'"]').empty();
for (var key in source) {
if (source[key] != rp_reference) {
option += '<option value="'+source[key]+'">'+key+'</option>';
} else {
option += '<option value="'+source[key]+'" selected="">'+key+'</option>';
}
}
console.log(option);
$('.resource_person[id="'+topic_code+'"]').append(option);
}
});
});
This what was happening when I first click the dropdown
After clicking it for the second time it goes back to the normal behavior of dropdown
On first click it makes request causing delay to show items, but it uses cahce on second request.
If you force request not to use cache, same delay will happen every time:
$.ajax({
cache: false,
//other options...
});
Note: Setting cache to false will only work correctly with HEAD and
GET requests.

Javascript loop with ajax call

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

jQuery Ajax placing random "jQuery111201xxx" into string

I have made a booking system that utilizes FullCalendar; though that part should be irrelevant. My problem is that upon saving an appointment, a 'notes' field I have created very occasionally has this strange string inserted into it, generally at a random point in the string. Here is the latest example:
Has this been changedjQuery1112010047650896012783_1444929292744 with Rich- finishing sleeve off.bringing deposit in on saturday. told him space isnt secure.
As you can see, there is a totally out of place "jQuery1112010047650896012783_1444929292744" placed in the middle of the note. I can't find anything about this online (mainly because I have no idea what terms I'd use to find it). It must be related to jQuery, considering the string.
I am using jQuery v1.11.2 - obviously the string looks like a long version number.
Why is my ajax request seemingly succeeding, but placing this message in the middle of the sent string? I cannot replicate this issue at all, especially this time since it was another user who managed to cause it.
The function that fetches/prepares/sends data looks like this:
function postForm(content, action, update) {
loader('show');
var popup = content.parent();
var children = content.find(".input");
var data = {}
var elements = [];
data['elements'];
$( children ).each(function() {
var child = {};
child['name'] = $(this).attr('data-name');
if ($(this).is(':checkbox')) {
child['value'] = $(this).is(":checked");
} else {
child['value'] = $(this).val();
}
elements.push(child);
});
data.elements = elements;
data.request = action;
dataPost = JSON.stringify(data);
console.log(dataPost);
ajaxRequest = $.ajax({
type: "POST",
url: "/?page=ajax",
data: dataPost,
dataType: 'json',
success: function(response) {
loader('hide');
console.log(response);
if (update) {
$(update.element).load(update.url+" "+update.element+" > *");
checkError = doExtra(response, update.extra);
}
if (checkError == false) {
popup.fadeOut();
}
}
});
return false;
}
The note section is just a textarea with the class 'input' (which is looped through and fetched).
I don't think there will be a solution for the exact problem, however, I'm looking for an explanation for the modification of the string. The application works perfectly, except for this very rare case.
Question marks (??) are replaced with a jQuery time stamp. To fix, I had to add jsonp: false to the parameters. Final ajax:
ajaxRequest = $.ajax({
type: "POST",
url: "/?page=ajax",
data: dataPost,
dataType: 'json',
jsonp: false,
success: function(response) {
loader('hide');
console.log(response);
if (update) {
$(update.element).load(update.url+" "+update.element+" > *");
checkError = doExtra(response, update.extra);
}
if (checkError == false) {
popup.fadeOut();
}
}
});

Categories