Ajax: Basic Utilities

Exclusive offer: get 50% off this eBook here
PHP Ajax Cookbook

PHP Ajax Cookbook — Save 50%

Over 60 simple but incredibly effective recipes to Ajaxify PHP websites with this book and ebook

$26.99    $13.50
by Milan Sedliak | December 2011 | AJAX PHP

In this article by Milan Sedliak, author of PHP Ajax we will learn how to build the basic Ajax forms. We will try to understand where we can use Ajax methodology and where we can't. There are a lot of ways in which we can use Ajax. Here are some "best" practices based on user experience and the performance of the specific system. Ajax makes our lives easier, faster, and better; how and where to use it is up to us.

In this article, we will cover the following topics:

  • Validating a form using Ajax
  • Creating an autosuggest control
  • Making form wizards
  • Uploading a file using Ajax
  • Creating a five star rating system

(For more resources on PHP Ajax, see here.)

Validating a form using Ajax

The main idea of Ajax is to get data from the server in real time without reloading the whole page. In this task we will build a simple form with validation using Ajax.

Getting ready

As a JavaScript library is used in this task, we will choose jQuery. We will download (if we haven't done it already) and include it in our page. We need to prepare some dummy PHP code to retrieve the validation results. In this example, let's name it inputValidation.php. We are just checking for the existence of a param variable. If this variable is introduced in the GET request, we confirm the validation and send an OK status back to the page:

<?php $result = array(); if(isset($_GET["param"])){ $result["status"] = "OK"; $result["message"] = "Input is valid!"; } else { $result["status"] = "ERROR"; $result["message"] = "Input IS NOT valid!"; } echo json_encode($result); ?>

How to do it...

  1. Let`s start with basic HTML structure. We will define a form with three input boxes and one text area. Of course, it is placed in :
  2. <body> <h1>Validating form using Ajax</h1> <form class="simpleValidation"> <div class="fieldRow"> <label>Title *</label> <input type="text" id="title" name="title" class="required" /> </div> <div class="fieldRow"> <label>Url</label> <input type="text" id="url" name="url" value="http://" /> </div> <div class="fieldRow"> <label>Labels</label> <input type="text" id="labels" name="labels" /> </div> <div class="fieldRow"> <label>Text *</label> <textarea id="textarea" class="required"></textarea> </div> <div class="fieldRow"> <input type="submit" id="formSubmitter" value="Submit" disabled= "disabled" /> </div> </form> </body> <style>

  3. For visual confirmation of the valid input, we will define CSS styles:
  4. label{ width:70px; float:left; } form{ width:320px; } input, textarea{ width:200px; border:1px solid black; float:right; padding:5px; } input[type=submit] { cursor:pointer; background-color:green; color:#FFF; } input[disabled=disabled], input[disabled] { background-color:#d1d1d1; } fieldRow { margin:10px 10px; overflow:hidden; } failed { border: 1px solid red; } </style>

  5. Now, it is time to include jQuery and its functionality:
  6. <script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="js/jquery-1.4.4.js"></script> <script> var ajaxValidation = function(object){ var $this = $(object); var param= $this.attr('name'); var value = $this.val(); $.get("ajax/inputValidation.php", {'param':param, 'value':value }, function(data) { if(data.status=="OK") validateRequiredInputs(); else $this.addClass('failed'); },"json"); } var validateRequiredInputs = function (){ var numberOfMissingInputs = 0; $('.required').each(function(index){ var $item = $(this); var itemValue = $item.val(); if(itemValue.length) { $item.removeClass('failed'); } else { $item.addClass('failed'); numberOfMissingInputs++; } }); var $submitButton = $('#formSubmitter'); if(numberOfMissingInputs > 0){ $submitButton.attr("disabled", true); } else { $submitButton.removeAttr('disabled'); } } </script>

  7. We will also initialize the document ready function:
  8. <script> $(document).ready(function(){ var timerId = 0; $('.required').keyup(function() { clearTimeout (timerId); timerId = setTimeout(function(){ ajaxValidation($(this)); }, 200); }); }); </script>

  9. When everything is ready, our result is as follows:

How it works...

We created a simple form with three input boxes and one text area. Objects with class required are automatically validated after the keyup event and calling the ajaxValidation function. Our keyup functionality also includes theTimeoutfunction to prevent unnecessary calls if the user is still writing. The validation is based on two steps:

  • Validation of the actual input box: We are passing the inserted text to the ajax/inputValidation.php via Ajax. If the response from the server is not OK we will mark this input box as failed. If the response is OK, we proceed to the second step.
  • Checking the other required fields in our form. When there is no failed input box left in the form, we will enable the submit button.

There's more...

Validation in this example is really basic. We were just checking if the response status from the server is OK. We will probably never meet a validation of the required field like we have here. In this case,it's better to use the length property directly on the client side instead of bothering the server with a lot of requests,simply to check if the required field is empty or filled. This task was just a demonstration of the basic Validationmethod. It would be nice to extend it with regular expressions on the server-side to directly check whether the URL form or the title already exist in our database, and let the user know what the problem is and how he/she can fix it.

Creating an autosuggest control

This recipe will show us how to create an autosuggest control. This functionality is very useful when we need to search within huge amounts of data. The basic functionality is to display the list of suggested data based on text in the input box.

Getting ready

We can start with the dummy PHP page which will serve as a data source. When we call this script with GET method and variable string, this script will return the list of records (names) which include the selected string:

<?php $string = $_GET["string"]; $arr = array( "Adam", "Eva", "Milan", "Rajesh", "Roshan", // ... "Michael", "Romeo" ); function filter($var){ global $string; if(!empty($string)) return strstr($var,$string); } $filteredArray = array_filter($arr, "filter"); $result = ""; foreach ($filteredArray as $key => $value){ $row = "<li>".str_replace($string, "<strong>".$string."</strong>", $value)."</li>"; $result .= $row; } echo $result; ?>

How to do it...

  1. As always, we will start with HTML. We will define the form with one input box and an unsorted list datalistPlaceHolder:
  2. <h1>Dynamic Dropdown</h1> <form class="simpleValidation"> <div class="fieldRow"> <label>Skype name:</label> <div class="ajaxDropdownPlaceHolder"> <input type="text" id="name" name="name" class="ajaxDropdown" autocomplete="OFF" /> <ul class="datalistPlaceHolder"></ul> </div> </div> </form>

  3. When the HTML is ready, we will play with CSS:
  4. <style>
    label { width:80px; float:left; padding:4px; }
    form{ width:320px; }
    input, textarea{ 
    width:200px; border:1px solid black;
    
    border-radius: 5px; float:right; padding:5px;
    }
    
    input[type=submit] { cursor:pointer; 
    background-color:green; color:#FFF; }
    
    input[disabled=disabled] { background-color:#d1d1d1; }
    
    fieldRow { margin:10px 10px; overflow:hidden; }
    validationFailed { border: 1px solid red; }
    validationPassed { border: 1px solid green; }
    
    .datalistPlaceHolder {
    width:200px; border:1px solid black;
    border-radius: 5px;
    float:right; padding:5px; display:none;
    }
    
    ul.datalistPlaceHolder li { list-style: none; 
    cursor:pointer; padding:4px; }
    
    ul.datalistPlaceHolder li:hover { color:#FFF; 
    background-color:#000; }
    </style>
    

     

    Now the real fun begins. We will include jQuery library and define our keyup events:

    <script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="js/jquery-1.4.4.js"></script> <script> var timerId; var ajaxDropdownInit = function(){ $('.ajaxDropdown').keyup(function() { var string = $(this).val(); clearTimeout (timerId); timerId = setTimeout(function(){ $.get("ajax/dropDownList.php", {'string':string}, function(data) { if(data) $('.datalistPlaceHolder').show().html(data); else $('.datalistPlaceHolder').hide(); }); }, 500 ); }); } </script>

  5. When everything is set, we will call the ajaxDropdownInit function within the document ready function:
  6. <script>

    $(document).ready(function(){

    ajaxDropdownInit();

    });

    </script>

     

    Our autosuggest control is ready. The following screenshot shows the output:

How it works...

The autosuggest control in this recipe is based on the input box and the list of items in datalistPlaceHolder. After each keyup event of the input box,datalistPlaceHolder will load the list of items from ajax/dropDownList.php via the Ajax function defined in ajaxDropdownInit. A good feature of this recipe is thetimerID variable that,when used with thesetTimeout method, will allow us to send the request on the server only when we stop typing (in our case it is 500 milliseconds). It may not look so important, but it will save a lot of resources. We do not want to wait for the response of "M" typed in the input box, when we have already typed in "Milan". Instead of 5 requests (150 milliseconds each), we have just one. Multiply it, for example, with 10,000 users per day and the effect is huge.

There's more...

We always need to remember that the response from the server is in the JSON format.

[{ 'id':'1', 'contactName':'Milan' },...,{ 'id':'99', 'contactName':'Milan (office)' }] Using JSON objects in JavaScript is not always useful from the performance point of view. Let's imagine we have 5000 contacts in one JSON file. It may take a while to build HTML from 5000 objects but, if we build a JSON object, the code will be as follows: [{ "status": "100", "responseMessage": "Everything is ok! :)", "data": "<li><h2><ahref=\"#1\">Milan</h2></li> <li><h2><ahref=\"#2\">Milan2</h2></li> <li><h2><ahref=\"#3\">Milan3</h2></li>" }]

It may take a while to build HTML from 5000 objects but, if we build a JSON object, the code will be as follows:

<?php echo "STEP 1"; // Same for 2 and 3 ?>

In this case, we will have the complete data in HTML and there is no need to create any logic to create a simple list of items.

PHP Ajax Cookbook Over 60 simple but incredibly effective recipes to Ajaxify PHP websites with this book and ebook
Published: December 2011
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

(For more resources on this PHP Ajax, see here.)

Making Form Wizards

Form Wizards are basically forms divided into more steps. They are useful for polls or special cases of forms, when we want to divide the registration process on our website. They are also used in e-commerce websites, in the purchase process (In this recipe, we will build a Form Wizard (as simple as possible).

Getting ready

We will prepare the dummy PHP files step1.php, step2.php, and step3.php. The content of these files is simple:

<script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="js/jquery-1.4.4.js"></script>

Here again we will include jQuery library:

<script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="js/jquery-1.4.4.js"></script>

How to do it...

  1. We start by defining the HTML content:
  2. <div class="wizard">
    <ul class="wizardNavigation">
    <li class="active first" id="step1">Step 1</li>
    <li id="step2">Step 2</li>
    <li id="step3" class="last">Step 3</li>
    </ul>
    <div class="wizardBody">STEP 1</div>
    <div class="wizardActionButtons">
    <a href="javascript:submitThePage('back');" class="back"
    style="display:none;">Back</a>
    <a href="" class="finish" style="display:none;">
    Finish</a>
    <a href="javascript:submitThePage('next');"
    class="next">Next</a>
    </div>
    </div>

  3. Next, we will include CSS styles in our HTML as follows:
  4. style>
    .wizard { width:300px; overflow:hidden;
    border:1px solid black; }
    .wizardNavigation { overflow:hidden;
    border-bottom:1px solid #D2D2D2; }
    .wizardNavigation li { float:left; list-style:none;
    padding:10px; cursor:default; color:#D2D2D2; }
    .wizardNavigation li.active { color:#000; }

    .wizardBody { clear:both; padding:20px; }
    .wizardActionButtons { padding:10px;
    border-top:1px solid #D2D2D2; }
    .wizardActionButtons .back { float:left; cursor:pointer; }
    .wizardActionButtons .next,
    .wizardActionButtons .finish { float:right; cursor:pointer; }
    .wizard .disabled { color:#D2D2D2; }
    </style>

  5. Next, we will place JavaScript before the closing tag:
  6. <script>
    var submitThePage = function (buttonDirection){
    var $currentTab = $('.wizardNavigation li.active');

    if(buttonDirection == 'next')
    var $actionTab = $currentTab.next('li');
    else
    var $actionTab = $currentTab.prev('li');

    var target = "ajax/"+ $actionTab.attr('id') +".php";
    $.get(target, {'param':'test'},
    function(data) {
    if(data){
    if($actionTab){
    $currentTab.removeClass('active');
    $actionTab.addClass('active');
    }
    displayFinishButton($actionTab.hasClass('last'));
    displayNextButton(!$actionTab.hasClass('last'));
    displayBackButton(!$actionTab.hasClass('first'));

    $('.wizardBody').html(data);
    }
    });
    }

    var displayBackButton = function(enabled){
    enabled == true ?
    $('.back').show() : $('.back').hide();
    }

    var displayNextButton = function(enabled){
    enabled == true ?
    $('.next').show() : $('.next').hide();
    }

    var displayFinishButton = function(enabled){
    enabled == true ?
    $('.finish').show() : $('.finish').hide();
    }
    </script>'

  7. The result is as follows:

How it works...

The wizard is divided into three parts:

  • The first part is wizardNavigation, which includes all the steps (tabs) in the wizard.
  • The second is wizardBody, with the content of the current step (tab).
  • The last part is wizardActionButtons, which contains the Back, Next, and Finish buttons. The Back and Next buttons trigger the submitThePage function with the buttonDirection parameter (Back or Next). This function sends the Ajax request on to the next step, which is represented by the target parameter in $.get() function. The target is taken automatically from the tab navigation. It is equal to id attribute of each navigation element.

There's more...

We have understood the basic idea of Form Wizards. But sometimes we do not have the time or resources to create our own jQuery functionality. In that case, we can just use some of the free jQuery plugins, such as the formwizard plugin from http://plugins.jquery.com/project/formwizard. Not all plugins are 100% functional; everything has its own 'bugs'. However, help is always easily available. We can modify the plugin to meet our requirements and then wait for the bugs to be fixed in the next release of the plugin, or we can just contribute.

Uploading a file using Ajax

In this recipe, we will talk about uploading a file via Ajax. Actually, there is no Ajax method to do this. We can use the iframe method to imitate the Ajax functionality.

Getting ready

In the beginning, we will prepare the uploads folder and make sure it is accessible. In Mac OS X/Linux, we will use:

$ sudo chmod 777 'uploads/'

In Windows 7, we can right-click on Folderproperties|Edit|Selectuser| Group from permission windows (choose anyone) and select Fullcontrol under the Allow column to assign full access rights control permissions .

Now let's create an HTML (ajaxUpload.html) and a PHP file (ajax/uploadFile.php).

How to do it...

  1. ajaxUpload.html will look like the following:
  2. <script>
    function submitForm(upload_field){
    upload_field.form.submit();
    upload_field.disabled = true;
    return true;
    }
    </script>

  3. Our HTML body is as follows:
  4. <h1>Uploading File Using Ajax</h1>

    <form action="ajax/uploadFileSingle.php" target="uploadIframe"
    method="post" enctype="multipart/form-data">
    <div class="fieldRow">
    <label>Select the file: </label>
    <input type="file" name="file" id="file"
    onChange="submitForm(this)" />
    </div>
    </form>

    <iframe id="uploadIframe" name="uploadIframe"></iframe>

    <div id="placeHolder"></div>

    'ajax/uploadFile.php' content:
    <head>
    <script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="../js/jquery-1.4.4.js"></script>
    </head>

    <body>
    <?php
    $upload_dir = "../uploads";

    $result["status"] = "200";
    $result["message"]= "Error!";

    if(isset($_FILES['file'])){
    echo "Uploading file... <br />";
    if ($_FILES['file']['error'] == UPLOAD_ERR_OK) {
    $filename = $_FILES['file']['name'];
    move_uploaded_file($_FILES['file']['tmp_name'],
    $upload_dir.'/'.$filename);
    $result["status"] = "100";
    $result["message"]=
    "File was uploaded successfully!";
    } elseif ($_FILES['file']['error'] ==
    UPLOAD_ERR_INI_SIZE) {
    $result["status"] = "200";
    $result["message"]= "The file is too big!";
    } else {
    $result["status"] = "500";
    $result["message"]= "Unknown error!";
    }
    }
    ?>
    </body>>

  5. Initiate the result message on $(document).ready:
  6. <script>
    $(document).ready(function(){
    $('#placeHolder', window.parent.document)
    .html('<?php echo htmlspecialchars($result["message"]); ?>');
    });
    </script>

  7. The result is as follows:

How it works...

As we can see in this task, we created a simple form with the ability to upload a file. The main point of this example is in iframe, to which we are submitting the form. This iframe represents a container with PHP, which provides the physical upload of selected file. When the upload is successful, we will display the result message in placeHolder in the parent document.

There's more...

To increase the maximum allowable size of uploaded file we can use the upload_max_filesize directive in php.ini. There are more directives for uploading files:

Directive

Default value

 

file_uploads

1

Allow/Disallow HTTP file uploads.

upload_tmp_dir

NULL

Temporary directory for storing files during the file upload.

upload_max_filesize

2M

The maximum size of uploaded file.

max_file_uploads

20

The maximum number of file uploads made simultaneously.

 

Creating a five star rating system

In this task, we will learn how to build a five star rating system. This feature is often used by e-commerce websites to allow the rating of products, articles, or anything that is worth evaluating by the user.

Getting ready

Let`s prepare a dummy PHP file ajax/saveRating.php to confirm the rating was saved:

<?php
$result = array();
$result["status"] = "";
$result["message"] = "";

if(isset($_POST["itemID"]) && isset($_POST["itemValue"])){
$result["status"] = "OK";
$result["message"] = "Rating has been saved successfully.";
} else {
$result["status"] = "ERROR";
$result["message"] = "Provide itemID and itemValue!";
}

echo json_encode($result);
?>

We need to prepare a .gif image with stars. This .gif includes three variations of the star: the first, for the inactive star, the second, for an "on hover" event, and the third for the active star.

How to do it...

  1. We are ready to start with HTML part:
  2. <body>
    <h1>Creating Five Stars Rating System</h1>
    <div class="fieldRow">
    <label>Book 123A</label>
    <ul id="book-123a" class="ratingStars">
    <li></li>
    <li class="active"></li>
    <li></li>
    <li></li>
    <li></li>
    </ul>
    </div>
    <div class="fieldRow">
    <label>Book 123B</label>
    <ul id="book-123b" class="ratingStars">
    <li class="active"></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    </ul>
    </div>
    <div class="fieldRow">
    <label>Book 123C</label>
    <ul id="book-123c" class="ratingStars">
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li class="active"></li>
    </ul>
    </div>

    <div id="placeHolder"></div>
    </body>

  3. Let's include jQuery library and define the JavaScript functionality:
  4. <script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="js/jquery-1.4.4.js"></script>
    <script>
    $(document).ready(function(){
    $('ul.ratingStars li.active').prevAll().addClass('active');

    $('ul.ratingStars li').each(function(){
    var $item = $(this);
    var $itemContainer = $item.parents('ul.ratingStars');
    var containerID = $itemContainer.attr('id');
    var $itemsAll = $itemContainer.find('li');

    $item.mouseover(function(){
    $itemsAll.addClass('default');
    $item.prevAll().addClass('highlighted');
    })
    .mouseout(function(){
    $itemsAll
    .removeClass('default')
    .removeClass('highlighted');
    });
    .bind('click', function(){
    var itemIndex = $itemsAll.index(this);

    $.post('ajax/saveRating.php',
    {'itemID':containerID, 'itemValue': itemIndex},
    function(data) {
    if(data && data.status == "100"){
    $item
    .addClass('active')
    .removeClass('highlighted');
    $item.nextAll().removeClass('active');
    $item.prevAll().addClass('active');
    } else {
    alert('Error!');
    }
    }, "json");
    });
    });
    });
    </script>

  5. CSS is one of the key parts in this task:
  6. <style>
    label, ul { float:left; }
    .fieldRow { clear:both; margin:5px 0px; overflow:hidden; }
    ul.ratingStars { list-style:none; margin:0px 0px;
    overflow:hidden; }
    ul.ratingStars li { float:left; width:16px; height:16px;
    background:url('icons/star.gif') no-repeat left top;
    cursor:pointer; }
    ul.ratingStars li.active { background-position: 0px -32px; }
    ul.ratingStars li.default { background-position: 0px 0px; }
    ul.ratingStars li.highlighted,
    ul.ratingStars li:hover { background-position: 0px -16px; }
    </style>

  7. Our result is as follows:

How it works...

Basically, the whole rating system is an unordered list of items. Each item represents the star, which can be provided in three states; default, active or highlighted. The change of the state is done by the change of the background position of each star. In our case, we are using icons/star.gif, which includes all three possible states (gray, red, and yellow). There is a mouseover event defined, which will highlight the hovered star and all previously selected stars. After clicking on the star, we call an Ajax post request to ajax/saveRating.php and set all the required stars to be activated.

There's more...

In most cases, we don`t want to allow multiple voting for one user. In that case, we can set the cookie as follows:

...
if(isset($_POST["itemID"]) && isset($_POST["itemValue"])){
setcookie("rated".$id, $id, time()+60*60*60*24*365);
$result["status"] = "OK";
$result["message"] = "Rating has been saved successfully.";
}

When the cookie is set to expire in one year we can use it in our rating system:

if(isset($_COOKIE['rated'.$id])) {
$result["status"] = "550";
$result["message"] = "Already voted!";
}

echo json_encode($result);

Summary

In this article we learnt some basic Ajax utilities such as, validating a form using Ajax, creating an autosuggest control, form wizards, uploading a file using Ajax, and creating a five star rating system.



PHP Ajax Cookbook Over 60 simple but incredibly effective recipes to Ajaxify PHP websites with this book and ebook
Published: December 2011
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Milan Sedliak

Milan Sedliak is a JavaScript specialist, jQuery and Cross-browser compatibility is one of his key strengths. He likes challenging tasks and he does everything he can to be at his best in this area. He has experience with all kinds of websites and a lot of technologies (eight+ years). Portfolios, company presentations, e-commerce, complicated reporting systems for telecommunication devices, PHP websites with MySQL or MS SQL, ASP.NET 3, 5 and 4 (C#) with MS SQL, etc.

He has a lot of experience in international environments and is currently employed by Skype as a software engineer specialized in front-end web technologies and cross-browser compatibility. In the past he has worked at Hewlett-Packard, Interoute and Intertec Media Group.

Books From Packt


iPhone JavaScript Cookbook
iPhone JavaScript Cookbook

PHP jQuery Cookbook
PHP jQuery Cookbook

AJAX and PHP: Building Modern Web Applications 2nd Edition
AJAX and PHP: Building Modern Web Applications 2nd Edition

phpList 2 E-mail Campaign Manager
phpList 2 E-mail Campaign Manager

Facebook Application Development with Graph API Cookbook
Facebook Application Development with Graph API Cookbook

Django JavaScript Integration: AJAX and jQuery
Django JavaScript Integration: AJAX and jQuery

CakePHP 1.3 Application Development Cookbook
CakePHP 1.3 Application Development Cookbook

Google Web Toolkit GWT Java AJAX Programming
Google Web Toolkit GWT Java AJAX Programming


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
r
5
R
d
Y
Z
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software