So I have my server-side code which executes multiple bigquery queries and arranges the results in a table,and this server-side code is called by an ajax call from the client.
I want to be able to send the table/div from my server-side code to client-side and have it render there. Is that possible??
I don't want to be able to create the tables on the client by first getting the JSON results through the call, since I will not know which query will run first and all the results are different. (multiple ajax calls are also out of the question for each query)
Server code (app.js)
function printResult(rows, queryNumber) {
console.log('Query No. '+queryNumber+' Results:____');
var keys = [];
if (queryNumber == 1) {
var table = document.createElement('table');
var td = [];
var tr = document.createElement('tr');
for (var i = 0; i < rows[0].length; i++) {
var tn1 = document.createTextNode(rows[i].Content_title);
var tn2 = document.createTextNode(rows[i].Audience_Size);
td[i] = document.createElement('td');
td[i].appendChild(tn1);
td[i + 1] = document.createElement('td').appendChild(tn2);
tr.appendChild(td[i]);
tr.appendChild(td[i + 1]);
table.appendChild(tr);
res.send(table);
}
}
}
Ajax call
$.ajax({
url: 'http://localhost:3000/example',
type: 'POST',
data: {showname: show, counter: uniquesOverallShowsCounter},
dataType: 'text',
contentType: 'application/x-www-form-urlencoded',
success: function (data) {
document.getElementById('outputTables').appendChild(data);
},
error: function() {
console.log("error");
}
});
Yes you can, but as you pointed out in the comments, there is a problem with the data returned.
Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
This is an error which is thrown when you try to append a child node with JavaScript, which is not a documentElement (i.e. document.createElement('div')). Since you're already using jQuery, you could easily change your code.
In the success function for the AJAX call, change
document.getElementById('outputTables').appendChild(data);
to
$('#outputTables').append(data);
If you want to be able to do multiple AJAX calls from one page and change the table every time (like replace the old table with the new one), you should use html(data) instead of append(data).
So can you simply increase one more parameter in your response json based on the query which is hit for example "queryProcessed"?
And add that additional check on client side and render the mark up based on that "queryProcessed"
Related
I can't seem to manage to break out of my each loop if the ajax returns an error. I've tried
return false;
and other similar thing but the $.each still continues to run.
I need to be able to do this so that I can display error messages from my back end after posting it via ajax(I know this is bad practice however a client needed to be able to be able to send multiple forms off at once.).
Can anyone explain what I've done wrong?
var postAll = function(button_clicked)
{
e.preventDefault();
var form_response = [];
var formsCollection = document.getElementsByTagName("form");
$.each(formsCollection, function (key, value)
{
console.log(value.action);
console.log(value.id);
var url = value.action;
var id = value.id;
var data = ($('#' + id + '').serialize());
if (id == 'additionalInfo')
{
data = {'Add_info': $('#Add_info').val(),};
}
if (id != 'DONE')
{
$.ajax({
type: "POST",
dataType: 'json',
url: url,
beforeSend: function (xhr)
{
xhr.setRequestHeader('X-CSRF-TOKEN',$("#token").attr('content'));
},
data: data,
success: function (data)
{
console.log('success'); // show response from the php script.
form_response.push(data); // show response from the php script.
},
error: function (data)
{
console.log('fail'); // show response from the php script.
display_errors(data, id); // show response from the php script.
return true;
}
});
}
});
}
AJAX is asynchronous, when executing your $.each function it will execute the AJAX call and "Not wait" for the others to finish
To solve your problem you'll have to write a function that will execute the first ajax call and in the success it will execute itself again with the second ajax call.
Example:
var data = [form1,form2...etc];
function letsLoop(data,index = 0){
$.ajax({
url:....
success: function(){
letsLoop(data,index+1);
},
error: function(){
}
});
}
and here you call your function:
letsLoop(data,0);
If by breaking out of the loop you mean the return in your error handler, then it won't work as you think it would.
Your loop creates asynchronous requests 'at once'. Then each of these requests is handled by the browser (more or less simultaneously), then come responses. So by the time your error handler runs the loop has long finished.
BTW, the return in your case relates to the error handler, not the function inside the loop.
So, to achieve what you want you should 'queue' your AJAX requests and perform them one by one.
One possible solution is to create an array of forms then take (and remove it from the array) the first one, perform a request, on a response repeat the whole thing, and keep repeating until the array is empty.
Hi all I'm pretty new to PHP and AJAX and all that good stuff and I'm a little stumped on how to proceed from here in my code.
I have a form that is getting sent and I have an array (subcategories) which contains the form labels to retrieve the values of the fields. The fields and values are getting created dynamically based on a textfile that the user uploads so I don't have any way of knowing what they are.
var arrayLength = subcategories.length;
for (var i = 0; i < arrayLength; i++) {
var eachfield = subcategories[i];
//Do something
//#C: selector is working fine, cleaning input
var eachfield = $('#' + eachfield).val().trim();
//push the appropriate values with the fixed stuff to a new array
values.push(eachfield);
}
What I'm trying to do is now to set these variables to some name and send them through $data using AJAX and POST.
Something like the following if I was setting everything statically.
var data = {
dimitypedata: dimitype,
densitydata: density,
velocitydata: velocity,
temperaturedata: temperature,
submitbtnclicked: "submitted"
};
//using the data and sending it through a post with promise handling
$.ajax({
type: 'POST',
url: "controller.php",
data: data,
success: function(response) {
//alert("worked");
//console.log(response);
alert(response);
},
error: function() {
alert("There was an error submitting the information");
}
});
I'm not quite sure how to mix these two and it may be partially because of getting a confused and not yet being that great with POST and AJAX calls.
EDIT: It looks like my question was a bit unclear (sorry first post lol) I'm trying to dynamically push values that I take out of an HTML form field. The problem is that the form is generated depending on what the user chooses to upload to the site (so both the fields and the forms. My ultimate goal is to enable the user to edit the dynamically generated form based on a text file that they upload and be able to generate a new text file after editing it on the GUI after clicking on the submit button. I can do this if its static but I'm having trouble figuring out how to do the same if I don't know what the form will contain.
I'm trying to to my data object so I can use it in my AJAX call. Here's a little bit of the PHP code that I would use in the next step if the variables were static:
if(isset($_POST['submitbtnclicked']) && $_POST['submitbtnclicked'] == 'submitted') {
//new instance of model for use
$model = new model();
$dimitypedata = $_POST['dimitypedata'];
$densitydata = $_POST['densitydata'];
$velocitydata = $_POST['velocitydata'];
$temperaturedata = $_POST['temperaturedata'];
For an exact answer, we need to see what the "subcategories" array look like.
If I understood correctly, you would like to put the values in an object instead of an array (values). So the first part would look like:
var data = {};
var arrayLength = subcategories.length;
for (var i = 0; i < arrayLength; i++) {
//notice that now field name and field value go in separate variables
var fieldName = subcategories[i];
//#C: selector is working fine, cleaning input
var fieldValue = $('#'+eachfield).val().trim();
//push the appropriate values with the fixed stuff to a data object
data[fieldName] = fieldValue;
}
//and then you send your gathered data
//using the data and sending it through a post with promise handling
$.ajax({
type: 'POST',
url: "controller.php",
data: data,
success: function(response) {
//alert("worked");
//console.log(response);
alert(response);
},
error: function() {
alert("There was an error submitting the information");
}
});
If you want to generate your 'data' object using 'values' variable, you can do the next:
values = []; // here your values collected previously
var data = {};
for (var key in values){
data[key] = values[key];
}
//now you can use your data in AJAX
I've read a good bit about callbacks, and while I use them for click events and similar, I'm using them without fully understanding them.
I have a simple web app with 3 or 4 html pages, each with its own js page.
I have some global functions that I've placed in a new js page which is referenced by each html page that needs it. I'm using this file, word_background.js, to hold functions that are lengthy and used by multiple pages.
pullLibrary is a function, residing in word_background.js, that pulls from my db and processes the results.
I want to call pullLibrary from webpageOne.html, make sure it completes, then do more processing in webpageOne.js.
In webpageOne.js I have the following - trying to call pullLibrary and, once it is complete, use the results for further work in webpageOne.js.
The code executes pullLibrary (in word_background.js) but doesn't "return" to webpageOne.js to continue processing.
I'm assuming I'm missing some critical, essential aspect to callbacks...
I just want to run the pullLibrary function (which has ajax calls etc) and, once it is complete, continue with my page setup.
Any explanation/correction appreciated.
This code is in webpageOne.js:
pullLibrary(function(){
console.log('Now processing library...');
processLibrary();
updateArrays();
//Do a bunch more stuff
});
----- UPDATE -----
Thank you for the comments...which I think are illuminating my broken mental model for how this should work.
pullLibrary is an ajax function - it pulls from a database and stuffs the results into an array and localStorage.
My expectation is that I can call pullLibrary and, when it is complete, the callback code (in this case anonymous function) will run.
function pullLibrary(){ //Values passed from startup() if no data is local
//Pull data from database and create basic LIBRARY array for further processing in processLibrary sub
console.log("Starting to pull library array in background.js..." + "User: " + localStorage.userID + " License: " + localStorage.licType);
var url1 = baseURL + 'accessComments3.php';
var url2 = '&UserID=' + localStorage.userID + '&LicType=' + localStorage.licType;
//Need global index to produce unique IDs
var idIndex = 0;
var index = 0;
$.ajax({
type: "POST",
url: url1,
data: url2,
// dataType: 'text',
dataType: 'json',
success: function(result){
// success: function(responseJSON){
arrLibrary = result; //store for use on this page
localStorage.library = JSON.stringify(result); //Store for use elsewhere
console.log('Saving to global variable: ') + console.log(arrLibrary);
//Now mark last update to both sync storage and local storage so access from other browsers will know to pull data from server or just use local arrays (to save resources)
var timeStamp = Date.now();
var temp = {};
temp['lastSave'] = timeStamp;
// chrome.storage.sync.set(temp, function() {
console.log('Settings saved');
localStorage.lastSync = timeStamp;
console.log('Last update: ' + localStorage.lastSync);
//Store Group List
var arrComGroups = $.map(arrLibrary, function(g){return g.commentGroup});
// console.log('List of comment groups array: ') + console.log(arrComGroups);
arrComGroups = jQuery.unique( arrComGroups ); //remove dupes
// console.log('Unique comment groups array: ') + console.log(arrComGroups);
localStorage.groupList = JSON.stringify(arrComGroups); //Store list of Comment Groups
//Create individual arrays for each Comment Groups
$.each(arrComGroups,function(i,gName){ //Cycle through each group of Comments
var arrTempGroup = []; //to hold an array for one comment group
arrTempGroup = $.grep(arrLibrary, function (row, i){
return row.commentGroup == gName;
});
//Store string version of each Comment Array
window.localStorage['group_' + gName] = JSON.stringify(arrTempGroup);
console.log('Creating context menu GROUPS: ' + gName);
});
// processLibrary(arrLibrary); //We've pulled the array with all comments - now hand off to processor
}, //End Success
error: function(xhr, status, error) {
alert("Unable to load your library from 11trees' server. Check your internet connection?");
// var err = eval("(" + xhr.responseText + ")");
// console.log('Error message: ' + err.Message);
}
}); //End ajax
}
Okay, there are tons of "here's how callbacks work" posts all over the internet...but I could never get a crystal clear example for the simplest of cases.
Is the following accurate?
We have two javascript files, one.js and two.js.
In one.js we have a function - lets call it apple() - that includes an Ajax call.
two.js does a lot of processing and listening to a particular html page. It needs data from the apple() ajax call. Other pages are going to use apple(), also, so we don't want to just put it in two.js.
Here's how I now understand callbacks:
one.js:
function apple(callback_function_name){
$.ajax({
type: "POST",
url: url1,
data: url2,
dataType: 'json',
success: function(result){
//apple processing of result
callback_function_name(); //This is the important part - whatever function was passed from two.js
}, //End Success
error: function(xhr, status, error) {
}
}); //End ajax
} //End apple function
** two.js **
This js file has all kinds of listeners etc.
$(document).ready(function () {
apple(function(apple_callback){
//all kinds of stuff that depends on the ajax call completing
//note that we've passed "apple_callback" as the function callback name...which is stored in the apple function as "callback_function_name".
//When the ajax call is successful, the callback - in this case, the function in two.js, will be called back...and the additional code will run
//So the function apple can be called by all sorts of other functions...as long as they include a function name that is passed. Like apple(anothercallback){} and apple(thirdcallback){}
}); //End apple function
}); //End Document.Ready
I have working on a webpage that displays json data in a html hierarchical structure, using the jQuery plugin json2html.
Currently the json data is entered into a text area and a button is pressed to run the conversion. This is the current function that gets the json from the text area and starts the conversion.
$('#btnVisualize').click(function() {
//Get the value from the input field
var json_string = $('#inputJSON').val();
try
{
//json
//var json = JSON.parse(json_string);
eval("var json=" + json_string);
visualize(json);
}
catch (e)
{
alert("Sorry error in json string, please correct and try again: " + e.message);
}
});
The api that the data is comming from needs a lot of authentication, so I have a seperate javascript file that generates the authenticaton and creates the full url to load the api.
function generateUrl(itemkey) {
var orig = "http://explorerapi.barratthomes.co.uk/v2.0/development/getbyitemkey?ItemKey="+itemkey+"&";
Auth.Auth = createAuth();
var var_pairs = [
{name: "Auth.Utc", val: encodeURI(Auth.Auth.Utc)},
{name: "Auth.RequestId", val: Auth.Auth.RequestId},
{name: "Auth.DeviceId", val: Auth.Auth.DeviceId},
{name: "Auth.Hash", val: Auth.Auth.Hash}];
for(var i=0; i<var_pairs.length; i++) {
orig += (i==0?"":"&")+var_pairs[i].name+"="+var_pairs[i].val;
}
var var_names = ["BrandCode", "ApplicationId", "ApplicationVersion", "LanguageCode", "IsPublished", "MarketingSuiteDevelopmentId", "UserLocation", "Os", "ScreenResolution", "Hierarchical"];
for(var j=0; j<var_names.length; j++) {
orig += "&"+var_names[j]+"="+Auth[var_names[j]];
}
return orig;
}
This is the function that generates the url.
I need to take the url from that function and connect to the api and pass the data directly to the json2html function, so I no longer have to paste the json data into the text area.
I have been looking at $.getJson and $.parseJSON but having no luck, I'm not sure where to go next?
Try this Jsonp to do the fetching the data from the url
function insertIntoTextArea(content) {
document.getElementById('output').innerHTML = content;
}
// create script element
var script = document.createElement('script');
// assing src with callback name
script.src = 'your proper url?callback=insertIntoTextArea';
// insert script to document and load content
document.body.appendChild(script);
You should be able to use $.getJSON like this
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
And then just pass the data object to json2html. However, check with the API that you're connecting to http://explorerapi.barratthomes.co.uk/v2.0/development/getbyitemkey as they might require JSONP (which pretty much just performs a callback function to get around CORS).
See http://api.jquery.com/jquery.getjson/
If the URL includes the string "callback=?" (or similar, as defined by the >server-side API), the request is treated as JSONP instead. See the discussion >of the jsonp data type in $.ajax() for more details.
I have the code section below which is a simple AJAX call to retrieve a JSON string from a .ASMX VB .NET Web Method. On success, it calls the createList function below, which should take the values in the JSON string (now parsed and formatted) and add them as new list items.
My issue is that the page does not update with the new list items, even though the callback function is successful. The loop executes, data is received and I have already tested with alerts just to make sure I'm not going crazy.
When I use the exact same line (substituting test data for the JSON string) to append my new list items, everything works fine.
As a side note for anyone that might be wondering why I believe I have to use this methodology:
It is important that I call the AJAX function the way I do, so I may pass multiple parameters to the function when I build the list. The other parameters allow me to specifically find which element is active in my user control.
I am relatively new to using AJAX as well. I hope I was able to explain everything clearly.
Thanks!
function getPcList(activeRow, activeTd) {
var row = $(activeRow).attr("id");
$.ajax({
url: "AJAXWebService.asmx/getPartnerColleges",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(data) {
createList(data, activeRow, activeTd);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
}
function createList(data, activeRow, td) {
var obj = JSON.stringify(eval("(" + data.d + ")"));
var json = $.parseJSON(obj);
var row = $(activeRow).attr("id");
var newtd = $(td).attr("id");
for (i = 0; i < json.length - 1; i++) {
$("#"+row+ "#" + newtd + " > #list > #thelist")
.append("<li id='listitem'" + i +
"' style='width:100%; z-index:300; position:relative' onclick='txtAppend($(this).parents().eq(2))'>" +
json[i] + "</li>");
}
}
If the string returned from the server is a JSON, as indicated by the dataType field of the $.ajax() call, you shouldn't need to use JSON.stringify() and eval(). You should be able to parse the string directly with $.parseJSON().