views:

431

answers:

3

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;`
+5  A: 

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 excellend 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
}
Horia Dragomir
thanks for the response, but i'm not sure how to implement it because i only need to echo the html one time as opposed to the for loop i created for the comments. can you take a look at my code i added to the question and point me in the right direction? thanks!
Dave Kiss
If you take a look at my answer you can do the same thing just without using an array. So `echo json_encode($html);` and then in the success function you'd just access it via `$data`.
anomareh
thanks! the json_encode array was just what i needed.
Dave Kiss
How do you deal with the slashes that jQuery adds to the HTML string?
Metropolis
+1  A: 

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;
        }
    }
});
anomareh
thanks for the answer - i did this, but now the html is being iterated over for every entry in my database due to the array being involved in a for loop. is there a way i can combine the array of information from the db with the single html variable to produce json that only displays the html: code one time?
Dave Kiss
I updated my answer for what you were looking for.
anomareh
A: 

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 
        }; 
    }); 
David Robbins