I am new to JavaScript. I am creating one table dynamically; I am facing a problem with the order of execution. I know JavaScript code won't execute sequentially, but what will be the work around?
First I will brief what I am trying to do.
1) loadList ()
-> I will call this method on click of load data button
here I will fire AJAX request to get data
2) using the result of above AJAX request, I am trying to create table rows
3) few table rows td
having bo box, whose value to be filled using another AJAX call, passing the rowObject
value
Below is my code:
var loadList = function(){
//ajax call
$.ajax({
url:"tworows.json",
type: "GET",
dataType : "json"
})
.done(function(data, textStatus, jqXHR){
generateTable(data);
});
};
function generateTable(data){
$("#gridTable").empty();
//create table header
var headertr = $("<tr><th>col1 </th><th>col 2</th><th>col 3</th><th>col 4</th><th>col 5</th><th>col 6</th><th>col 7</th></tr>");
//get table id from jquery
var tableelement = $("#gridTable");
//add header row to table
tableelement.append(headertr);
for(var i=0; i< data.links.id.length; i++){
tableelement.append(createRow(data.links.id[i]));
}
}
function createRow(rowObject){
//used to create bo box 1 based row 1 value
var bo1 = createCombo1(rowObject);
//used to create bo box 2 based row 1 value
var bo2 = createCombo2(rowObject);
var trElement = "<tr>"+
"<td><input type='text' name='col1name' value='"+rowObject.Number+"' onblur='handleInput(this)'/></td>"+
"<td><input type='text' name='col3name' value='"+rowObject.name+"'/></td>"+
"<td><input type='text' name='col3name' value='"+rowObject.quantity+"'/></td>"+
"<td>"+bo1+"</td>"+
"<td>"+bo2+"</td>"+
"<td><button>Del</button></td>" +
"<td><button>Add</button></td></tr>";
return trElement;
}
function createCombo1(rowObject){
var boList = [];
//call ajax to get bo value
$.ajax({
url:"bo1data.json",
type: "GET",
dataType : "json",
async : false
})
.done(function(data, textStatus, jqXHR){
boList = data.links.id;
});
var cmb1 = "<select name='cmb1' onchange='handlecmb1Change(this)'>";
for(var i=0;i < boList.length; i++){
cmb1 +="<option value='"+boList[i].id+"'>"+boList[i].name+"</option>";
}
cmb1 += "</select>";
return cmb1;
}
function createCombo2(rowObject){
var boList = [];
//call ajax to get bo value
$.ajax({
url:"bo2data.json",
type: "GET",
dataType : "json",
async : false
})
.done(function(data, textStatus, jqXHR){
boList = data.links.id;
});
var cmb2 = "<select onchange='handlecmb2Change(this)'>";
for(var i=0;i < boList.length; i++){
cmb2 +="<option value='"+boList[i].id+"'>"+boList[i].name+" </option>";
}
cmb2 += "</select>";
return cmb2;
}
Here row is creating first, after that control is going to createCombo
methods. Because of this I am not getting bo boxes in td
.
I want to create bobox based on first result of AJAX call; using the first result I need to call other 2 AJAX calls and populate them in the td
bobox.
I am new to JavaScript. I am creating one table dynamically; I am facing a problem with the order of execution. I know JavaScript code won't execute sequentially, but what will be the work around?
First I will brief what I am trying to do.
1) loadList ()
-> I will call this method on click of load data button
here I will fire AJAX request to get data
2) using the result of above AJAX request, I am trying to create table rows
3) few table rows td
having bo box, whose value to be filled using another AJAX call, passing the rowObject
value
Below is my code:
var loadList = function(){
//ajax call
$.ajax({
url:"tworows.json",
type: "GET",
dataType : "json"
})
.done(function(data, textStatus, jqXHR){
generateTable(data);
});
};
function generateTable(data){
$("#gridTable").empty();
//create table header
var headertr = $("<tr><th>col1 </th><th>col 2</th><th>col 3</th><th>col 4</th><th>col 5</th><th>col 6</th><th>col 7</th></tr>");
//get table id from jquery
var tableelement = $("#gridTable");
//add header row to table
tableelement.append(headertr);
for(var i=0; i< data.links.id.length; i++){
tableelement.append(createRow(data.links.id[i]));
}
}
function createRow(rowObject){
//used to create bo box 1 based row 1 value
var bo1 = createCombo1(rowObject);
//used to create bo box 2 based row 1 value
var bo2 = createCombo2(rowObject);
var trElement = "<tr>"+
"<td><input type='text' name='col1name' value='"+rowObject.Number+"' onblur='handleInput(this)'/></td>"+
"<td><input type='text' name='col3name' value='"+rowObject.name+"'/></td>"+
"<td><input type='text' name='col3name' value='"+rowObject.quantity+"'/></td>"+
"<td>"+bo1+"</td>"+
"<td>"+bo2+"</td>"+
"<td><button>Del</button></td>" +
"<td><button>Add</button></td></tr>";
return trElement;
}
function createCombo1(rowObject){
var boList = [];
//call ajax to get bo value
$.ajax({
url:"bo1data.json",
type: "GET",
dataType : "json",
async : false
})
.done(function(data, textStatus, jqXHR){
boList = data.links.id;
});
var cmb1 = "<select name='cmb1' onchange='handlecmb1Change(this)'>";
for(var i=0;i < boList.length; i++){
cmb1 +="<option value='"+boList[i].id+"'>"+boList[i].name+"</option>";
}
cmb1 += "</select>";
return cmb1;
}
function createCombo2(rowObject){
var boList = [];
//call ajax to get bo value
$.ajax({
url:"bo2data.json",
type: "GET",
dataType : "json",
async : false
})
.done(function(data, textStatus, jqXHR){
boList = data.links.id;
});
var cmb2 = "<select onchange='handlecmb2Change(this)'>";
for(var i=0;i < boList.length; i++){
cmb2 +="<option value='"+boList[i].id+"'>"+boList[i].name+" </option>";
}
cmb2 += "</select>";
return cmb2;
}
Here row is creating first, after that control is going to createCombo
methods. Because of this I am not getting bo boxes in td
.
I want to create bobox based on first result of AJAX call; using the first result I need to call other 2 AJAX calls and populate them in the td
bobox.
- try asyn:false in ajax call – Illaya Commented Jun 5, 2014 at 11:43
- Thanks Illaya, it worked this means if no ajax call then javascript go line by line in correct order? – user3231742 Commented Jun 5, 2014 at 12:39
- If it is working, then give me an upvote @user3231742 – Illaya Commented Jun 6, 2014 at 5:22
- still i need 12 more reputaions to give u vote i guess.. – user3231742 Commented Jun 6, 2014 at 5:32
2 Answers
Reset to default 2Please use below code block, this might be solve your problem. Your requirement need synchronous execution of methods, for this you need to use callback structure. below is the code :
var loadList = function(){
//ajax call
$.ajax({
url:"tworows.json",
type: "GET",
dataType : "json"
})
.done(function(data, textStatus, jqXHR){
generateTable(data);
});
};
function generateTable(data){
$("#gridTable").empty();
//create table header
var headertr = $("<tr><th>col1 </th><th>col 2</th><th>col 3</th><th>col 4</th><th>col 5</th><th>col 6</th><th>col 7</th></tr>");
//get table id from jquery
var tableelement = $("#gridTable");
//add header row to table
tableelement.append(headertr);
for(var i=0; i< data.links.id.length; i++){
tableelement.append(createRow(data.links.id[i]));
}
}
function createRow(rowObject){
var trElement = "<tr>";
//used to create bo box 1 based row 1 value
var bo1 = createCombo1(rowObject,function(response){
//used to create bo box 2 based row 1 value
var bo2 = createCombo2(rowObject,function(result){
trElement+= "<td><input type='text' name='col1name' value='"+rowObject.Number+"' onblur='handleInput(this)'/></td>";
trElement+="<td><input type='text' name='col3name' value='"+rowObject.name+"'/></td>";
trElement+="<td><input type='text' name='col3name' value='"+rowObject.quantity+"'/></td>";
trElement+="<td>"+response+"</td>";
trElement+="<td>"+result+"</td>";
trElement+="<td><button>Del</button></td>";
trElement+="<td><button>Add</button></td></tr>";
});
});
return trElement;
}
function createCombo1(rowObject,callback){
var boList = [];
//call ajax to get bo value
$.ajax({
url:"bo1data.json",
type: "GET",
dataType : "json"
})
.done(function(data, textStatus, jqXHR){
boList = data.links.id;
var cmb1 = "<select name='cmb1' onchange='handlecmb1Change(this)'>";
for(var i=0;i < boList.length; i++){
cmb1 +="<option value='"+boList.id+"'>"+boList.val+"</option>";
}
cmb1 += "</select>";
return callback(cmb1);
});
}
function createCombo2(rowObject,callback){
var boList = [];
//call ajax to get bo value
$.ajax({
url:"bo2data.json",
type: "GET",
dataType : "json"
})
.done(function(data, textStatus, jqXHR){
boList = data.links.id;
var cmb2 = "<select name='cmb1' onchange='handlecmb1Change(this)'>";
for(var i=0;i < boList.length; i++){
cmb1 +="<option value='"+boList.id+"'>"+boList.val+"</option>";
}
cmb2 += "</select>";
return callback(cmb2);
});
}
thanks
There are several problems that need to be addressed.
First, the return value from an ajax callback won't go anywhere.
This line
var bo1 = createCombo1(rowObject);
Will set bo1 to undefined
every single time. Because createCombo1()
doesn't return anything. The anonymous function inside of createCombo1()
is what returns the value your looking for, but in this case you can't use that return value.
What I remend for createCombo1()
and createCombo2()
is to save the return value to a global variable or maybe even an array, so you can access them when they are done.
Which brings me to the next problem...how do you know when they are done?
jQuery has something called a deferred object. Which allows you to chain multiple callbacks to one function. There is a similar SO question that addresses how to use this using When()
.
Here is the question
There is still a lot to do on your end, but hopefully this will point you in the right direction.