I'm trying to use PHP and jQuery to create a dynamic search results page.
On the PHP side, a SELECT statement is called, where I check if all variables are set, add my HTML that I want to be used clientside, then put the variables in an array named $result.
Of the results of the database call, I also add the longitude and latitude in their own array, named $pins.
I then create a multidimensional array called $results, and put the array together like so:
$result = array('listing'=>$listing);
$pins = array('lat'=>$lat1,'lng'=>$lon2);
$results = array('listing'=>$result,'pins'=>$pins);
echo json_encode($results);
Now, clientside I use jquery. The issue I'm facing, is there should be 2 results in total. However I see the same result repeated twice (I can confirm they should be unique). Here is my jQuery:
$.ajax({
url: '/updatedsearch.php',
type: 'POST',
data: {
q: search,
lng: coordinates[0],
lat: coordinates[1],
},
dataType: "json",
success: function(data) {
if(data == "undefined" || data == null) {
console.log("There was no search results or something similar");
} else {
var pins = [data.pins.lat, data.pins.lng];
$.each(data, function(key, val) {
$('#listings').append(data.listing.listing);
console.log(pins);
console.log(data);
});
}
},
Everything here works as it should, apart from when $.each() runs, it appears to be appending the same data twice.
I assume it's because of .append(data.listing.listing);, if I understand correctly I'm not looping through the array here, I'm effectively referencing data.listing.listing[0] - have I understood this correctly?
Edit: I now have an issue with my results appearing twice. There should be only two results, however there are four in total, it appears as though these have been duplicated.
{"listing":["<div>This contains my HTML</div>"], "pins":"lat":"50.000000","lng":"-1.000000"}}
I have run this though jsonlint and it appears invalid. Using PHP I have created this data as follows:
while($listrow = mysqli_fetch_assoc($list)) {
$listing[] = '<div>This contains my HTML</div>';
}
$pins = array("lat"=>$lat1, "lng"=>$lon2);
$results = array('listing'=>$listing, 'pins'=>$pins);
echo json_encode($results);
Have I misunderstood using multidimensional arrays, which is causing the error?
You are correct that you are not looping through the array. You are also not referencing the individual array items when you append.
Try:
$.each(data.listing.listing, function(i, item) {
$('#listings').append(item);
});
When you do the following:
$.each(data, function(key, val) {
You are looping through the properties of the data object. It has two properties: listings and pins, so the loop executes twice.
And for each iteration of the loop, you are appending the same value (data.listing.listing), which I assume is an array.
Instead, I think you want to iterate over the array, and append each item in the array.
EDIT: The PHP you show at the top of your question looks like it would generate JSON like this:
{
"listing": { "listing": ["<div>This contains my HTML</div>"] },
"pins": { "lat":"50.000000","lng":"-1.000000" }
}
But with your edit, you show JSON that looks like this:
{
"listing": ["<div>This contains my HTML</div>"],
"pins": { "lat":"50.000000","lng":"-1.000000" }
}
If that is what your JSON looks like, you should use:
$.each(data.listing, function(i, item) {
jsfiddle
It appears that you intend your $.each to loop through the listings placed in $results['listing'] in your PHP, but it's actually looping over the whole $results.
To better see what's going on, use a different name for the current item in your $.each. Because you use data, the same name you use as the argument of your success callback, you're making the code harder to debug. If you want to cycle through your listings, do the following inside the success callback:
$.each(data.listing, function(i, result)){
$('#listings').append(result);
}
The JSON you posted:
{
"listing":["<div>This contains my HTML</div>"],
"pins": "lat":"50.000000","lng":"-1.000000"}
}
Is invalid because you're missing an opening bracket between "pins": and "lat". It should be
{
"listing":["<div>This contains my HTML</div>"],
"pins": {"lat":"50.000000","lng":"-1.000000"}
}
Related
I have search results generated by a 3rd party script that I would like to add data to. I have parsed the results to get an array of id's, and queried the database for additional fields. The ajax success method receives the formatted array back, but now I'm stuck on how to get those results into the right place in the DOM.
The HTML:
<div class="ihf-results-property-info">
<div class="ihf-results-price">LIST: $2,150,000</div>
<div class="ihf-results-links"> 24 Photos
</div>
<div class="ihf-results-extra-info">
<div class="ihf-results-listingnum hidden-xs">Listing # 727938</div>
</div>
Repeat...
The last div I included in the example has the unique ID I'm using for the query. I'd like to use that to associate the ajax return with proper placement in the DOM. Here is my javascript:
jQuery(document).ready(function($) {
// grab the listings numbers so we can query the db for extra data
var listings = $('.ihf-results-listingnum').map(function() {
// grab just the digits
var listingNum = $(this).text().replace(/[^0-9]/g, '');
// add the listing number to the parent so we can target it later
$( this ).parents('.ihf-results-extra-info').parent().addClass('marketing-details-' + listingNum);
return listingNum;
// use .get to create an array of the listing numbers
}).get();
$.ajax({
type: "GET",
url: "custom/07-idx-queries.php",
data: 'mlsNums=' + listings, // looks like ?mlsNums=735383,727468,699876...
success: function(result) {
// this logic came from here: http://stackoverflow.com/questions/15311320/how-to-work-with-jquery-ajax-and-php-array-return
resultJson = $.parseJSON(result);
if (typeof resultJson == 'object') {
jsObject = eval(resultJson);
jsArray = [];
for(elem in jsObject){
jsArray.push(jsObject[elem]);
}
console.log(jsArray);
// this works as expected, except keys are 0 based
// This is where it all falls apart. I want to extract each object and stick it in the DOM in the correct place
jQuery.each(jsArray, function(key, value) {
$( this ).appendTo('.marketing-details-' + key);
});
}
else {
console.log("error occurred");
}
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
})
});
And the php I'm using produces the desired results from the db, with the exception that it is a numerical array. I think an associative array would work better when trying to put the results into the DOM, tha way I could use the ID's as the key and match them to the classes I added. Here is the relevant code from custom/07-idx-queries.php:
$mls_nums = explode(",",$_GET['mlsNums']);
// removed all of the conditionals to keep the question clean
$html = array();
foreach ($mls_nums as $mls_num) {
// just retreiving a single object from each row for now
$remarks = $mysqli->query("SELECT mr FROM listings WHERE ln = '$mls_num'")->fetch_object()->mr;
// format the data
$my_html = "<p class='marketing-remarks mlsnum-".$mls_num."'>$remarks</p>";
// build an array of the results - necessary?
array_push($html,$my_html);
}
// send the data back in a JSON string
echo json_encode($html);
So my goal is to query the db for up to 10 rows, and insert the results into an equal number of new divs that are children to a div with the same id number in its class. I greatly appreciate any help.
In your PHP do this:
$html[$mls_num] = $my_html;
// this isn't needed
// array_push($html,$my_html);
Now your returned data has a way to tie into the target div.
Not clear if you have control over the HTML in the first part of your example, but this would be one approach.
<div class="ihf-results-listingnum hidden-xs">Listing # 727938</div>
<div class="remarks" id="remarks_<?= $listingid; ?>"></div>
Then in the JavaScript $("#remarks_" + key).html(value);
Otherwise, you need to use jQuery to locate the div with the listing id using the :contains selector:
$("div:contains('# " + key + "')").appendTo(value);
'# " + key + "' would equate to # 1234 or whatever it is. This won't work if the same listing is on the page twice though!
Okay, here is the working success method. Thanks to LG_PDX for the cleaned up php. I eliminated the unnecessary processing as .each() appears to iterate just fine over the JSON response:
success: function(result) {
resultJson = $.parseJSON(result);
if (typeof resultJson == 'object') {
$.each(resultJson, function(key, value) {
$('.marketing-details-' + key).append( value );
});
}
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
I have posted a question about How to alert a php array in ajax success function in this post: How to alert a php array in ajax success function
I got the answer to use alert(JSON.stringify(result[0])); but this will give me access to the first row of the array while i need to have access to each element of each row. imagine that my array is like this now
[0]1>>>>2>>>>>3>>>>>5>>>>>6
[1]1>>>>2>>>>>3>>>>>5>>>>>6
[2]1>>>>2>>>>>3>>>>>5>>>>>6
[3]1>>>>2>>>>>3>>>>>5>>>>>6
[4]1>>>>2>>>>>3>>>>>5>>>>>6
[5]1>>>>2>>>>>3>>>>>5>>>>>6
alert(JSON.stringify(result[0])) will give me only [0]1>>>>2>>>>>3>>>>>5>>>>>6 but I want to alert 5 only, I have tried alert(JSON.stringify(result[0][3])) but no luck.
Could you tell me how to have access to 2d array elements using JSON.stringify? Or is there any other way than JSON.stringify(result[0]
Here is the ajax function :
$.ajax({
type: 'POST',
url: "profile/ajax/getorder.php",
data: {id:gotid},
dataType: 'json',
cache: false,
success: function(result) {
alert(JSON.stringify(result[0]))
},
});
here is the php
$ent = $_POST['id'];
$column = array();
$gtord = mysql_query("SELECT * FROM order WHERE oId = '$ent' ");
while($rowmnu2=mysql_fetch_array($gtord))
{
$column[] = $rowmnu2;
}
echo json_encode($column);
Appreciated.
The json.stringify method simply gets the array in a text format that can be sent to alert. If you are only looking at a single value that isn't an array, you don't need it. Just alert(result[0][3]).
After getting more info:
To access a whole row, use JSON.stringify(result[0]), to look at a specific element use result[0]['user_id']. If you want to use numbers to look at the specific elements, use mysql_fetch_row instead of mysql_fetch_assoc. Hope that helps.
So I have got to a stage in my website where I need to pack a lot of information into a single json array like object, so in order to do this I need to pack a list of array information under a certain key name, then another set of data under another key name.
So for example:
$array = array();
foreach(action goes here)
{
$array['data1'] = array('information' => data, 'more_information' => more_data)
}
$array['data2'] = array("more data");
This basically illustrates what I am trying to do, I am able to partially do this, however naming the key for the new data set only replaces each data, instead of adding into it in the foreach loops.
Now if this part isn't too confusing, I need some help with this. Then in addition to this, once this is sorted out, I need to be able to use the data in my jQuery response, so I need to be able to access each set of data something like: json.data1[i++].data, which would ideally return "more_information".
You need an incremental number in that loop and make the results available as a json object...
$array = array();
$i = 0;
foreach(action goes here)
{
$array['data'.$i] = array('information' => data, 'more_information' => more_data)
$i++;
}
$array['data2'] = array("more data");
$data = json_encode($array);
Then in php you might set a js var like so:
<script type="text/javascript">
var data = <?php echo $data; ?>;
</script>
which could then be accessed in js easily:
alert(data.data1.information);
If I understand your question correctly you expect to get this object as a response to something? Like a jQuery .ajax call?
http://api.jquery.com/jQuery.ajax/
This link illustrates how to use it pretty clearly. You would want to make sure to specify dataType = "json" and then place your data handling in the success call:
$.ajax({
url: 'some url string',
type: "GET",
dataType: "json",
success: function(data)
{
$.each(data, function(i, v){
console.log(data[i]);
});
},
error: function()
{
//error handling
}
});
This is relatively untested, but the concept is what I am trying to convey. You basically make your multi-dimensional array in php and json_encode it. Either of these methods will allow you to parse the json.
I attempt to fill a drop down from a database. I query and add my result to an array. I then use json_encode to send my data to a php file.
$query="SELECT project FROM main";
$results = $db->query($query);
while ($row_id = $results->fetchArray()) {
$proj_option[] = "<option value=\"".$row_id['project']."\">".$row_id['project']."</option>\n";
$pselected=$row_id['project'];
}
$output = array( "proj" => $proj_option);
echo json_encode($output);
In my php file, I use jquery ajax to fill the drop down.
$("#turninId").change(function() {
var user_id = $("#turninId").val();
$.ajax ( {
url:"send_input.php",
type: "POST",
dataType: "json",
data:{id_selection: user_id},
success:function(response) {
for (var i=0; i<response.proj.length; i++) {
$("#exp").html(response.proj[i]);
$("#project").html(response.proj[i]); } });
});
This is great, BUT the only item in my drop down is the last item in the db. For example, my database has the following under Project:
Project: up, down, low, right
But my drop down only fills with the last entry, "right." Why is this? How can I fix it?
PHP json_encode() in while loop was similar, and I made the changes, but there is something missing here.
may be try this
success:function(response) {
$.each(response.proj,function(key,value){
$("#exp").append(value);
$("#project").append(value);
});
}
each time thru your loop in javascript you are overwriting your html. The .html() method sets the innerHTML property of the tag, so each time you call it you are resetting the html and only the last one will show. try not using a loop, instead join you response together and then call .html()
$("#exp").html(response.proj.join(''));
$("#project").html(response.proj.join(''));
I'm trying to use jQuery.post() function to retrieve some data. But
i get no output.
I have a HTML that displays a table. Clicking this table should trigger a jQuery.post event.
My scriptfile looks like this:
jQuery(document).ready(function() {
jQuery('#storeListTable tr').click(function() {
var storeID = this.cells[0].innerHTML; //This gets me the rowID for the DB call.
jQuery.post("../functions.php", { storeID: "storeID" },
function(data){
alert(data.name); // To test if I get any output
}, "json");
});
});
My PHP file looks like this:
<?php
inlcude_once('dal.php');
//Get store data, and ouput it as JSON.
function getStoreInformation($storeID)
{
$storeID = "9";//$_GET["storeID"];
$sl = new storeLocator();
$result = $sl->getStoreData($storeID);
while ($row = mysql_fetch_assoc($result)) {
{
$arr[] = $row;
}
$storeData = json_encode($arr);
echo $storeData; //Output JSON data
}
?>
I have tested the PHP file, and it outputs the data in JSON format. My only problem now is to return this data to my javascript.
since the javascript is located in the /js/ folder, is it correct to call the php file by using '../'?
I don't think I'm passing the storeID parameter correctly. What is the right way?
How can I call the getStoreInformation($storeID) function and pass on the parameter? The jQuery example on jQuery.com has the following line: $.post("test.php", { func: "getNameAndTime" }
Is the getNameAndTime the name of the function in test.php ?
I have gotten one step further.
I have moved the code from inside the function(), to outside. So now the php code is run when the file is executed.
My js script now looks like this:
jQuery('#storeListTable tr').click(function() {
var storeID = this.cells[0].innerHTML;
jQuery.post("get_storeData.php", { sID: storeID },
function(data){
alert(data);
}, "text");
});
This results in an alert window which ouputs the store data as string in JSON format.
(because I have changed "json" to "text").
The JSON string looks like this:
[{"id":"9","name":"Brandstad Byporten","street1":"Jernbanetorget","street2":null,"zipcode":"0154","city":"Oslo","phone":"23362011","fax":"22178889","www":"http:\/\/www.brandstad.no","email":"bs.byporten#brandstad.no","opening_hours":"Man-Fre 10-21, L","active":"pending"}]
Now, what I really want, is to ouput the data from JSON.
So I would change "text" to "json" and "alert(data)" to "alert(data.name)".
So now my js script will look like this:
jQuery('#storeListTable tr').click(function() {
var storeID = this.cells[0].innerHTML;
jQuery.post("get_storeData.php", { sID: storeID },
function(data){
alert(data.name);
}, "json");
});
Unfortunately, the only output I get, is "Undefined".
And if I change "alert(data.name);" to "alert(data);", the output is "[object Object]".
So how do I output the name of teh store?
In the PHP file, I've tried setting $storeID = $_GET["sID"]; But I don't et the value. How can I get the value that is passed as paramter in jQuery.post ?
(currently I have hardcoded the storeID, for testing)
Lose the quotes around "storeID":
Wrong:
jQuery.post("../functions.php", { storeID: "storeID" }
Right:
jQuery.post("../functions.php", { storeID: storeID }
bartclaeys is correct. As it is right now, you are literally passing the string "storeID" as the store ID.
However, a couple more notes:
It might seem weird that you will be setting storeID: storeID - why is only the second one being evaluated? When I first started I had to triple check everytime that I wasn't sending "1:1" or something. However, keys aren't evaluated when you are using object notation like that, so only the second one will be the actual variable value.
No, it is not correct that you are calling the PHP file as ../ thinking of the JS file's location. You have to call it in respect of whatever page has this javascript loaded. So if the page is actually in the same directory as the PHP file you are calling, you might want to fix that to point to the right place.
Kind of tied to the previous points, you really want to get your hands on Firebug. This will allow you to see AJAX requests when they are sent, if they successfully make it, what data is being sent to them, and what data is being sent back. It is, put simply, the consensus tool of choice to debug your Javascript/AJAX application, and you should have it, use it, and cherish it if you don't want to waste another 6 days debugging a silly mistake. :)
EDIT As far as your reply, if you break down what you are returning:
[
{
"id":"9",
"name":"Brandstad Byporten",
"street1":"Jernbanetorget",
"street2":null,
"zipcode":"0154",
"city":"Oslo",
"phone":"23362011",
"fax":"22178889",
"www":"http:\\/www.brandstad.no",
"email":"bs.byporten#brandstad.no",
"opening_hours":"Man-Fre 10-21, L",
"active":"pending"
}
]
This is actually an array (the square brackets) containing a single object (the curly braces).
So when you try doing:
alert(data.name);
This is not correct because the object resides as the first element of the array.
alert(data[0].name);
Should work as you expect.
Your JSON is returned as a javascript array... with [] wrapping the curly bits [{}]
so this would work.
wrong: alert(data.name);
right: alert(data[0].name);
Hope that helps.
D
Ok, thanks to Darryl, I found the answer.
So here is the functional code for anyone who is wondering about this:
javascript file
jQuery(document).ready(function() {
jQuery('#storeListTable tr').click(function() {
jQuery.post("get_storeData.php", { storeID: this.cells[0].innerHTML }, // this.cells[0].innerHTML is the content ofthe first cell in selected table row
function(data){
alert(data[0].name);
}, "json");
});
});
get_storeData.php
<?php
include_once('dal.php');
$storeID = $_POST['storeID']; //Get storeID from jQuery.post parameter
$sl = new storeLocator();
$result = $sl->getStoreData($storeID); //returns dataset from MySQL (SELECT * from MyTale)
while ($row = mysql_fetch_array($result))
{
$data[] = array(
"id"=>($row['id']) ,
"name"=>($row['name']));
}
$storeData = json_encode($data);
echo $storeData;
?>
Thanks for all your help guys!