jQuery and php Progressive Form Example

Posted: December 22nd, 2009 | Author: jriggs | Filed under: php | Tags: , , | No Comments »

How to use php and jquery to submit a form. This form features progressive enhancement meaning that if the client has javascript disabled the form will still function.

First the form, written in php:

 
<?php
function DisplayForm($values, $errors){
?>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Progressive Enhancement</title>
<meta name="description" content="" />
<meta name="keywords" content="" />
<link rel="stylesheet" href="style.css" type="text/css" media="screen" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="progressive.js"></script> 
</head>
<body>
<div id="contact_form">
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST" id="contact">
 
	<div id="top_message" class="top_message">
	<?php echo (count($errors)>0) ? '<span class="required_show">Please enter required information</span>' : 'Enter Your Information Below' ?>
	</div>
 
	<div class="container">
 
		<div class="spacer" id="spacer">
		&nbsp;
		</div>
 
		<div id="form">
			<div class="row">
			  <span class="label">Name:</span>
			  <span class="input_span"><input size="30" <?php echo (ISSET($errors['name_check'])) ? 'class="missing"' : '' ?> maxlength="30" name="name" id="name" value="<?php echo htmlentities($values['name']) ?>" ></span>
			  <span id="name_error" <?php echo (ISSET($errors['name_check'])) ? 'class="required_show"' : 'class="required_hide"' ?> >(required)</span>
			</div>
 
			<div class="row">
			  <span class="label">Email:</span>
			  <span class="input_span"><input size="30" <?php echo (ISSET($errors['email_check'])) ? 'class="missing"' : '' ?> maxlength="30" name="email" id="email" value="<?php echo htmlentities($values['email']) ?>"></span>
			  <span id="email_error" <?php echo (ISSET($errors['email_check'])) ? 'class="required_show"' : 'class="required_hide"' ?> >(required)</span>
			</div>
 
			<div class="row">
			  <span class="label">Phone:</span>
			  <span class="input_span"><input size="15" <?php echo (ISSET($errors['phone_check'])) ? 'class="missing"' : '' ?> maxlength="15" name="phone" id="phone" value="<?php echo htmlentities($values['phone']) ?>"></span>
			  <span id="phone_error"  <?php echo (ISSET($errors['phone_check'])) ? 'class="required_show"' : 'class="required_hide"' ?> >(required)</span>
			</div>
 
			<div class="row">
			  <span class="submit_span">
			  <input type="image" id="submit" value="submit" name="submit" src="submit.gif" alt="Submit" /></span>
			</div>
		</div>
 
		<div class="spacer" id="spacer">
		&nbsp;
		</div>
 
	</div>
 
</form>
</div>
</body>
</html>
 
<?php
}
 
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
	//$formValues = $_POST;
 
	include ('process.php');
 
	if (count($return_arr)>0){
 
		$formErrors = $return_arr;
 
		if(isset($formErrors['process_check'])){//error occurred processing data
			displaySubmit("Sorry an error occurred, please try again later.");
			exit;
		}
 
		DisplayForm($_POST, $formErrors);
 
	}else{
		//success! no validation or processing errors
		displaySubmit("Thank you for submitting your data.");
	}
 
}else{
	DisplayForm(null, null); //form not submitted - typically when page is loaded 1st time
}
 
?>

Next the php script the handles validation and processing of data:

<?php
//requires php 5.2 or greater
//sleep(2);  // use to mimic delayed response from server
 
if (empty($_POST)){exit;}
 
$return_arr = array();
 
if (isset($_POST['email']) && !isEmail(trim($_POST['email']))){ //validate value posted from email input box
	$return_arr["email_check"] = 'invalid';
}
 
if (isset($_POST['name']) && !isName(trim($_POST['name']))){
	$return_arr["name_check"] = 'invalid';
}
 
if (isset($_POST['phone']) && !isPhone(trim($_POST['phone']))){
	$return_arr["phone_check"] = 'invalid';
}
 
if (count($return_arr) == 0 && !isset($_POST['single_field'])){	//if no validation errors try to process the data and not single field flag set
 
	$process_errors = processData($_POST);
 
	if (!$process_errors){ //mail function returns 1
		$return_arr["process_check"] = 'invalid';
	}
}
 
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')){
		//data posted using jquery framework
		echo json_encode($return_arr);
 
	}else{
		//data posted using traditional form post
		return $return_arr;
}
 
function processData($formValues){
 
  $subject = "Contact Information Submitted";
  $message = 'Name: ' . $formValues['name']."\r\n" ;
  $message .= 'Email: ' . $formValues['email']."\r\n" ;
  $message .= 'Phone: ' . $formValues['phone']."\r\n" ;
 
//ini_set("SMTP","smtp.example.com"); //if you are using an smtp server add it here
//return mail("me@example.com", "Subject: $subject", $message, "From: contact-form@example.com");
//return 0; //test fail use this if you dont want to actually send an email while testing
return 1; //test success
}
 
 
//validation functions
function isEmail($email){
	return(preg_match("/^[-_.[:alnum:]]+@((([[:alnum:]]|[[:alnum:]][[:alnum:]-]*[[:alnum:]])\.)+(ad|ae|aero|af|ag|ai|al|am|an|ao|aq|ar|arpa|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|biz|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|com|coop|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|in|info|int|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mil|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|museum|mv|mw|mx|my|mz|na|name|nc|ne|net|nf|ng|ni|nl|no|np|nr|nt|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pro|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)$|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\.){3}([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$/i"
			,$email));
}
 
function isPhone($phone){
	return(preg_match( "/(\d)?(\s|-)?(\()?(\d){3}(\))?(\s|-|\.)?(\d){3}(\s|-|\.)?(\d){4}$/"
			,$phone));
}
 
function isName($name){
	return strlen($name) > 2;
}
 
function displaySubmit($message){
 
$data_posted = <<<EOT
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Progressive Enhancement</title>
<meta content="" name="description"/>
<meta content="" name="keywords"/>
<link media="screen" type="text/css" href="style.css" rel="stylesheet">
</link>
</head>
<body>
<div id="contact_form">
<form id="contact">
<div id="top_message" class="top_message error"> </div>
<div class="container">
<div id="spacer" class="spacer">$message</div>
</div>
</form>
</div>
</body>
</html>
EOT;
echo $data_posted;
 
}
 
?>

The jQuery file to process ajax requests:

 
$(document).ready(function(){
 
var bSubmitted = false;
 
	$("#name").focus(); //set focus to first input box
 
 
 
	$("#contact").submit(function(){  //form submitted
		//disable submit button and display loading gif to prevent multiple posts
		$('input[id=submit]', this).attr('disabled', 'disabled');
		$("#submit").attr("src", "loading-ani.gif");
 
		$.post("process.php", $("#contact").serialize(),
		function(data){
			var valid ='true';	//function level variable to track if all inputs on the form passed validation
 
			if (data.phone_check == 'invalid'){
				valid = 'false'; 
				$("#phone").addClass('missing'); 
				$("#phone_error").removeClass('required_hide');
				$("#phone_error").addClass('required_show');
				$("#phone").focus(); 
			} else {
				$("#phone_error").removeClass('required_show');
				$("#phone_error").addClass('required_hide');
				$("#phone").removeClass('missing'); 
			}
 
			if (data.email_check == 'invalid'){
				valid = 'false'; 
				$("#email_error").removeClass('required_hide');
				$("#email_error").addClass('required_show');
				$("#email").addClass('missing'); 
				$("#email").focus();
			} else {
				$("#email_error").removeClass('required_show');
				$("#email_error").addClass('required_hide');
				$("#email").removeClass('missing'); 
			}
 
			if (data.name_check == 'invalid'){
				valid = 'false'; 
				$("#name_error").removeClass('required_hide');
				$("#name_error").addClass('required_show');
				$("#name").addClass('missing'); 
				$("#name").focus(); 
			} else {
				$("#name_error").removeClass('required_show');
				$("#name_error").addClass('required_hide');
				$("#name").removeClass('missing'); 
			}
 
			//re-enable submit button
			$("#submit").removeAttr("disabled");
			$("#submit").attr("src", "submit.gif");
 
			if (valid == 'false'){ 	//if the form contains invalid data notify user else display thank you message	
				$("#top_message").html('Please enter required information');
				$("#top_message").addClass('error'); 
			} else  {  //all form data is valid and has been processed
				$("#form").hide();
				$("#top_message").html('&nbsp;');
					if (data.process_check == 'invalid'){  //processing error
						$("#spacer").html('Sorry an error occurred, please try again later.');
					}else{
						$("#spacer").html('Thank you for submitting your data.');
					}
			}
 
		}, "json");
		//prevent default post behavior
		bSubmitted = true;
		return false; 
 
		});
 
	//single field validation functions - fired on key up event
	$("#name").keyup(function(){
		if (bSubmitted == true){ //only validate after the form has been submitted
			val  =  $(this).val();
		//	val  = $("input#name").val();
			what = 'name';
			SingleValidate(val, what);
			}
		});
 
	$("#email").keyup(function(){
		if (bSubmitted == true){ //only validate after the form has been submitted
			val  = $(this).val();
			what = 'email';
			SingleValidate(val, what);
			}
		});
 
	$("#phone").keyup(function(){
		if (bSubmitted == true){ //only validate after the form has been submitted
			val  = $(this).val();
			what = 'phone';
			SingleValidate(val, what);
			}
		});
 
 
});
 
 
function SingleValidate(val, what) {
 
var dataString = what + '=' + val + '&single_field=yes';//single field = tell process script to only validate data
var error = what + "_check";
 
	$.post("process.php", dataString, function(data){
			if (data[error] == 'invalid'){
				$('#' + [what] + '_error').removeClass('required_hide');
				$('#' + [what] + '_error').addClass('required_show');
				$('#' + what).addClass('missing'); 
			}else{
				$('#' + [what] + '_error').removeClass('required_show');
				$('#' + [what] + '_error').addClass('required_hide');
				$('#' + what).removeClass('missing');
			}
		}, "json");
}

Finally, a style sheet to help with the presentation

input.missing {
 /*background-color: #FFFF77;*/
 border: 2px solid #ff0000;
}
 
div.row {
 clear: both;
 padding-top: 5px;
}
 
div.row span.label {
 float: left;
 width: 100px;
 text-align: right;
  }
 
div.row span.input_span {
 width: 235px;
 text-align: left;
 padding-right: 0px;
 padding-left: 45px;
 
  } 
 
div.row span.submit_span {
 padding-right: 0px;
 padding-left: 145px;
 
  } 
 
div.spacer {
 clear: both;
 }
 
.container{
 width: 425px; 
 background-color: #ccc;
 border: 1px dotted #333;
 padding: 5px 5px 5px 5px; 
 margin: 0px auto;
 }
 
.top_message{ 
 width: 360px; 
 margin: 10px auto;
}
 
.error{
 color: #ff0000;
  }
 
.required_hide{
 color: #ff0000;
 display:none;
} 
 
.required_show{
 color: #ff0000;
 }

See the form in action here.
Download


Address Standardization & Verification with USPS web tools and PHP

Posted: October 27th, 2009 | Author: jriggs | Filed under: php | Tags: , , , , , | 1 Comment »

Before using this code you will need to sign up for an account with USPS webtools here.

Class, save as ‘usps_address_class.php’

 
<?php
 
class usps {
 
		public $account = 'xxxxxxx'; //you need to register for this
		public $url = 'http://production.shippingapis.com/ShippingAPI.dll';
		public $address1, $address2, $city, $state, $zip;
		public $ship_address1, $ship_address2, $ship_city, $ship_state, $ship_zip;
 
	function toXML() {
		$xml = ' <AddressValidateRequest USERID="' . $this->account . '"><Address ID="1">';
		$xml .= '<Address1>' . $this->address1 . '</Address1>';
		$xml .= '<Address2>' . $this->address2 . '</Address2>';
		$xml .= '<City>' . $this->city . '</City>';
		$xml .= '<State>' . $this->state . '</State>';
		$xml .= '<Zip5>' . $this->zip . '</Zip5>';
		$xml .= '<Zip4></Zip4></Address>';
 
		if ($this->ship_address2 <> ''){
			//shipping address
			$xml .= '<Address ID="2">';
			$xml .= '<Address1>' . $this->ship_address1 . '</Address1>';
			$xml .= '<Address2>' . $this->ship_address2 . '</Address2>';
			$xml .= '<City>' . $this->ship_city . '</City>';
			$xml .= '<State>' . $this->ship_state . '</State>';
			$xml .= '<Zip5>' . $this->ship_zip . '</Zip5>';
			$xml .= '<Zip4></Zip4></Address>';
			}
 
		$xml .= '</AddressValidateRequest>';
 
     return $xml;
     }
 
	function submit_request() {
 
		$ch = curl_init($this->url);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, "API=Verify&XML=" . $this->toXML());
		curl_setopt($ch, CURLOPT_TIMEOUT, 60);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
 
		$result = curl_exec($ch);
		$error = curl_error($ch);
 
		if(empty($error)) {
			return $result;
		}else{
			die(curl_error($ch));
		}
	}
}
 
?>

And a sample page accessing it:

 
<?php
 
 
require("usps_address_class.php");
$uspsRequest = new usps(); //class instantiation
$uspsRequest->address1 = 'suite 321';
$uspsRequest->address2 = '1600 Pennsylvania Ave NW';
$uspsRequest->city = 'Washington';
$uspsRequest->state = 'DC';
$uspsRequest->zip = '20500';
/*
//optional second address
$uspsRequest->ship_address1 = '';
$uspsRequest->ship_address2 = '';
$uspsRequest->ship_city = '';
$uspsRequest->ship_state = '';
$uspsRequest->ship_zip = '';
*/
 
$result = $uspsRequest->submit_request();
 
if (!empty($result)){
		$xml = new SimpleXMLElement($result);
	}else{
		die;
	}
 
 
if(isset($xml->Address[0]->Error)) { echo ' Error Address 1';}
if(isset($xml->Address[1]->Error)) { echo ' Error Address 2';}
 
echo $xml->Address[0]->Address2 . ' ' . $xml->Address[0]->Address1 ;
echo '<br />';
echo $xml->Address[0]->City. ' ' . $xml->Address[0]->State  . ' ' . $xml->Address[0]->Zip5;
echo '<br />';
echo $xml->Address[1]->Address2 . ' ' . $xml->Address[1]->Address1 ;
echo '<br />';
echo $xml->Address[1]->City. ' ' . $xml->Address[1]->State  . ' ' . $xml->Address[1]->Zip5;
 
?>

php: Create Url Safe Encrypted String

Posted: August 6th, 2009 | Author: jriggs | Filed under: php | Tags: , , | 1 Comment »

The following code represents an easy way to create an encrypted string that can be passed in an URL.  While this method is adequate for email addresses, user names, and the like – it should not be used to encrypt mission-critical info or personal data such as Social Security numbers or credit card information.

Also, you will need to have the ‘mcrypt’ module enabled.  You can do this by opening your php.ini file and removing the ‘;’ just before ‘extension=php_mcrypt.dll’.

<?php
 
$cc=mencrypt("This is the string to be encrypted","key-change-this");
 
 
echo $cc.'<br />';
$dd=mdecrypt($cc,"key-change-this");
echo $dd.'<br />';
 
//encrypted value passed in url ie:
//http://yoursite.com/crypted.php?id=encrypted_string
if (isset($_GET["id"])){
$ee=$_GET["id"];
echo $ee.'<br />';
echo mdecrypt($ee,"key-change-this");
}
 
function mencrypt($input,$key){
$key = substr(md5($key),0,24);
$td = mcrypt_module_open ('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
mcrypt_generic_init ($td, $key, $iv);
$encrypted_data = mcrypt_generic ($td, $input);
mcrypt_generic_deinit ($td);
mcrypt_module_close ($td);
return trim(chop(url_base64_encode($encrypted_data)));
}
 
function mdecrypt($input,$key){
$input = trim(chop(url_base64_decode($input)));
$td = mcrypt_module_open ('tripledes', '', 'ecb', '');
$key = substr(md5($key),0,24);
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
mcrypt_generic_init ($td, $key, $iv);
$decrypted_data = mdecrypt_generic ($td, $input);
mcrypt_generic_deinit ($td);
mcrypt_module_close ($td);
return trim(chop($decrypted_data));
}
 
function url_base64_encode($str){
return strtr(base64_encode($str),
array(
'+' => '.',
'=' => '-',
'/' => '~'
)
);
}
 
function url_base64_decode($str){
return base64_decode(strtr($str,
array(
'.' => '+',
'-' => '=',
'~' => '/'
)
));
}
?>

End Code.


php: Send xml/soap to Secured Server

Posted: March 11th, 2009 | Author: jriggs | Filed under: php | Tags: , , , , | 1 Comment »

Sample requires curl see code below:

function callWebServicePost($host, $url, $payload, $user, $password) {
 
$header[] = "Host: ". $host;
$header[] = "Content-type: text/xml";
$header[] = "Content-length: ".strlen($payload) . "\r\n";
$header[] = $payload;
 
$session = curl_init($url);
 
 // Tell curl to use HTTP POST
curl_setopt ($session, CURLOPT_POST, true);
curl_setopt($session, CURLOPT_CONNECTTIMEOUT,30);
// Tell curl that this is the body of the POST
curl_setopt ($session, CURLOPT_POSTFIELDS, '');
 
// Tell curl not to return headers, but do return the response
curl_setopt($session, CURLOPT_HEADER, true);
// Display headers
curl_setopt($session, CURLOPT_VERBOSE, true);
// Display communication with server
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// Return data instead of display to std out
curl_setopt($session, CURLOPT_HTTPHEADER, $header );
 // headers from above
 
// provide credentials if they're established
if(!empty($user) &amp;&amp; !empty($password))
      curl_setopt($session, CURLOPT_USERPWD, $user . ":" . $password);
    // tell cURL to graciously accept an SSL certificate if presented
    if(ereg("^(https)",$url))
          curl_setopt($session, CURLOPT_SSL_VERIFYPEER,false);
    $result = curl_exec($session);
 
    curl_close($session);
 
    return $result;
}