Adding Ajax
You can add a layer of Ajax on top of the system just created in one of two ways:
- Hand-code raw JavaScript
- Tap into an existing JavaScript framework
I’ve personally done both, but these days, when I want quick, reliable Ajax features, I turn to jQuery. The jQuery framework is a snap to use (once you understand the somewhat cryptic syntax) and degrades nicely. This is to say that for those unfortunate souls who can’t use the Ajax-enabled version of the system, they’ll still be able to use the non-Ajax system without a problem.
The first thing you’ll need to do is incorporate the jQuery framework into the site. You can, of course, download the framework, upload it to your server, and then use the <script> tag to add it to a page, but I’d recommend you consider using Google’s API library system. Here is that code, for the current version of jQuery at the time of this writing (1.4.4):
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript" charset="utf-8"></script>
The main benefit of using Google’s API library is speed. The jQuery framework will be provided to your site’s visitors from the closest Google server, taking advantage of Google’s CDN (Content Delivery Network). Also, if visitors have been to another site that uses Google’s API library for jQuery, their browser should have cached the jQuery framework, meaning they won’t need to download it again.
Once you’ve included the jQuery library, start by creating an anonymous function to be called when the user rates a product:
<script type="text/javascript" charset="utf-8"> $('#rating_form').submit(function() { // Actual function code. }); </script>
That code says that when the form with an ID of rating_form is submitted, the following functionto be defined nextshould be called. This code will work with either of the two forms (the select menu or the radio buttons).
Within the anonymous function, replacing “Actual function code”, you make the Ajax call:
// Create a new, empty object. var data = new Object(); // Add a property called 'rating' with a value of the form element's value: data.rating = $('#rating').val(); // Add a property called 'item_id' with a value of the page’s item ID: data.item_id = <?php echo $item_id; ?>; // Post the request: $.post('rating_ajax.php', data, handleAjaxRating, 'text'); // Prevent the form's submission: return false;
I would probably also add code validating the rating and item ID values within the JavaScript so that the Ajax request is only made when appropriate.
The jQuery post() method makes a POST request of a page. Its first argument is the page being requestedhere, rating_ajax.php. I want the Ajax to use a different PHP script than rating.php, as the output of each script will differ.
The second argument is an object of data to be sent to the page. That data object is built up over a couple of lines. The third argument is a function to be called when the response is received, here named handleAjaxRating. And the fourth argument is the type of response to be expected back. I’ll return to the function after looking at rating_ajax.php.
The rating_ajax.php script isn’t meant to be run directly, so it contains no HTML. It needs to validate the received values, run the INSERT query, and return a simple text message indicating the success of the whole operation. Here is that script, in its entirety:
<?php // rating_ajax.php // This script is called to post a rating of an item via Ajax. // It needs to receive two values: a rating and an item ID. // It returns a simple text message--worked/failed/error/invalid--to indicate the results. if (isset($_POST['rating'], $_POST['item_id']) && filter_var($_POST['rating'], FILTER_VALIDATE_INT, array('min_range' => 1, 'max_range' => 5)) && filter_var($_POST['item_id'], FILTER_VALIDATE_INT, array('min_range' => 1))) { // Okay! // Include the database connection script! // The database connection script should define the $dbc--database connection--variable. // Run the query: $q = "INSERT INTO ratings (item_id, rating) VALUES ({$_POST['item_id']}, {$_POST['rating']})"; if ($r = mysqli_query($dbc, $q)) { // Query didn't cause an error. if (mysql_affected_rows($dbc) == 1) { // Worked! echo 'worked'; } else { // Didn't work! echo 'failed'; } } else { // MySQL error! echo 'error'; } } else { echo 'invalid'; } ?>
The comments in the code, and a basic understanding of PHP, should make it clear what’s happening where and why. The script will only print one of four single words: worked, failed, error, or invalid. Using this information, you can now define the handleAjaxRating function:
function handleAjaxResponse(response) { // Change the DIV if the response was positive: if (response == 'worked') { $('#rating_div').html('<div>Thanks for rating this thing!</div>'); } } // End of handleAjaxResponse() function.
The function will receive the server response (the result of calling the PHP script) as its lone argument. Because the jQuery post() method was told the response would be text, the function’s response variable will have a simple string value. You could use that value in any number of ways. In the previous code, the HTML contents of the rating_div DIV (which is the form, by default) will be replaced by a message, but only if the script had a positive result. The script doesn’t do anything right now for the other responses, but that’d be easy enough to add (by adding else if clauses to the conditional in the function).
And that’s all there is to the Ajax layer. You can test this all in your browser (using the downloaded code, if you want) to see the result. Disable JavaScript in your browser to see how the system still works the old fashioned way.