Edit:
Solved using the below suggestion of removing:echo '{"results":'.json_encode($arr).'}';
and replacing with echo json_encode($arr);
This combined with replacing these lines:
var items = [];
$.each(data, function(key, val) {
$.each(val, function(key, val)
{
//Test insert into box using customer number
$("#chatbox").html(val.number);
});
});
with
$.each(data, function(key, val) {
$("#chatbox").html(this.number);
});
Made it work, I can now access the object data using the this followed by the property I want.
End Edit
Hi could anyone help me with these JSON feed. I am almost there with it (I think) however whenever I put this feed into JQuery it is picked us as a string rather than as an array of JSON objects and I can't figure out why.
The PHP to create the feed:
<?php
session_start();
include 'connect.php';
$number = $_SESSION['number'];
$query = "SELECT * FROM $tableName WHERE number='$number'";
$result = mysql_query($query, $sqlCon);
$arr = array();
while($obj = mysql_fetch_object($result)) {
$arr[] = $obj;
}
if (count($arr) == 0)
{
echo "Your reference number is: $number";
} else {
echo '{"results":'.json_encode($arr).'}';
}
?>
The returned JSON looks like this:
{"results":[{"id":"40","number":"466741","message":"dsfdsv","date":"2011-10-05","time":"00:28:32"},{"id":"41","number":"466741","message":"sacsac","date":"2011-10-05","time":"00:30:17"}]}
What I instead want is:
[{"id":"40","number":"466741","message":"dsfdsv","date":"2011-10-05","time":"00:28:32"},{"id":"41","number":"466741","message":"sacsac","date":"2011-10-05","time":"00:30:17"}]
Or a return value which would allow me to iterate over the objects.
The JQuery I'm reading it with:
$.getJSON('get.php', function(data) {
var items = [];
$.each(data, function(key, val) {
$.each(val, function(key, val)
{
//Test insert into box using customer number
$("#chatbox").html(val.number);
});
});
});
I'm guessing my problem is the way in which I'm creating the JSON feed but I'm just stuck and cant figure out how to fix it.
Any help would be appreciated, thanks.
You should set the headers from PHP to specify that it is json content. This isn't 100% required but good practice and you'll see the content-type parsed correctly in tools like firebug.
header('Content-type: application/json');
You are wrapping your json content with a results key that that you aren't looking for in your javascript so you either need to remove that part or look for that your javascript. Since you say you want the array and not the object with the results key/value just replace echo '{"results":'.json_encode($arr).'}'; with echo json_encode($arr);
Related
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"}
}
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 am trying to make an html select list of options update according to a selection made on a prior html select object. My jquery is below. This is being called correctly.
var brandName = $("#Brand").val();
$.get("updateTypes.php?q="+brandName, function(data) {
$("#Type").remove();
var typeData = JSON.parse(data);
for (loop=0; loop < typeData.length; ++loop) {
$("#Type").options.add(new Option(typeData[loop]));
}
});
As I am using a singleton to interface with my mySQL database, this jquery function calls a 'go-between' .php file called updateTypes.php which is below:
include 'databaseInterface.php';
$brand = $_GET["q"];
$typesData = databaseInterface::getBrandTypes($brand);
return $typesData;
This calls the getBrandTypes function in my singleton below:
$query = "SELECT psTypeName FROM types WHERE brands_psBrandName='$BrandName'";
$result = mysqli_query($con, $query) or die ("Couldn't execute query. ".mysqli_error($con));
$resultArray = array();
while ($row = mysqli_fetch_assoc($result)) {
extract($row);
$resultArray[] = $psTypeName;
}
return json_encode($resultArray);
The webpage correctly removes the existing options from the jquery function but fails to update them. It seems to go wrong when I decode the JSON data in the jquery. Why is it going wrong? Is the loop for updating the select object appropriate?
You can use $.getJSON if your expecting a json response. You might also be able to use $.each() and then simply .append() to the select tag. You can reference this.property inside the .each().
Something like the following:
$.getJSON("updateTypes.php?q="+brandName, function(data) {
$("#Type").html('');
$.each(data, function(){
$("#Type").append('<option value="'+ this.value +'">'+ this.name +'</option>')
)
})
This would assume your json response is something like the following:
[ { name : "foo", value : "bar" }, { name : "another", value : "example" } ]
Your code $("#Type").remove(); removes the select object not its options. The correct way of removing options is:
$("#Type option").remove();
or
$("#Type").html('');
The second solution seems to be better as stated here: How to remove options from select element without memory leak?
There is also an error in the part that adds new options. Your javascript code should be:
var brandName = $("#Brand").val();
$.get("updateTypes.php?q="+brandName, function(data) {
$("#Type option").remove();
var typeData = JSON.parse(data);
for (loop=0; loop < typeData.length; loop++) {
$("#Type").get(0).options.add(new Option(typeData[loop]));
}
});
The $('#Type').get(0) method refers to the raw DOM object which has the "options" property that you wanted to use (How to get a DOM Element from a JQuery Selector)
I'm building a search function to retrieve XML data for a google map.
In addition to that, I want to display how many results were actually found.
I thought about doing an echo inside the actual document, however that might mess with my marker data. How would I take a PHP variable and retrieve it in Jquery after a success call?
If my PHP looked like this:
$result = mysql_query($query);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
$num_rows = mysql_num_rows($result);
And Jquery like this:
$.ajax({
type: "POST",
url: "MapSearchxml.php",
data: {
dataFromDate: FromDate,
//lalala
dataHasPatio: HasPatio
},
beforeSend: function (html) { // this happens before actual call
$("#results").html('Please Wait');
$("#searchresults").show();
$(".phpFromDate").html(FromDate);
},
success: function (data, status, jqXHR) {
//Success?
},
dataType: 'xml'
});
Might find it easier to create array in php and send JSON. At client is easy to loop over response object/array
$output=array('status'=>'', 'results'=>array());
$result = mysql_query($query);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
$num_rows = mysql_num_rows($result);
if( $num_rows){
$output['status']='ok';
/* push row data to $output['results'][]; in while loop*/
}else{
$output['status']= 'No results';
}
echo json_encode( $output);
Then in jQuery:
success:function( data){
if (data.status != 'No results' ){
/* count array length*/
var count= data.results.length;
/* loop over data.results array*/
}
}
/* change dataType to "json"*/
I forgot about count and added it in jQuery...can also add a count property to the $output php array and use $num_rows to populate
Just trying out a JSON example for you, this has echo but you can do complex things with it?
Not sure if that is what your after? I get that you don't want to do echo on each variable, and you wont if using JSON.
<?php
$simple = 'simple string';
$complex = array('more', 'complex', 'object', array('foo', 'bar'));
?>
<script type="text/javascript">
var simple = '<?php echo $simple; ?>';
var complex = <?php echo json_encode($complex); ?>;
</script>
You see, what AJAX gets on success is an html code. If you AJAX a complete html page you will get it back, starting with <html> and ending with </html>. You can just make a special markap on your return html data, like [sepcial_info : 'INFO'] or somthing and then just to filter it.
Okay, I needed a bit to decipher your question, probably I'm still wrong, let's try:
What you try to do is not technically possible with what you have in mind. In short: If you do one Ajax request, you return one response. The moment the success function is called, your PHP script is already gone. So you can only pass one return value.
However what you can do is, that you make that return value a nested one, e.g. containing two parts:
The XML document you already returned
The count
That is probably your solution. If you ask how, I would add the count as a namespaced value to the XML and then process it with javascript.
As you have not shown any code here, I can not give a quick example (and I leave that as a pointer for your future questions) for your case. Add a namespace element, like an attribute is pretty simple with DOMDocument in PHP.
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(''));