Data available only after alert [duplicate] - javascript

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
jQuery: Return data after ajax call success
I wrote a script which adds a new div container to the said with the a select field inside. The data for the select field is loaded with an ajax request before. But for some reason the fields are only visible when I output something with alert().
var o = '';
$.ajax({
type: 'post',
dataType: 'json',
url: webroot + 'items',
success: function(data) {
$.each(data, function(index, value) {
o += '<option value="' + index + '">' + value + '</option>';
});
}
});
var l = parseInt($('.items .item').length);
var h = '<div class="item"><span class="bold">Item ' + (l + 1) + '</span><select id="ItemName" name="data[Item][name]">' + o + '</select></div>';
I have actually no idea how to solve this problem. Can you help me?

Ajax is asynchronous. Move all of your code into the success function, and it will work. The reason it works with alert is because the alert allows some time to get the AJAX result.
$.ajax({
type: 'post',
dataType: 'json',
url: webroot + 'items',
success: function(data) {
var o = '';
$.each(data, function(index, value) {
o += '<option value="' + index + '">' + value + '</option>';
});
var l = parseInt($('.items .item').length);
var h = '<div class="item"><span class="bold">Item ' + (l + 1) + '</span><select id="ItemName" name="data[Item][name]">' + o + '</select></div>';
}
});
Your code doesn't actually do anything other than load some html into a variable though. So whatever you were doing with "h", do it in the success function.

Related

Add custom object as option inside dropdownlist

I'm having some kind of a bad time where i need to append some json objects as selectlistitems inside a dropdownlist that is different from where i display these json objects.
I managed to retrieve all data, but i dont know how to translate all the information from one kind of element to another. Currently i set up something like this:
All objects that come from my JsonResult method in controller comes like this:
Jsonresult
and the current format for my dropdownlist is as follows:
Dropdownlist selection from controller
For right now I have come to the current state:
i created an array that stores all my objects and convert them to tags, but as i went debugging my array looks like this:
Array from ajax as option tags
My Ajax Request is working as follows:
function GetContratosFiltro() {
$("#id_contrato_aplicativo").empty();
$("#ckSelecionarTdsContratosFiltro").removeAttr("disabled");
var array_sistema = $('#id_sistema').val();
var array_build = $('#id_build_verus').val();
$.ajax({
type: "POST",
url: '#Url.Action("GetContratosFiltros")',
dataType: "json",
//data: "{ 'id_sistema': '" + array_sistema + "'," + "'id_build_verus': '" + array_build + "'}",
data: JSON.stringify({ id_sistema: array_sistema || null, id_build_verus: array_build || null }),
contentType: "application/json; charset=utf-8",
success: function (contratos) {
console.log(JSON.stringify(contratos));
var formoption = [];
content = contratos;
$.each(contratos, function (index, element) {
console.log(element);
var xx = $('<div class="checkbox">' +
'<input value="' + element.id_contrato + '" type="checkbox" name="' + element.contrato + '" class="form-check-input" id="' + index + '" checked>' +
'<label class="form-check-label" for="' + index + '">' + element.contrato + '</label>' +
'</div >');
$('#id_contrato_aplicativo').append(xx);
for (var i = 0; i < contratos.length; i++) {
formoption[index] = " < option value = '" + element.id_contrato + "' id='" + element.id_contrato + "' > " + element.contrato + "</option >";
}
});
array = formoption;
$("#ckSelecionarTdsContratosFiltro").prop('checked', true);
console.log('formoption: ' + formoption);
console.log('array: ' + array);
console.log(content);
},
error: function (ex) {
//alert('Failed to retrieve states.' + ex);
}
});
}
My output on the filter modal is, for example:
Modal filter
On this code: id_contrato_aplicativo is a div where i store all the results from jsonresult query and displays them as checkboxes divs with input and labels, by this bootstrap documentation Checkboxes. My HTML consists into a modal with the filter options with two fields that send information to controller and the main dropdown just gets all information from regular query in controller, but i'm using a custom class called select2 which create the layout for my application and generate the multiselect dropdownlist as a element with each new showing as a block inside dropdown selection, like the image below:
Dropdown result
This code is where i generate all tags for each item from ajax call and below is the function that i am testing right now.
for (var i = 0; i < contratos.length; i++) {
formoption[index] = " < option value = '" + element.id_contrato + "' id='" + element.id_contrato + "' > " + element.contrato + "</option >";
}
$('#btnTransf').click(function () {
console.log('clicou no botão!')
for (var i = 0; i < array.length; i++) {
array[i].appendTo('#id_contrato select');
$('#id_contrato').select();
//appends to select if parent div has id dropdown
//return !$("#id_contrato_aplicativo :checked").remove().appendTo('#id_contrato');
}
//return !$("#id_contrato_aplicativo :checked").remove().appendTo('#id_contrato');
});
UPDATE:
i have managed to locate the correct element and turn out that i only need to pass all elements already formated array variable with all elements as tags inside id_contrato element.
Removed useless info
I've managed to get it to work by making an event bind on a button that gets each element of my array of already formatted objects and with its ids as values from tags.
Array Structure example ( from ajax call):
array = []; //external variable
//put this susccess inside your call from ajax, considering a JsonResult as your controller method
success: function (contratos) {
console.log(JSON.stringify(contratos));
var formoption = [];
content = contratos;
$.each(contratos, function (index, element) {
console.log(element);
var xx = $('<div class="checkbox">' +
'<input value="' + element.id_contrato + '" type="checkbox" name="' + element.contrato + '" class="form-check-input" id="' + index + '" checked>' +
'<label class="form-check-label" for="' + index + '">' + element.contrato + '</label>' +
'</div >');
$('#id_contrato_aplicativo').append(xx);
for (var i = 0; i < contratos.length; i++) {
formoption[index] = " <option value='" + element.id_contrato + "'selected> " + element.contrato + "</option>";
}
});
array = formoption;
$("#ckSelecionarTdsContratosFiltro").prop('checked', true);
console.log('formoption: ' + formoption);
console.log('array: ' + array);
console.log(content);
}
Code:
$('#btnTransf').click(function () {
console.log('test to check if click successful!')
$.each(array, function (index, element) {
console.log(element);
$('#id_contrato').append(element);
$('#id_contrato').select();
});
});

AJAX request time over

I did ajax get request on php file that takes temperature data via snmp and give back a json array of data.
Now for every location I'm trying to generate only once the divs and then only update the values.
Treid to do on the first ajax request to generate the divs with the values inside already to an array and then display them but they won't display in the specific div.
I can see in the console that the array is properly populated. But I can't make it display all the elements in the div with id=data. Tried html(), append(), text() and nothing works.
How should I modify the code so the request won't take that much time?
I'm thinking of creating containers for every location temperature once with the first ajax request and then using setIntervals only getting the value and updating it so I guess it won't take that much time on the request and I will avoid page flickering cause only the numbers will change but how can I achieve that?
I don't want to reload the page.
$(document).ready(function(){
var tr_str = [];
var menu_list = [];
$.ajax({
url: 'getData.php',
type: 'get',
dataType: 'JSON',
success: function(response){
var len = response.length;
for(var i=0; i<len; i++){
var location = response[i].location;
var temp_int = response[i].temp_int;
var temp = response[i].temp;
var hum = response[i].hum;
var dew = response[i].dew;
tr_str[i] = "<div id='locc" + i + "' class='location'>" +
"<span class='title'>" + location + "</span>" +
"<div class='temp'" + i + "><span>Temperatura: </span><span id='check'>" + temp + " &degC</span></div>" +
"<div><span>Względna wilgotność: </span><span>" + hum + " %RH</span></div>" +
"<div><span>Punkt rosy: </span><span>" + dew + " &degC</span></div>" +
"</div>";
menu_list[i] = "<label for='loc" + i + "'>" +
"<input type='checkbox' id='loc" + i + "' />" +
"<span class='css-checkbox'></span>" +
"<p>" + location + "</p>" +
"</label>";
}
},
});
console.log(tr_str);
console.log(menu_list);
$("#data").html(tr_str[0]);
<!-- language: lang-html -->
<body>
<div id="data" class="wrapper"></div>
</body>

why i don't get return value javascript

When i debug my code i can see i have value but i don't get value to createCheckBoxPlatform FN
function createCheckBoxPlatform(data) {
var platform = "";
$.each(data, function (i, item) {
platform += '<label><input type="checkbox" name="' + item.PlatformName + ' value="' + item.PlatformSK + '">' + item.PlatformName + '</label>' + getOS();
});
$('#platform').append((platform));
}
function getOS() {
$.ajax({
url: "/QRCNew/GetOS",
type: "post",
dataType: "Json",
success: function (data) {
var os = '<div>';
$.each(data, function (i, item) {
os += '<label><input type="checkbox" name="' + item.OperatingSystemName + ' value="' + item.OperatingSystemSK + '">' + item.OperatingSystemName + '</label> ';
});
os += '</div>';
return os;
}
});
}
I think you have to turn around your logic. The createCheckBoxPlatform loop will have completed before the getOS() ajax call returns, unless it's a synchronous call.
You could split the functions into pieces, gather the getOS data for each data point you have, then construct the checkboxes when your ajax call returns.
You can make your ajax call async and have to make no changes to your current logic. But your execution will stop till you don't get the callback to your ajax call.
function getOS() {
$.ajax({
url: "/QRCNew/GetOS",
type: "post",
dataType: "Json",
async: true,
success: function (data) {
var os = '<div>';
$.each(data, function (i, item) {
os += '<label><input type="checkbox" name="' + item.OperatingSystemName + ' value="' + item.OperatingSystemSK + '">' + item.OperatingSystemName + '</label> ';
});
os += '</div>';
return os;
}
});
}
the first "A" in AJAX stands for "Asynchronous" that means, it is not executed right after it has been called. So you never get the value.
Maybe you could first, get the os list and then output what you need, like this:
function createCheckBoxPlatform(myDatas) {
$.ajax({
url: "/QRCNew/GetOS",
type: "post",
dataType: "Json",
success: function (osList) {
var os = '<div>';
$.each(osList, function (i, item) {
os += '<label><input type="checkbox" name="' + item.OperatingSystemName + ' value="' + item.OperatingSystemSK + '">' + item.OperatingSystemName + '</label> ';
});
os += '</div>';
$.each(myDdatas, function (i, item) {
platform += '<label><input type="checkbox" name="' + item.PlatformName + ' value="' + item.PlatformSK + '">' + item.PlatformName + '</label>'+os
});
$('#platform').append((platform));
}
});
}

incorporating pagination in ajax json

I have a ajax json retrieving all query results in a div.I'm not sure how to introduce pagination though.
<script>
$(document).ready(function () {
var hdnIds = document.getElementById('<%= HiddenField1.ClientID %>').value;
$.ajax({
type: "POST",
url: "WebService1.asmx/GetEmployees",
data: "{userid: " + JSON.stringify(hdnIds) + " }",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (list) {
$("#Something").append("<ul id='bullets' class='ul1'></ul>");
for (i = 0; i < list.d.length; i++) {
$("#bullets").append("<li class='li1'>"
+ "<div style='float:left; width:20%'>"
+ "<img id='image' src='Handler3.ashx?id=" + list.d[i].id + "' />"
+ "<p style='margin-left:2px; position:relative;color:DodgerBlue;font-size:small; font-style:bold'>" + list.d[i].UserName + "</p>"
+ "<p style='margin-left:2px; position:relative;color:DodgerBlue;font-size:small'>" + list.d[i].Created_on + "</p>"
+ "</div>"
+ "<div style='float:left; width:80%'>"
+ "<p class='p11'>" + list.d[i].Statusmes + "</p>"
+ "</div>"
+ "</li>");
}
},
error: function (e) {
$("#Something").html("There was an error retrieving records");
}
});
});
</script>
And html as
<div id="Something"></div>
ANy help will be greatly appreciated!
First, I would read up on javascript templating. There are a lot of libraries out there that will allow you to remove the bloated html code from your JS code so that it's easier to manage. Something like this: https://github.com/BorisMoore/jquery-tmpl.
After that, you should put the responsibility of pagination on the server side and let the JS/Ajax handle the calls to retrieve the data set. For instance:
//server side
var start = request.params.start //retrieve start index for data set
var limit = request.params.limit //retrieve max number of data set size
return db.Model.find({start: start, limit: limit, ...})
//client side JS/Ajax
//load first page 0-9
$.ajax({
url: '/my/data/url',
params: {
start: 0, //start at first record in db
limit: 10 //only return 10 results
}
}).success(function(data) {
//render data set using template
$.template('#my-data-template', data).renderTo('#someDiv');
});
//load second page 10-19
$.ajax({
url: '/my/data/url',
params: {
start: 10, //start at nth record in db
limit: 10 //only return 10 results
}
}).success(function(data) {
//render data set using template
$.template('#my-data-template', data).renderTo('#someDiv');
});
If I understand the question correctly, you already know about append which is what you need, but you need to change all your ids to classes since there will be more than 1 of them. Then, put all of the html you want to append into a string and just append that html.
HTML:
<div id = "parent">
<div class = "Something"></div>
</div>
JAVASCRIPT (replace to the success AJAX call):
var htmlList = "<div class = "Something"><ul class='bullets ul1'>";
for (i = 0; i < list.d.length; i++) {
htmlList += "<li class='li1'>"
+ "<div style='float:left; width:20%'>"
+ "<img id='image' src='Handler3.ashx?id=" + list.d[i].id + "' />"
+ "<p style='margin-left:2px; position:relative;color:DodgerBlue;font-size:small; font-style:bold'>" + list.d[i].UserName + "</p>"
+ "<p style='margin-left:2px; position:relative;color:DodgerBlue;font-size:small'>" + list.d[i].Created_on + "</p>"
+ "</div>"
+ "<div style='float:left; width:80%'>"
+ "<p class='p11'>" + list.d[i].Statusmes + "</p>"
+ "</div>"
+ "</li>");
}
htmlList += "</ul></div>";
$("#parent").append(htmlList);

populating data in two html tables using two ajax calls

i'm trying to populate two tables using two separate ajax calls. following is my code.
var payload = "authUserName=admin&authPassword=admin";
$.ajax({
url: "https://appserver.dev.cloud.wso2.com/t/madusanka/webapps/projecttracker-default-SNAPSHOT/services/projecttracker/userservice/user/1/projects",
type: "POST",
async: false,
dataType: "json",
data: payload,
complete: function(data) {
alert("complete " + JSON.stringify(data));
// for(var i = 1; i<= data.projects.project.length; i++){
// var tableRow = "<tr><td>" + data.projects.project[i].projectName + "</td><td>" + data.projects.project[i].startDate + "</td><td>" + data.projects.project[i].endDate + "</td><td>" + data.projects.project[i].statusId + "</td><td>" + "delete" + "</td></tr>";
// $("#projectListTable tbody:last").append(tableRow);
// }
}
}).then(function(data) {
alert("started");
var payload2 = "authUserName=admin&authPassword=admin";
$.ajax({
url: "https://appserver.dev.cloud.wso2.com/t/madusanka/webapps/projecttracker-default-SNAPSHOT/services/projecttracker/userservice/user/1/projects",
type: "POST",
async: false,
dataType: "json",
data: payload2
}).then(function(data) {
alert("ended");
for(var i = 1; i<= data.projects.project.length; i++){
var tableRow = "<tr><td>" + data.projects.project[i].projectName + "</td><td>" + data.projects.project[i].startDate + "</td><td>" + data.projects.project[i].endDate + "</td><td>" + data.projects.project[i].statusId + "</td><td>" + "delete" + "</td></tr>";
$("#userTable tbody:last").append(tableRow);
}
});
});
If i run above code as it is it will execute well and execute whatever functions in "then".
When i uncomment the commented for loop, it won't execute beyond that for loop. after populating project list table it simply stop executing. therefore "then" functions won't get executed. it seems only one table data population loop can be there.
I want both tables to be populated one after other using ajax. I'm really confused about this. Can someone point me in correct direction?
Why do you need to have both complete and then callback functions? Looking at your codes, they don't seem to do anything different. You might as well just merge them like this:
var payload = "authUserName=admin&authPassword=admin";
$.ajax({
url: "https://appserver.dev.cloud.wso2.com/t/madusanka/webapps/projecttracker-default-SNAPSHOT/services/projecttracker/userservice/user/1/projects",
type: "POST",
dataType: "json",
data: payload,
complete: function(data) {
alert("complete " + JSON.stringify(data));
for(var i = 1; i<= data.projects.project.length; i++){
var tableRow = "<tr><td>" + data.projects.project[i].projectName + "</td><td>" + data.projects.project[i].startDate + "</td><td>" + data.projects.project[i].endDate + "</td><td>" + data.projects.project[i].statusId + "</td><td>" + "delete" + "</td></tr>";
$("#projectListTable tbody:last").append(tableRow);
$("#userTable tbody:last").append(tableRow);
}
}
});

Categories

Resources