returning JSON and HTML from PHP script - php

Hi searched through the questions here, but couldn't find anything. I'm new at writing PHP and jQuery, so bear with me.
What I'm trying to do is send an ajax request using jQuery to my script which runs a mysql query on data from my database and serializes it into the JSON format using php's json_encode. The response is then parsed with the available json2.js script. All of this works fine, but I'd also like to return more data other than just JSON from this script.
mainly, i'd like to also echo the following line before the json_encode:
echo "<h1 style='margin-left: 25px;'>$num_rows Comments for $mysql_table</h1>";
however, my jQuery is evaluating the entire response during the ajax success, making the json.parse function fail due to the script's return being in an invalid format.
success: function(data) {
//retrieve comments to display on page by parsing them to a JSON object
var obj = JSON.parse(data);
//loop through all items in the JSON array
for (var x = 0; x < obj.length; x++) {
//Create a container for the new element
var div = $("<div>").addClass("bubble").appendTo("#comments");
//Add author name and comment to container
var blockquote = $("<blockquote>").appendTo(div);
$("<p>").text(obj[x].comment).appendTo(blockquote);
var cite = $("<cite>").appendTo(div);
$("<strong>").text(obj[x].name).appendTo(cite);
$("<i>").text(obj[x].datetime).appendTo(cite);
}
$("#db").attr("value", '' + initialComments + '');
}
does anyone know how i can return the html line as well as the json_encode to use this script for more than just json population?
thankyou, this website has been wonderful in answering my noob questions.
my php:`
for ($x = 0, $numrows = mysql_num_rows($result); $x < $numrows; $x++) {
$row = mysql_fetch_assoc($result);
$comments[$x] = array("name" => stripslashes($row["name"]), "comment" => stripslashes($row["comment"]), "datetime" => date("m/d/Y g:i A", strtotime($comment['datetime'])));
}
//echo "<h1 style='margin-left: 25px;'>$num_rows Comments for $mysql_table</h1>";
$response = json_encode($comments);
echo $response;`

Don't echo the line, save it in a variable. Construct a simple array
$response = array(
'html' => $the_line_you_wanted_to_echo,
'jsobject' => $the_object_you_were_going_to_send_back
); and send that back ( via json_encode ) instead.
Also, you don't need json2.js, jQuery has an excellent JSON parser.
you can load like this $.get( 'your/url', { params : here }, success, 'JSON' );
Changed to match your newly introduced iteration.
for ($x = 0, $num_rows = mysql_num_rows($result); $x < $num_rows; $x++) {
$row = mysql_fetch_assoc($result);
$comments[$x] = array(
"name" => stripslashes($row["name"]),
"comment" => stripslashes($row["comment"]),
"datetime" => date("m/d/Y g:i A", strtotime($comment['datetime']))
);
}
$html = "<h1 style='margin-left: 25px;'>$num_rows Comments for $mysql_table</h1>";
echo json_encode(array( 'comments' => $comments, 'html' => $html ));
then, in your javascript, you have
function success( parsedObject ){
parsedObject.html; // "<h1 style..."
parsedObject.comments; // an array of objects
parsedObject.comments[0].name
+ " on " + parsedObject.comments[0].datetime
+ " said \n" + parsedObject.comments[0].comment; // for example
}

As said above just put all the data you want to get back in an array and encode that.
<?php
echo json_encode(array(
'html' => $html,
'foo' => $bar,
'bar' => $baz
));
?>
Also as said you don't need json2.js. You can parse JSON data with any of jQuery's ajax functions by specifying the data type as json.
$.ajax({
type: 'POST',
url: 'path/to/php/script.php',
dataType: 'json',
data: 'foo=bar&baz=whatever',
success: function($data) {
var html = $data.html;
var foo = $data.foo;
var bar = $data.bar;
// Do whatever.
}
});
EDIT Pretty much what Horia said. The only other variation I could see is if you wanted everything in the same array.
For example:
PHP:
<?php
// You have your comment array sent up as you want as $comments
// Then just prepend the HTML string onto the beginning of your comments array.
// So now $comments[0] is your HTML string and everything past that is your comments.
$comments = array_unshift($comments, $your_html_string);
echo json_encode($comments);
?>
jQuery:
$.ajax({
type: 'POST',
url: 'path/to/php/script.php',
dataType: 'json',
data: 'foo=bar&baz=whatever',
success: function($comments) {
// Here's your html string.
var html = $comments[0];
// Make sure to start at 1 or you're going to get your HTML string twice.
// You could also skip storing it above, start at 0, and add a bit to the for loop:
// if x == 0 then print the HTML string else print comments.
for (var x = 1; x < $comments.length; x++) {
// Do what you want with your comments.
// Accessed like so:
var name = $comments[x].name;
var comment = $comments[x].comment;
var datetime = $comments[x].datetime;
}
}
});

You might be interested in jLinq, a Javascript library that allows you to query Javascript objects. A sample query would be:
var results = jLinq.from(data.users)
.startsWith("first", "a")
.orEndsWith("y")
.orderBy("admin", "age")
.select();
jLinq supports querying nested objects and performing joins. For example:
var results = jLinq.from(data.users)
.join(data.locations, //the source array
"location", //the alias to use (when joined)
"locationId", // the location id for the user
"id" // the id for the location
)
.select(function(r) {
return {
fullname:r.first + " " + r.last,
city:r.location.city,
state:r.location.state
};
});

Related

php how to return JSON for jQuery .get() or .post() request, parse it and output to browser

Edit:
I can output the table now but the strange thing is, trying to parse the JSON returned from PHP using JS or jQuery methods results in skipping all remaining lines in the debugger with zero output to the browser. Where as not parsing and using it to construct at table works.
Also, trying to .append() the JSON using the parse methods or not to a ` does not work.
I'm so confused right now.
Anyways, the jQuery that worked looks like this making a .post() request, notice I added the 'json' fourth parameter although it might work without it.
$(document).ready(function(){
$('#disease_btn').click(function(){
showDisease();
});
});
function showDisease(){
//var disease = $("#disease-dropdown:selected").text();
//var disease = $("#disease-dropdown:selected").val();
var disease_dropdown = document.getElementById("disease-dropdown")
var disease = disease_dropdown.options[disease_dropdown.selectedIndex].text;
var controller = 'controller.php';
$.post(controller, //url, data, callback, dataype=Json
{
page: 'SpaPage',
command: 'search-disease',
search_term: disease
},
function(disease_json, status){
//#search-results display table
//var disease_obj = JSON.parse(disease_json); this did not work
//var disease_obj = jQuery.parseJSON(disease_json); //this did not work
var disease_obj = disease_json;
//$('#test-out').append(disease_obj); /this did not work
var table = $.makeTable(disease_obj);
$('#search-results').append(table); //this worked!
}, 'json');
//https://stackoverflow.com/a/27814032/13865853
$.makeTable = function(disease_obj){
var table = $('<table border=1>');
var tblHeader = "<tr>";
for (var h in disease_obj[0]) tblHeader += "<th>" + h + "</th>";
$(tblHeader).appendTo(table);
$.each(disease_obj, function(index, value){
var tblRows = "<tr>";
$.each(value, function (key, val){
tblRows += "<td>" + val + "</td>";
});
tblRows += "</tr>";
$(table).append(tblRows);
});
return ($(table));
}
};
That table code I mimicked what I saw here: https://stackoverflow.com/a/27814032/13865853
I sort of get it but still not crystal clear on all of it. I guess it's outputting HTML so I can throw in a class for the table to take advantage of bootstrap.
On the PHP side I do this:
case 'search-disease':
$matches_arr = [];
$disease = $_POST['search_term'];
$matches_arr = search_disease($disease);
//todo: decide to use session or returned arr
if(isset($_SESSION['disease-matches_arr'])){
$matches_arr = $_SESSION['disease-matches_arr'];
}
if(count($matches_arr) > 0) {
//jsonify array here to send back
//https://stackoverflow.com/a/7064478/13865853
//https://stackoverflow.com/a/58133952/13865853
header('Content-Type: application/json');
$disease_json = json_encode($matches_arr);
echo $disease_json;
exit;
}
and then the model.php interaction with database looks like this:
function search_disease($disease_option){
// search DB for substring of question
//add results to an array of strings
//return array of strings or empty array
//
$user_id = -1;
$matches_arr = array();
$sql = "SELECT * FROM diseases
WHERE disease LIKE '%$disease_option%'";
$result = mysqli_query(Db::$conn, $sql);
if (mysqli_num_rows($result) > 0) {
//iterate
while($row = mysqli_fetch_assoc($result)){
//get username
$disease = $row['disease'];
$food = $row['food'];
$en_name = $row['en_name'];
$health_effect = $row['healthEffect'];
$metabollite = $row['metabollite'];
$citation = $row['citation'];
$next_row = array("Disease"=>$disease, "Food"=>$food,
"Name"=>$en_name, "Health Benefits"=>$health_effect, "Metabollite"=>$metabollite,
"Sources"=>$citation);
$matches_arr[] = $next_row;
}
}
$_SESSION['disease-matches_arr'] = $matches_arr;
return $matches_arr;
//https://stackoverflow.com/questions/1548159/php-how-to-sen
So I set a session variable and also return it, still have to decide which way but they are both working.
My questions still remaining are:
Why do the parse methods cause this strange behavior?
How can I just output the JSON to a testing <div>?
If you have to return data from PHP to javascript you must have use json_encode() if data type is array otherwise just return.
To take action with array type data by javascript you have to decode this json data by JSON.parse() function.
Array example
$data = array('carname' => 'TOYOTA','model'=>'ARTYIR500');
echo json_encode($data);
exit;
String example
echo 'lorem ipsum is a simple text';
exit;

returned ajax query data undefined

Hello I am attempting to create an ajax query but when my results are returned I get Undefined as a response. Except for the object called "hello" which returns back as "h" even though it is set to "hello". I have a feeling it has something to do with the way ajax is sending the data but i'm lost as to what may be the issue. Any help would be greatly appreciated.
here is the ajax
function doSearch() {
var emailSearchText = $('#email').val();
var keyCardSearchText = $('#keyCard').val();
var userNameSearchText = $('#userName').val();
var pinSearchText = $('#pin').val();
var passwordSearchText = $('#password').val();
$.ajax({
url: 'process.php',
type: 'POST',
data: {
"hello": "hello",
"emailtext": "emailSearchText",
"keycardtext": "keyCardSearchText",
"usernametext": "userNameSearchText",
"pinText": "pinSearchText",
"passwordtext": "passwordSearchText"
},
dataType: "json",
success: function (data) {
alert(data.msg);
var mydata = data.data_db;
alert(mydata[0]);
}
});
}
Then here is the php
include_once('connection.php');
if(isset($_POST['hello'])) {
$hello = $_POST['hello'];
$emailSearchText = mysql_real_escape_string($_POST['emailSearchText']);
$keyCardSearchText = mysql_real_escape_string($_POST['keyCardSearchText']);
$userNameSearchText = mysql_real_escape_string($_POST['userNameSearchText']);
$pinSearchText = mysql_real_escape_string($_POST['pinSearchText']);
$passwordSearchText = mysql_real_escape_string($_POST['passwordSearchText']);
$query = "SELECT * FROM Students WHERE (`User name`='$userNameSearchText' OR `Email`='$emailSearchText' OR `Key Card`='$keyCardSearchText')AND(`Password`='$passwordSearchText'OR `Pin`='$pinSearchText')";
$students = mysql_query($query);
$count = (int) mysql_num_rows($students);
$data = array();
while($student = mysql_fetch_assoc($students)) {
$data[0] = $student['First Name'];
$data[1] = $student['Last Name'];
$data[2] = $student['Date of last class'];
$data[3] = $student['Time of last class'];
$data[4] = $student['Teacher of last class'];
$data[5] = $student['Membership Type'];
$data[6] = $student['Membership Expiration Date'];
$data[7] = $student['Free Vouchers'];
$data[8] = $student['Classes Attended'];
$data[9] = $student['Classes From Pack Remaining'];
$data[10] = $student['5 Class Packs Purchased'];
$data[11] = $student['10 Class Packs Purchased'];
$data[12] = $student['Basic Memberships Purchased'];
$data[13] = $student['Unlimited Memberships Purchased'];
$data[14] = $student['Groupon Purchased'];
};
echo json_encode(array("data_db"=>$data, "msg" => "Ajax connected. The students table consist ".$count." rows data", "success" => true));
};
Your PHP script is likely producing error messages because the $_POST values you are trying to access don't match the key names you are sending in the request. For example: $_POST['emailSearchText'], yet you used emailtext in the AJAX call.
This is most likely causing jQuery to not be able to parse the response as JSON, hence the Undefined.
First of all, you have to remove the quotes or you will be passing those literals instead of the variables.
$.ajax({
...
data: {
hello: "hello",
emailtext: emailSearchText,
keycardtext: keyCardSearchText,
usernametext: userNameSearchText,
pinText: pinSearchText,
passwordtext: passwordSearchText
},
...
});
And then, like ashicus point out, in your PHP file:
$emailSearchText = mysql_real_escape_string($_POST['emailtext']);
$keyCardSearchText = mysql_real_escape_string($_POST['keycardtext']);
$userNameSearchText = mysql_real_escape_string($_POST['usernametext']);
$pinSearchText = mysql_real_escape_string($_POST['pinText']);
$passwordSearchText = mysql_real_escape_string($_POST['passwordtext']);
JS file looks ok, so this few clues to check PHP file.
See if there are even POST params there (printr all $_POST in php)
Check if your even enters IF. Add an else statement and echo some dummy json.
Check what is actually in encoded json that is echoed. Assign it to var then print.

can't set variable in JavaScript based on json id from php

I have a simple array from a php file (the reason for not using a json file is cause this info comes from a mysql database)
$array[0] = array('id' => 1,'price' => '325');
$array[1] = array('id' => 2,'price' => '486');
header('Content-type: application/json');
echo json_encode($array);
and it echos as:
[{"id":1,"price":"325"},{"id":2,"price":"486"}]
now what I want to do is take the id and add it to a variable called counterval so that JavaScript will read it as
counterval1 = 325;
counterval2 = 486;
but I can't seem to get it to read that way. Here is the script at the current moment.
$.getJSON('test.php',function(data) {
$.each(data, function(i) {
counterval + data[i].id = data[i].price;
console.log (counterval2);
});
$('#results').html(counterval2);
});
var counterval1 = 0;
var counterval2 = 0;
any help on this would be greatly appreciated.
you can't do that... but you can do this...
var counterval = [];
$.getJSON('test.php',function(data) {
$.each(data, function(i) {
counterval[data[i].id] = data[i].price;
console.log (counterval[2]);
});
$('#results').html(counterval[2]);
});
counterval[1] = 0;
counterval[2] = 0;
See my comment on your post. If you really want the vars to look like you explained:
eval("counterval" + data[i].id + " = data[i]..price");
alert(counterval1);

jquery autcomplete returning source array

I'm using jquery's ajax function to fetch data from an external php file. The data that is returned from the php file will be used for the autocomplete function. But, instead of the autocomplete function suggesting each particular value from the array in the php file, it returns ALL of them. My jquery looks like this.
jQuery('input[name=past_team]:radio').click(function(){
$('#shadow').fadeIn('slow');
$('#year').fadeIn('slow');
var year = $('#year').val();
$('#year').change(function () {
$('#shadow').val('');
$.ajax({
type: "POST",
url: "links.php",
data: ({
year: year,
type: "past_team"
}),
success: function(data)
{
var data = [data];
$("#shadow").autocomplete({
source: data
});
}
});
});
});
The link.php file looks like this:
<?php
session_start();
require_once("functions.php");
connect();
$type = $_POST['type'];
$year = $_POST['year'];
if($type == "past_team")
{
$funk = mysql_query("SELECT * FROM past_season_team_articles WHERE year = '".$year."'")or die(mysql_error());
$count = mysql_num_rows($funk);
$i = 0;
while($row = mysql_fetch_assoc($funk))
{
$name[$i] = $row['team'];
$i++;
}
$data = "";
for($i=0;$i<$count;$i++)
{
if($i != ($count-1))
{
$data .= '"'.$name[$i].'", ';
} else
{
$data .= '"'.$name[$i].'"';
}
}
echo $data;
}
?>
The autocomplete works. But, it's just that when I begin to enter something in the input field, the suggestion that are loaded is the entire array. I'll get "Chicago Cubs", "Boston Red Sox", "Atlanta Braves", .....
Use i.e. Json to render your output in the php script.
ATM it's not parsed by javascript only concaternated with "," to a single array element. I do not think that's what you want. Also pay attention to the required datastructure of data.
For a working example (on the Client Side see the Remote JSONP example http://jqueryui.com/demos/autocomplete/#remote-jsonp )

Jquery autocomplete - strip tags to enter into input

I have the following jquery autocomplete code which works perfectly:
$("#autoc1").autocomplete("/autoc2.php?arg=1&category=<? echo $category_id; ?>", {
width: 400,
matchContains: true,
minChars: 3,
selectFirst: false
});
I format the data using PHP to show an image in the automplete, for a better more informative UI for the user, the PHP code is:
$query = "SELECT $title, imageURL FROM PRprodINFO2 WHERE ((prodcatID = '$cat_id')
AND ($title LIKE \"%" . $_GET["q"] . "%\")) group by $title LIMIT 8"; }
$result = mysql_query($query);
$output_items = array();
while($row = mysql_fetch_array($result)) {
$row[$title] = preg_replace('/[^\w\s].*$/', "", $row[$title]);
$row[$title] = trim($row[$title]);
$output_items[$row['title']] = $row['imageURL'];
} // while
$output_items = array_unique($output_items);
$output = '';
foreach ($output_items as $title => $image) {
$output .= '<img src='.$image.' style=max-width:50px;>'.$title."\n";
}
echo $output;
The problem is that the JQuery autocomplete code is pushing the <img> tag data into the input as well.
Is there a way to format like this but have only the item title in the input box without the <img src=/....>?
You can achieve that by extending the Autocomplete plugin by overwriting certain core functions, mainly "parse". The internal version of this function simply loops over each line of the returned data and “parses” it into an array of objects, each containing the following attributes:
data – the entire entry
value – the default display value
result – the data to populate the input element on selection
You can overwrite this by passing your own parse function as part of the options object to autocomplete.
you will also need to provide a "formatItem" function that will give you a chance to format the data shown in the autocomplete dropdown!
var acOptions = {
minChars: 3,
max: 100,
dataType: 'json', // this parameter is currently unused
extraParams: {
format: 'json' // pass the required context to the Zend Controller
},
parse: function(data) {
var parsed = [];
data = data.users;
for (var i = 0; i < data.length; i++) {
parsed[parsed.length] = {
data: data[i],
value: data[i].displayName,
result: data[i].displayName
};
}
return parsed;
},
formatItem: function(item) {
return item.displayName + ' (' + item.mail + ')';
}
};
Then you can call and also provide a function that can remove the image as required by you in the .result call as follows:
jQuery(document).ready(function($) {
$('#user_id')
.autocomplete('/path/to/ajax/data/source', acOptions)
.attr('name', 'display_name')
.after('<input type="hidden" name="user_id" id="ac_result">')
.result(function(e, data) {
$('#ac_result').val(data.uid); // remove the img here for your text field!
});
});
Hope this helps!
try this :
$img = $('img');
$img.replaceWith($img.html());
read here Jquery remove form tag, not content

Categories