This topic is to discuss the tutorial:
Building an AJAX paste-board STAGE 3, more functionality
OK so a quick recap, whats left to be done?
* save new postie
* view existing postie
Ok, lets do the first one first: saving the new postie.
First we need to make the "Paste" button do something. It already has the OnClick action "PasteIt()", so now lets define that function in your JavaScript area:
function PasteIt() {
var pastetext = $("textarea#pastetext").val();
$.post("backend.php", {action: 'paste', paste: pastetext}, ajaxCallback );
}
Simple eh? very similiar to the previous GET method, just with "post" this time, and a different set of values (action=paste, paste=).
SO lets see what happens in our PHP script yes? Add this to the start of your script:
print_r( $_POST );
and this to your ajaxCallback function:
alert( data )
save both, and submit a pastie. you should get something like this:
<pastie>
array
(
[action] => paste
[paste] => some text
)
</pastie>
So now we have to make the PHP do something itself. This involves connecting to the database, so we need to do a number of things:
REPLACE
print_r($_POST);
WITH
$action = $_POST['action'];
also, this is to make any setcookies work later on:
REPLACE
<pastie>
<?php
WITH
<?php
$output = "<pastie>
";
and add this to a portion of your PHP, before the print $output;
if( $action == "paste" && strlen( $_POST['paste']) > 1 )
{
}
Ok so now we have a logical block for when something longer than 1 character is pasted.
Now we need to go through a number of steps:
1 make the string safe to save to the mysql db, including adding slashes and replacing html entities with safe chars
2 open a connection the database
3 INSERT the paste into the database.
4 return the new paste to the page along with a success message
step 1: make string safe
$paste = $_POST['paste'];
$paste = htmlentities( $paste, ENT_QUOTES );
$paste = addslashes( $paste );
So now if we were to submit "here is 'some' <b>bold</b> text" we would find "here is 'some' <b>bold</b> text" being inserted to the database - completely mysql safe.
step 2: open a connection
$user = "xxxxxx";
$pass = "xxxxxx";
$server= "xxxxxx";
$connect = mysql_connect( $server, $user, $pass );
$output .= "<newpaste>";
if( !$connect ) {
$output .= "<status>0</status>";
$output .= "<statusmessage>".mysql_error()."</statusmessage>";
} else {
}
$output .= "</newpaste>";
Ok, i might have skipped a stage or two here for the less observant... The connection is the first 4 lines, and after that i have done same status checking + XML building. This makes it give a status 0 (false) to the frontend on failure, including the mysql_error string for debugging.
Also, remember to change the mysql info for your own.
See that "} else {" ? This is where we go to:
step 3: insert the new paste
mysql_select_db( "pastie" );
$userip = $_SERVER['REMOTE_ADDR'];
$insert = "INSERT INTO `pastes` VALUES('', '".$userip."', '".time()."', '".$paste."')";
$query = mysql_query($insert);
$newid = mysql_insert_id();
setcookie("own[".$newid."]", time(), time()+(3600*24*365));
Ok... even i realise this is a bit too skippy... Firstly, where has this database come from?
Well remember at the start i posted that database layout? Well we need to create it... heres some nice code for you to save and run:
<?php
$user = "xxxxxx";
$pass = "xxxxxx";
$server = "xxxxxx";
mysql_connect( $server, $user, $pass ) or die(mysql_error());
$query = "CREATE DATABASE IF NOT EXISTS `pastie`;";
$query .="USE `pastie`;";
$query .="create table if not exists pastes (
id int(6) primary key auto_increment,
userip varchar(12),
posttime integer(12),
post mediumtext);";
mysql_query($query) or die(mysql_error());
?>
Save this, run it, and you should get a blank page - which indicates success, and you now have a database
Ok so back to the backend.PHP, remember the code we just added? well the INSERT string is pretty basic, so i won't explain it. We have also set a cookie to add to our users "own" list.
Now we need to check if the QUERY was succesful, and return to the relevant info to the front end:
mysql_select_db( "pastie" );
$userip = $_SERVER['REMOTE_ADDR'];
$insert = "INSERT INTO `pastes` VALUES('', '".$userip."', '".time()."', '".$paste."')";
$query = mysql_query( $insert );
if($query) {
$newid = mysql_insert_id();
setcookie("own[".$newid."]", time(), time()+(3600*24*365));
$output .= "<status>1</status>";
} else {
$output .= "<status>0</status>";
$output .= "<statusmessage>".mysql_error()."</statusmessage>";
}
See how the code has changed? So now we have all the relevant info in our backend. If it all goes well, it should insert + return status=1.
So back to the
frontend:
in
ajaxCallback:
var newpost = $(data).find("newpaste");
var npstatus = $.trim( $(data).find("newpaste status").text() );
var recent = $(data).find("recent");
var own = $(data).find("own");
if( npstatus == 1 ) {
$("div.viewpane").html( "<h1>Your new paste:</h1>"+newpost.find("text").html() );
$("div.pasteform").hide().find("textarea").empty();
$("div.viewpane").show();
$(".savescreen").fadeOut("fast").hide();
var newitem = "<li><a href='#' onclick='viewPostie(\""+newpost.find("id").html()+"\")'>Postie #"+newpost.find("id").html()+"</a> just now</li>";
$("ul#own, ul#recent").append( newitem );
} else {
$(".savescreen").fadeOut("fast").hide();
}
Thats what i have now.... lots of code which does not an awful lot... just check the status, show the viewpane, add items to the UO and RV lists....
However, if you can see that else at the end, you will notice that handles for when the status ISNT 1, ie when there is an error. We could handle that in a number of ways, for example:
* show something similiar to the savescreen, but with a red "error" in it.
* show an alert
* show the viewpane with the error in it.
the first one is best IMO, so add this to your html:
<div class="errorscreen"><h2>Error</h2><h3></h3><a onclick='$(".errorscreen").fadeOut("fast");'>close this message</a></div>
and download the update CSS at the end of the post
[b]okay, thats everything for the save function, heres a review of the code for various bits:
[indent]
*******
The javascript, ajaxCallback function:
function ajaxCallback( data ) {
// alert(data);
var newpost = $(data).find("newpaste");
var npstatus = $.trim( $(data).find("newpaste status").text() );
var recent = $(data).find("recent");
var own = $(data).find("own");
if( newpost.size() == 1) {
if( npstatus == 1 ) {
$("div.viewpane").html( "<h1>Your new paste:</h1>"+newpost.find("text").html() );
$("div.pasteform").hide().find("textarea").empty();
$("div.viewpane").show();
$(".savescreen").fadeOut("fast").hide();
var newitem = "<li><a href='#' onclick='viewPostie(\""+newpost.find("id").html()+"\")'>Postie #"+newpost.find("id").html()+"</a> just now</li>";
$("ul#own, ul#recent").append( newitem );
} else if( npstatus == 0 ) {
$(".savescreen").fadeOut("fast").hide();
$(".errorscreen").css("opacity",0).css("display","block").fadeTo("slow", 0.5).find("h3").html( newpost.find("statusmessage") );
}
}
if( recent.size() == 1 ) {
$("ul#recent").empty();
recent.children().each( function() {
var newitem = "<li><a href='#' onclick='viewPostie(\""+$(this).find("id").html()+"\")'>Postie #"+$(this).find("id").html()+"</a> at "+$(this).find('time').html()+"</li>";
$("ul#recent").append( newitem );
} );
}
if( own.size() == 1 ) {
$("ul#own").empty();
own.children().each( function() {
var newitem = "<li><a href='#' onclick='viewPostie(\""+$(this).find("id").html()+"\")'>Postie #"+$(this).find("id").html()+"</a> on "+$(this).find('time').html()+"</li>";
$("ul#own").append( newitem );
} );
}
}
*******
The php add paste section
*******
if( $action == "paste" )
{
$paste = $_POST['paste'];
$paste = htmlentities( $paste, ENT_QUOTES );
$user = "root";
$pass = "";
$server= "localhost";
$connect = mysql_connect( $server, $user, $pass );
$output .= "<newpaste>";
if( strlen( $paste ) < 1) {
$output .= "<status>0</status>";
$output .= "<statusmessage>Please paste something longer... we don't like single letters;)</statusmessage>";
} else
if( !$connect ) {
$output .= "<status>0</status>";
$output .= "<statusmessage>".mysql_error()."</statusmessage>";
} else {
mysql_select_db( "pastie" );
$userip = $_SERVER['REMOTE_ADDR'];
$insert = "INSERT INTO `pastes` VALUES('', '".$userip."', '".time()."', '".$paste."')";
$query = mysql_query( $insert );
if($query) {
$newid = mysql_insert_id();
setcookie("own[".$newid."]", time(), time()+(3600*24*365));
$output .= "<status>1</status>";
$output .= "<text>".stripslashes(str_replace("\n","<BR \>",$paste))."</text>";
$output .= "<id>".$newid."</id>";
} else {
$output .= "<status>0</status>";
$output .= "<statusmessage>".mysql_error()."</statusmessage>";
}
}
$output .= "</newpaste>";
}
okay, i'm gonna split this into a fourth part for the ease of the read.