Retrieve multiple variables from an AJAX call to jQuery - javascript

I have a PHP file that requests six rows from a database. I'm using an ajax call.
I want these six rows (multiple columns) to be passed through to my main file. I was unable to find a way to get these values to my main page except for posting them in html in the request file and posting this as a table on my main page.
I don't want them on the page in a plain table for everyone to be seen.
So not like this:
success: function(html) {
$("#display").html(html).show();
}
I always need six rows at the moment but could be more later on.
One of the ideas that I had was posting it as one long string and loading this into a variable, and then reading using explode or something a-like. Not sure if this is a good way to do this...
I am basically asking for ideas to expand my horizon.
I am still learning JavaScript and jQuery so I'd rather have a good explanation than a block of working code.
Thanks in advance!

PHP Side
This is a very simple process, which you may kick yourself after grasping ;) But once you do, it opens a world of possibilities and your mind will go crazy with ideas.
The first stage is you want to adjust your data that you will be returning to the ajax call. If you have a few rows of a few fields, you would do have something along these lines (could come from db, or assignments, whatever):
$rows = [];
$rows[] = array('thing'=>'value 1','something'=>'blah','tertiary'=>'yup');
$rows[] = array('thing'=>'value 2','something'=>'yadda','tertiary'=>'no');
$rows[] = array('thing'=>'value 3','something'=>'woop','tertiary'=>'maybe');
Now, to get this rows of data out to ajax, you do this one simple operation:
echo json_encode($rows);
exit; // important to not spew ANY other html
Thats all you really need to do on the PHP side of things. So what did we do? Well, we took a multidimensional array of data (usually representing what comes from a database), and encoded it in JSON format and returned it. The above will look like this to your browser:
[{"thing":"value 1","something":"blah","tertiary":"yup"},
{"thing":"value 2","something":"yadda","tertiary":"no"},
{"thing":"value 3","something":"woop","tertiary":"maybe"}]
It will have handled all escaping, and encoding of utf8 and other special characters. The joys of json_encode()!
JAVASCRIPT Side
This side is not as difficult, but theres some things to understand. FIrst off, lets get your jquery ajax call into shape:
<div id="rows"></div>
<script>
$("#your-trigger").on('click',function(e){
e.preventDefault(); // just stops the click from doing anything else
$.ajax({
type: "POST",
url: 'your_ajax.php',
data: { varname: 'value', numrows: '6' },// your sent $_POST vars
success: function(obj) {
// loop on the obj return rows
for(var i = 0; i < obj.length; i++) {
// build a div row and append to #rows container
var row = $('<div></div>');
row.append('<span class="thing">'+ obj[i].thing +'</span>');
row.append('<span class="details">'+
obj[i].something +' '+ obj[i].tertiary
+'</span>');
$("#rows").append(row);
}
},
dataType: 'json' // important!
});
});
</script>
So lets explain a few key points.
The most important is the dataType: 'json'. This tells your ajax call to EXPECT a json string to turn into an object. This object becomes what you define in the success function arg (which I named obj above).
Now, to access each specific data variable of each row, you treat it as an object. Array of rows, each row has vars named as you named them in PHP. This is where I have the for example to loop through the array of rows.
For example obj[0].thing refers to the first row of variable thing. The use of i lets you just go through all rows automatically based on length of the object. A few handy things in there.
You can build any html you wish from the returned object and values. I just showed how to setup a <div><span class="thing"></span><span class="details"></span></div> example row. You may want to use tables, or more complex setups and code.
To keep the return data from your ajax call, you can store it in a local or global variable like so:
<script>
var globalvar;
$....('click',function(e){
var localvar;
$.ajax(.... success: function(obj){
....
localvar = obj;
globalvar = obj;
....
});
});
</script>

Do what Frederico says above. Return json from your php and get in in jQuery using ajax call.
Something like this: http://makitweb.com/return-json-response-ajax-using-jquery-php/. Just skip step #3 and do what you need with received data in step #5 if you don't need it to be printed to html.

Related

The file is emptied when I use file_put_contents

Main issue was solved in comments, although one of the bonus questions is still open and the other's solution could use some improvement
All of this takes place on a webhosting service, the folder structure is as follows:
The JavaScript and PHP files are in /public_html/, the JSON is in /public_html/data/.
In my JS code, I'm sending a POST request with some data for my JSON file:
console.log(objdata.buildings[0].coords);
var params = JSON.stringify(objdata);
if (objdata.buildings[0].coords != " "){
$.ajax({
type: "POST",
data: params,
url: "writecoords.php",
success: function(data){
console.log(params);
console.log(data);
console.log("AJAX success");
},
error: function(){
console.log("failed to send POST");
alert("error");
}
});
}
PHP file:
<?php
function debug_to_console($data){
if(is_array($data) || is_object($data))
{
echo("\n".json_encode($data));
} else {
echo("\n".$data);
}
}
$newJSON = json_decode(file_get_contents('php://input'));
debug_to_console($newJSON);
if (is_writable('data/strogi.json')) {
$a = file_put_contents('data/strogi.json', $newJSON);
if(! $a)
debug_to_console("Wrote nothing");
debug_to_console("PHP write success");
} else {
debug_to_console("PHP write failed");
}
?>
As you can see, I perform a check at every possible point to see if I'm actually processing non-empty data -- I log the value of the key in question, the AJAX request is sent only if it was changed, I log the data being sent and I log the data my PHP file receives and decodes.
I also check if the file is writable to avoid a possible permission problem, and only then I try to write to the file. The file comes out empty and I get the following outputs in console
params is my JSON object as a single line;
data is: my JSON object as a single line with line breaks before every new object and all cyrillic converted to \u format, "Wrote nothing!", "PHP write success";
"AJAX success"
If I check the strogi.json file after this, it's absolutely empty.
To rule out a problem with the format of passed JSON object, I tried writing to a simple test.txt file in the same directory as the .php, which turns out empty as well.
I tried using the method described here, but nothing changed.
I tried using a FTP upload (the method is pointed out somewhere in the comments here), and I got "No such file or directory" returned both for the strogi.json and test.txt files. I used both public_html/test.txt and test.txt as file name.
I tried using the combination of locks FILE_APPEND | LOCK_EX, and no changes happen to either of the files.
My questions are:
Why?
Can a different solution be used if all of this is taking place in the .done() callback for $.getJSON() called on the same file?
Follow-up question worthy of a separate section:
coords is a 3-dimensional array
[
[[x1,y1],[x2,y2],...]]
]
where the external array contains up to two arrays. The first array contains points of the external polygon and (if present) second array contains points of the internal polygon that serves as a cutout.
The code in question is an attempt to make submitting the coords array to strogi.json work for at least one object.
What I'm trying to do, in general, is
$.getJSON() the data/strogi.json file
go through the buildings[] array of objects inside it in the .done()
callback
for each object, check if "coords" is " " (default value)
If it is, a constructor is called to build a polygon using a map API, and when construction is finished, $.ajax is used to submit coords extracted through one of API's functions.
As of now, I'm submitting the whole JSON object, because I'm only working with one of the inner objects, but I imagine resubmitting the whole thing is excessive with multiple objects presented.
Is there a way to pass objdata.buildings[i].coords with the index i to PHP to change the "coords" key value in JSON for a certain buildings[i] object?
Do I need to make any changes to the way I'm processing data to make my JSON valid upon further reads? I assume I'd have to change the "coords" value from [[[x1,y1],[x2,y2]]] (the way it's passed now) to something like this (pastebin because there's no code formatting even though I'm using the 4 space indent)
for it to work, right? How do I do that? partly solved by going through the array in JS with two for() loops and applying toString() to every coordinate, there's gotta be a better way

How to parse xml with js or jquery, when fields are not known in advance?

I have been searching for the past hour and have not found a solution that is well suited to my situation. I have an event registration form and in order for users to have the form auto populated they can specify an id from a previous registration. There are over 20 fields.
Everything is working pretty well. I have a PHP script that creates an xml response for ajax. The xml is of form
<response>
<field1>f1</field1>
<field1>f2</field1>
etc
</response>
My javascript is
$.ajax({
type : "POST",
url : "myscript.php",
data : $(this).serialize(),
success: function(xml){
$("#field1").val($("field1",xml).text());
$("#field2").val($("field2",xml).text());
}
})
Above works fine but I don't want to manually write out each form field assignment. I want to do it in a loop. So something like this in the success function:
var fields= xmlResponse.getElementsByTagName("response");
for (i = 0; i < fields.length; i++) {
// not sure what to put here...
}
In the for loop I have to index in to the node name and value so that I can simply have a statement that would be of this form: $("#"+fields[i].nodename).val($(fields[i].nodevalue,xml).text());
I tried
$("#" + fields[0].childNodes[i]).val(fields[0].childNodes[i].nodeValue);
But that did not return the values.
Any idea on how best to do this? I feel like I am very close to having this working! Thanks!
You can use $.parseXML, and then loop over the elements with .each().
var $xml = $.parseXML(xml);
$("#response", xml).children().each(function(i, e) {
var field = e.tagName;
var value = e.innerHTML;
$("#" + field).val(value);
});
You're on the right track. What it comes down to is that when you parse an XML file, the parser doesn't care what the fields are, it'll parse it as it sees it. You would basically have to tell the script to pull certain tags with certain text. As far as I know, this is best done using the .tagName property and the tag's value and storing it in an object.
var data={}
$(this).children().each(function() {
data[this.tagName]=$(this).text();
})
You can see how this would work here:
http://jsfiddle.net/dpK7x/1/

Execute javascript inside the target of an Ajax Call Drag and Drop Shopping Cart without Server language

Well i wanna create an Ajax Drag and Drop Shopping cart using only javascript and ajax. Currently i'm using the example in this page as a stepping stone. Right now it's only with local jquery and it works fine but i want to make the cart work with ajax calls. Note that i do not want to use a server side language( like php, rubby, asp etc), only html and javascript.
My initial thought was that at the $(".basket").droppable i should add an ajax call to another html page containing the "server logic" in javascript, execute in that file all the necessary steps( like reading the get variables (product name, product id and quantity), set a cookie and then return an ok response back. When the server got the "ok" response it should "reload" the cart div with the updated info stored inside the cookie.
If this was with php i would know how to do it. The problem is that as far as i know, you can execute javascript once it reaches the DOM, but how can you execute that js from inside the page that isbeing called upon ? ( thanks to Amadan for the correction)
I've thought about loading the script using $.getScript( "ajax/test.js", function( data, textStatus, jqxhr ).. but the problem with that is that the url GET variables i want to pass to the "server script" do not exist in that page.
I havent implemented all the functionality yet as i am stuck in how to first achieve javascript execution inside an ajax target page.
Below is a very basic form of my logic so far
// read GET variables
var product = getQueryVariable("product");
var id = getQueryVariable("id");
var quantity= getQueryVariable("quantity");
//To DO
//--- here eill go all the logic regarding cookie handling
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
alert('Query Variable ' + variable + ' not found');
}
Any help regarding this matter will be appreciated.
Note: Logic in simple words:
1)have an html page with products+cart
2)Have an "addtocart.html" with the "Cart Server Logic"( being the target of the ajax call when an item is dropped into the product.)
If you have some other idea on this, please enlighten me :)
thanks in advance
Foot Note-1:
if i try loading the scipt using
$("#response").load("ajax/addtocart.html?"+ $.param({
product: product,
id: id,
quantity:quantity
})
);
i get the alert about not being able to find the url parameters( something that i thing is normal as because the content is being loaded into the initial page, from which the request is started, there are no get parameters in the url in the first place)
The problem is that as far as i know, you cannot execute javascript contained in the target of an ajax call, as that page never reaches the browser interpreter.
This is either incorrect or misleading. The browser will execute any JavaScript that enters DOM. Thus, you can use $.load to load content and execute code at the same time. Alternately, you can use hacked JSONP to both execute code and also provide content as a JSON document.
EDIT: Yes, you can't get to the AJAX parameters from JavaScript. Why do you want to? Do you have a good reason for it, or is it an XY problem?
The way I'd do it is this:
$('#response').load(url, data, function() {
onAddedToCart(product, id, quantity);
});
and wrap your JS code in your HTML into the onAddedToCart function.
Depending on what exactly you're doing, it could be simplified even further, but this should be enough to cover your use case.

passing JSON data and getting it back

I'm new to passing objects through AJAX, and since I am unsure of both the passing and retrieving, I am having trouble debugging.
Basically, I am making an AJAX request to a PHP controller, and echoing data out to a page. I can't be sure I'm passing my object successfully. I am getting null when printing to my page view.
This is my js:
// creating a js filters object with sub arrays for each kind
var filters = {};
// specify arrays within the object to hold the the list of elements that need filtering
// names match the input name of the checkbox group the element belongs to
filters['countries'] = ["mexico", "usa", "nigeria"];
filters['stations'] = ["station1", "station2"];
filters['subjects'] = ["math", "science"];
// when a checkbox is clicked
$("input[type=checkbox]").click(function() {
// send my object to server
$.ajax({
type: 'POST',
url: '/results/search_filter',
success: function(response) {
// inject the results
$('#search_results').html(response);
},
data: JSON.stringify({filters: filters})
}); // end ajax setup
});
My PHP controller:
public function search_filter() {
// create an instance of the view
$filtered_results = View::instance('v_results_search_filter');
$filtered_results->filters = $_POST['filters'];
echo $filtered_results;
}
My PHP view:
<?php var_dump($filters);?>
Perhaps I need to use a jsondecode PHP function, but I'm not sure that my object is getting passed in the first place.
IIRC the data attribute of the $.ajax jQuery method accepts json data directly, no need to use JSON.stringify here :
data: {filters: filters}
This way, you're receiving your json data as regular key/value pairs suitable for reading in PHP through the $_POST superglobal array, as you would expect.
http://blog.teamtreehouse.com/beginners-guide-to-ajax-development-with-php
When you use ajax the page is not reloaded so the php variable isn't of use.
You may want to look for a tutorial to help. I put one at the beginning as I don't see how to format this on my tablet
you will need to json_encode your response as the tutorial shows
you may want to print to a log on the server when you are in the php function and make it world readable so you can access it via a browser
I like to use the developer tools in Chrome to see what is actually returned from the server

Accessing JSON values with a variable

I'm trying to access JSON data with jQuery and grab a specific set of values based on a variable. I've done this before using [] but for some reason I can't figure out what is going wrong this time.
My JSON file (being read in by getJSON, and named jsonmaker.php) looks like this:
{"0107001":{"label":"Canada","x":"0","y":"0.34"},"0107002":{"label":"USA","x":"-0.16","y":"0.53"}}
I then have a function which is essentially this:
function addAttrib(attrib) {
$.getJSON("jsonmaker.php", function(data) {
alert(data[attrib].label);
}
}
But it keeps returning undefined. Any idea what I'm doing wrong? I've checked to make sure the var going to attrib is 0107001, no problems there.
Also, I know my JSON file is a php file so I could filter what's returned to match the attrib value, but I'm looking to develop something that can run purely on HTML and JS, so I could just pack the JSON file for the project and take it with me. No need for a web server w/ PHP etc.
The data access itself works for me:
var data = {"0107001":{"label":"Canada","x":"0","y":"0.34"},"0107002":{"label":"USA","x":"-0.16","y":"0.53"}};
var attrib = "0107002";
alert(data[attrib].label); // USA
Make sure that attrib remains untouched between the moment you call addAttrib() and the moment when the AJAX request completes and your anonymous callback function gets called.
Update: is this your real code? You have at least one syntax error:
function addAttrib(attrib) {
$.getJSON("jsonmaker.php", function(data) {
alert(data[attrib].label);
}); // <- Please note missing ");"
}
In my experience, $.getJSON() doesn't always return an object. Depending on the MIME type that the server returns along with the JSON, you might end up with a string instead of an object. Check what data contains. If it's a string, you must manually parse it using eval() (old style) or JSON.parse() (new browsers only).
try to list all properties from data, to have sure the data is being returned:
for (var p in data){
if (data.hasOwnProperty(p){
alert(data[p]);
}
}
It's not your solution but with this you can know how your data is coming.

Categories

Resources