TeleFlowRelay AJAX Tutorial

TeleFlowRelay AJAX Tutorial

From TeleFlow

Jump to: navigation, search

This page provides an overview and instructions on how to build an AJAX application that will add additional components (such as buttons, or other clickable objects) to the web page, and have them operate without the need to refresh. This tutorial references the TeleFlowRelay web foundation, which includes an application that incorporates jQuery to provide cloning.

  • To help us improve this tutorial, and support for the TeleFlowRelay Web Foundation, please visit our Forum
  • This AJAX tutorial references a Bar Code graphics creation page. To see what you will be working with before you get started, take a look at a screen shot first. All this code is included in the download found in the Forum.
  • Please note that the Bar Code example, and not the Lab Results, is included with the code. No database is needed for this example.
  • This page needs: Clarification of cloning, and an an easier to follow walk through. Feed back should help form this up a bit better.

submit to reddit

Contents

How to Develop and AJAX / XML Web Application

This entry describes the step by step process you will need to work through to develop an AJAX (Asynchronous JavaScript and XML) / XML web page. Essentially, there are three parts to an AJAX web application:

  • HTML web page client with JavaScript - Note: PHP will create and combine the standard page layout at the server, and then provide it to the brower client
  • JavaScript to communicate between the web client and a server PHP application (For our demo set of files, they are found in directories named as '*_xml.php')
  • A PHP XML processing application (mentioned above) which accepts XML from JavaScript running in the browser client, communicates to the database server, and returns XML for processing by JavaScript on the client.

In effect, and using software such as jQuery JavaScript library, pages can be dynamically modified based on XML data returning from PHP code. Warning: This is not easy to code! If you haven't done this before, expect to spend a week just learning how it all fits together before getting very far. However, once you have a feel for it, and have mastered knowing when to reference helper Apps like FireBug, you will be moving forward much sooner.

Please note that this document relates to files created using the "engenic_app_root" files found in the TeleFlowRelay download. We call it that, because the web applications built by engenic are all found at this root directory.

What Is AJAX

AJAX is a term applied to a style of development for web applications. AJAX stands for Asynchronous JavaScript and XML, and is the cornerstone of Web 2.0 development. The core concept is that any web page that uses Web 2.0 capabilities can dynamically build content potentially running on several threads.

AJAX is essentially provided by having the browser (or client) running JavaScript being constantly in contact with web server, which is processing with PHP. This client/server relationship then uses XML to express information and requests for it back and forth.

Standard Configuration

Although there are several methods for deploying AJAX applications, a general approach and the one used for this document is:

  • JavaScript and FireFox (with FireBug for debugging) and all browsers supported at end
  • PHP for deploying HTML (which includes links to JavaScript and CSS) to the browser
  • PHP accepting and processing XML for AJAX (JavaScript communications)

The files are being served by Apache running PHP, but could just as easily be deployed in IIS running PHP. The database used is MySQL, but the Bar Codes examples does not need a database. If you are not familiar with installations of web services, you might want to use XAMPP (Windows or Linux) available from

  • XAMPP: www.apachefriends.org/en/xampp.html

The site uses examples from a simple Lab Results input screen from our MedicalRelay product, as well as the Bar Codes generator website. The latter is provided in the TeleFlowRelay download, and includes a set of example files you can deploy on your web server to modify to see how it all works.

Tools You Need

Libraries

  • TeleFlowRelay platform (files in "engenic_app_root"): This is the software that manages most of engenic's web developments, as well as other company's applications including MedicalRelay, Cheap UPC Barcodes, and others.
  • jQuery: This is embedded in the TeleFlowRelay installation as "library_js", however, if you are building a stand alone system, you might want to include this library directly in your code.
  • jQuery Addons: jQuery.TimeEntry, jQuery.Timer, jQuery.MaskedInput, jQuery.DatePicker and others. Note that these are included in the engenic_root_app.

Please note that TeleFlowRelay Web Foundation installs all these components. For information on how to install this environment, find the links in TeleFlowRelay.

When it comes to JavaScript libraries, ensure that they are visible to the browser as they are loaded directly into your browser before your page completes its load. You will need to place these files in a location on the website above the "htdocs" folder in order for the website to serve them by request. PHP libraries on the other hand, because they are only accessed by the server and not the browser, may be located anywhere on the drive. It can be helpful to address security concerns by having key files located below the reach of the browser.

Open Source Helper Applications

We recommend that you have these programs installed on both your development computer. Each runs in Windows perfectly, and very well in Linux using Wine.

  • TFHTTPXMLPost.exe - find this at http://teleflow.org, and put it in the *_xml directory for the application you are building in. This tool was created by engenic to quickly test XML document posts, and is a lifesaver.
  • NotePad++: This is a great editor, but anything that can express and/or highlight tag pairs will work.
  • FireFox with FireBug: Essential. Without this product, you will not get far along at any rate. FireBug is what makes it possible to debug AJAX.
  • HeidiSQL: A great MySQL database interface. Highly recommended.
  • Documentation tool: Something you can use to make notes which will then be entered into a wiki, or other documentation formation.

As mentioned, if you do not have a local (that is, on your computer) installation of Apache/PHP, you might want to consider downloading and installing:

  • XAMPP: www.apachefriends.org/en/xampp.html

It's best to have the GUI applications running as you will be jumping back and forth between them frequently.

Formulating in XML and Its Advantages

When developing the code for sending a Request that will receive a Response, make sure that the Responses are designed to be as identical as possible! This effort includes, and where possible, providing the full set of fields, and the names of the elements. This way, you can reuse, via procedure calls, good portions of JavaScript where you pass XML structures back to from jQuery AJAX calls.

XML was used in AJAX because it provides a standard means of expressing data which can then be readily broken down and processed by the environment receiving it. Advantages of using XML include:

  • It replaces direct references to SQL statements to databases from within JavaScript. This provides the opportunity to create a more secure environment if done properly. For additional information on a famous security breach of older websites, look up "SQL Injection Attack". There is also a code snipped below that should be involved in all Client to Server communications.
  • Ease of manipulation of data for processing against a database or other information source at the server end, and then also for reporting back on the JavaScript / browser end. Using XML helps bridge the two programming environments to a degree.
  • Re-usability comes with a general standard for accessing information. For example, the XML Request and Response structures can be readily used by other non-web environments including TeleFlow Speech Server applications, or compiled code applications build in C++/C#,Delphi,VisualBasic and other environments.
  • Layered development using XML to access data also means that should your data source need to shift from MySQL to SQL Server, you will only need to changes the data structures and means of access in the "*_xml.php" files. This provides your application with a level of future proofing.
  • A single web page (with no refreshing) for your entire application can be achieved using XML to command and guide changes by. Because XML has become a strong standard, you will be able to readily adopt data from other XML information sources at the server end, and then combine it for re-display in JavaScript. Building rich websites becomes easier when thinking in XML.

JSON Option

XML is not dead simple. In fact, it's awkward to work in. For that reason, a simplified version of it has been developed, and its called JSON. With it, you can potentially save some manipulation effort. It's something worth mentioning, but not essential. XML, after working with it for a few days does become easier as time goes on.


Example Applications

Lab Results

Lab Results is a simple edit entry screen which allows you to add entries manually. It is useful because it also include a calendar and review. It relies on the following files

  • eng_medicalrelay/mr_labresults-entry.php - The entry screen
  • eng_medicalrelay_xml/xml_medicalcmd.php - The program that handles the PHP

Bar Codes (Included in TeleFlowRelay)

For the Bar Code web pages, the equivalent files are

  • bc_infoweb/bc_index.php
  • bc_infoweb/bc_ajax_barcodes_commands.php

Getting Started

To use the code, first install the TeleFlowRelay web foundation. This whole process should take about 10 minutes, but currently does require that MySQL is also installed.

Assuming you understand how to generate a web page using HTML and PHP, the applications mentioned above will be watching for XML requests, will generate additional HTML information and/or provide XML in response which can then be used to update the web page.

Lets get an XML statement working to see the effect. When you first get started, use the TFHTTPXMLPost.exe HTTP_XML_Post_testing_tool program (see download in this wiki) to test that the "hello" function is working. Copy this command:

<REQUEST action="Hello" seconds="2"></REQUEST>

into the program with the location of the file for your development environment

http://localhost/engenic_app_root/eng_medicalrelay_xml/xml_medicalcmd.php

or

http://localhost/engenic_app_root/bc_infoweb/bc_ajax_barcodes_commands.php

On pressing the "Post" button, you should see the following result:

<RESPONSE action="Hello">
<SUCCESS action="Hello" result="SUCCESS" type="DB">Hi back: Database is up. 
We are here to serve</SUCCESS></RESPONSE>

This should be your starting point. In fact, you can test for this when you start your program running to make certain that the environment is even available. See the lab results entry program for an example.


Barcode Generator

Our example application uses in addition to jQuery, PHP and several other libraries, a bar code creation component which creates bar codes from 10 digit numbers provided to it. The Barcode Generator is a class provided by:

  • Jean-Sebastien Goupil

It can be downloaded from barcodephp.com, however we have also included the class in the TFR installation in order to run the examples which are be provided in this tutorial.

Configuration

If you are using the TeleFlowRelay web foundation, then before you start running tests, and creating routines to start plugging data into databases, ensure that your database connections are set correctly.

  • LocalSettings.php - check the ($cGlobalMode = MODE_TEST; and $cGlobalDebug = TRUE;) near the top, and compare in:
  • LocalSettings_Database.php

Useful Variables

If you are using the engenic_app_root's security mechanism, then you might want to gather security information for use in your code to limit access for the session. This is related to the security system build into TeleFlowRelay, and not applicable to the demo, but you should be aware of this in case there are access issues. With the Bar Codes demo, there is no authentication, so you could simply run the web pages and bypass the security system. This useful for XML commands etc.

$ClientID = $_SESSION['userclientid'];
$UserID   = $_SESSION['userclientid']; 
$UserName = $_SESSION['username'];

NOTE: To bypass the security system, change session.php to session_nodb.php at the top of each page. (( More to follow ))

Relative Files Names

For the purposes of this document, the following files relate to the names.

  • Input screen:
    • mr_labresults-entry.php
    • bc_index.php (barcode.php)
  • AJAX manager or processing application:
    • mr_ajax_labresults_commands.php
    • bc_ajax_barcodes_commands.php


Developer Skills

Your system will comprise of reading writing data, and then building and extracting data to and from XML, in both PHP and JavaScript. Most likely, this data will be derived from a database, but it could come from other sources including additional XML request and response applications. Once you have built the database, you will need to display and edit using HTML. Because of this, you will need skills in:

  • PHP
  • JavaScript
  • jQuery, an extension build on JavaScript
  • XML (and/or JSON)
  • HTML and Web design
  • CSS
  • For most applications: SQL for MySQL (or other database)

In fact, you should probably not be creating much HTML initially, just the minimum to display the layout, and data. Much of your HTML experience should be limited, and you following using classes so that you can change the look and feel in CSS. This is all incredibly annoying stuff, and may even be hazardous to your health and the general well being of those around you.

If you are looking for a great resource to understand some of the above concepts better, check out:

Website Design

Before getting too far, try and determine how you are going to layout the DIVS, or sections on the page.

  • Draw on paper, the names of your DIVs, or boxes that will hold functionality
  • Name their SPANs, so that you can refer to them in code
    • labresults_reportdate_box
    • labresults_report_box
    • labresults_dataentry_box
    • labresults_search_box

The barcode named DIVS in the barcode example are apparent.

Cloning Introduction

This is a brief description of cloning ahead of the section where it is applied provided to give you a sense of its need.

When you load a page in a browser, the JavaScript also loaded is made aware of all the interactive objects (buttons, fields, check boxes etc) just once at the end of the load. This means that the screen need to have all the objects defined in order for events (such as onClick) to be recognised specifically for each of them.

If you do not know how many objects you are going to display, then you could create x number for a "hopefully" worst case scenario. This is plainly messy if you could have potentially hundreds of various of objects needed after a load.

Immediately, you might think, that you can just have a JavaScript snippet add more HTML objects to the browser at any point after the page load, and those objects will be as good as any defined at the initial page load. For example, if you wanted to add a button to get information on each client (id: 8487 in example) displayed, you might add this code to a row or DIV:

<input id="ClientButton_8487" class="infoButton" value="Client Info" />

However, by having JavaScript create HTML objects based on an after page load event, JavaScript will not be able to also assign it events. Clicking on the button will not, in this case, fire the "onClick" event so that jQuery can act on the request.

So, here is where cloning is needed.

The way to get around this is to create a button, or any object with the events assigned to it, at page load time, set it as hidden, and then clone and display it each time it is required. Cloning provides a means for all the events associated with an object to also be recognised.

To approach cloning, you may need to create clone DIVs and/or tables "rows" which are used to dynamically create new content to be inserted into your DIV blocks. Clone DIVs and/or tables "rows" are used so that jQuery can interact with them to populate new data to the browser. Nice effects can be applied such as "fadeIn" which is available in jQuery.

  • labresults_report_entry
    • Note: You will clone these to labresults_report_entry_clone. That way, you will not accidentally remove the original.

Once you have completed the clone DIVs, you will need to define the containers in which they will be created.

  • labresults_report_container
    • eg: <table id="labresults_report_container"...

Ensure any SPANS are properly nested in the DIVs. This is really an issue of aesthetics. Keep in mind that DIV in DIVs with a common class name will enable you to change the look en-mass, but that you are going to want to class each block with different names so that you can move them around the web page at the final part of the development effort.

See examples in Barcode Generate where both types of cloning are applied.

Development Effort

As you are going to need to have clone-able sections and additional display elements (underpinnings) for the web page created by responding to XML requests, you may as well define those first, and then build them. This is probably the hardest part, as it requires planning, should be well described and then very carefully developed. Having said that, once you build one XML Request and Responses, the rest becomes much easier. Just be mindful before you start out that you are covering every data read, write, and error possibility for your page. It's best not try and get away with writing just enough to get started, as you will be wasting time later having to go back again and again to build new sections. But again, your first AJAX project should only have one or two reads and a write, so that you get somewhere fast and see results in order to gain a psychological victory.

To recap, it is a very good idea to understand what the scope of data is, and how it will display to your web page following the initial web load. This vision should be solid, and well planned before building the page.

Planning and building the XML request and response structure has many benefits:

  • You determine your field naming conventions early, so problems are quickly found.
  • Create the database tables, so that naming conventions are succinct.
  • You build code relatively quickly once you get started.
  • You have the underpinnings to test data flow with once completed.
  • XML statements can immediately also be used by TeleFlow server, or other environments.
  • You are starting the technical documentation (if you follow the example described here)

Make certain when you develop these routines that:

  • You make the Primary Key (PK) available everywhere. Please see "database normalisation" for more information.
  • Ensure that client rules are enforced so that one client doesn't accidentally kill another's data. By client, we mean the users of your system. This oversight is common. Please note that TeleFlowRelay includes provisions for separate client databases, which can be very beneficial for secure multi-client applications.
  • Also, highly recommended, is a mechanism to create all your tables and indexes within the XML processor if they do not already exists. This helps for quick deployment of applications to other servers, and keeps the database documentation close by.
    • Note: Review xml_medicalcmd_functions.php for an example of how to create tables.

XML Commands Back and Forth

Start your development effort by creating all the commands. For example the Bar Codes example has very few commands, but the Lab Results use the following commands:

For the Bar Code example, here are screen shots of the XML command that is generated by JavaScript/jQuery and sent to PHP for processing. FireBug is very helpful to see what goes on beneath the hood.

The response that PHP returns is this:

What happened here, is:

  • PHP received the XML
  • PHP ran the number through the Barcode Class mentioned earlier
  • The class generated the image and then a responded to the request by JavaScript saying: "Here is your new image file and where its located."
  • Back at the web client, jQuery received the response, and the then did a fadeIn function to display it

Finally, jQuery then created a clone DIV, and displayed a smaller version of the bar code to it.

This is what the cloned element looks like. Note that the original clone template at the top is never shown, and just provided for cloning purposes.


CreateDatabase
<REQUEST action="CreateDatabase"></REQUEST>

Returns:

<RESPONSE action="CreateDatabase"><SUCCESS action="CreateDatabase" 
result="SUCCESS" type="DB">Tables exist or have been created</SUCCESS></RESPONSE>

Using the Lab Results example, the following requests where developed ahead of time:

ListLabResultsForDate
<REQUEST action="ListLabResultsForDate"
client_id="376"
entry_date="2009/01/19"></REQUEST>

Returns:

<RESPONSE action="ListLabResultsForDate" result="SUCCESS" type="DB"
client_id="1234" entry_date="2009/01/19"
labresultstotal="2">
<LABRESULT count="1" labresult_id="4" pat_id="" pat_id_human="N/A" 
pat_first="Bob" pat_last="Best"  pat_tele="6045550310" pat_tele_human="(604) 555-0310" 
phy_first="Bill" phy_last="Simpson" lab_result="NORMAL" 
lab_call_status="ADD">NORMAL</LABRESULT>
<LABRESULT count="2" labresult_id="5" pat_id="" pat_id_human="N/A" 
pat_first="Sally" pat_last="Mann" pat_tele="6045551110" pat_tele_human="(604) 555-1110" 
phy_first="Bill" phy_last="Simpson" lab_result="NORMAL" 
lab_call_status="ADD">NORMAL</LABRESULT>
</RESPONSE>
AddLabResult
<REQUEST action="AddLabResult"
client_id="1234"
pat_id="991"
pat_first="Janis"
pat_last="Zalcron"
pat_tele="6045551234"
phy_first="Paul"
phy_last="Simmons"
lab_result="NORMAL"></REQUEST>

Returns:

<RESPONSE action="AddLabResult" result="SUCCESS" type="DB">
<LABRESULT 
labresult_id="17" pat_id="991" 
pat_first="Janis" pat_last="Zalcron" 
pat_tele="6045551234" pat_tele_human="(604) 555-1234" phy_first="" 
phy_last="Simmons" lab_result="NORMAL" lab_call_status="ADD">
</LABRESULT></RESPONSE>


UpdateLabResult
<REQUEST action="UpdateLabResult"
client_id="1234"
labresult_id="1633"
pat_id="991"
pat_first="Janis"
pat_last="Zalcron"
pat_tele="6045559999"
phy_first="Paul"
phy_last="Simmons"
lab_result="NORMAL | CONTACT"></REQUEST>

Returns:

<RESPONSE action="UpdateLabResult" result="SUCCESS" type="DB"><SUCCESS 
labresult_id="16"></SUCCESS></RESPONSE>

or

<RESPONSE action="UpdateLabResult" result="ERROR" type="DB"><ERROR 
labresult_id="1633"></ERROR>Record not found</RESPONSE>

or

<RESPONSE action="UpdateLabResult" result="ERROR" type="CMD">Mandetory parameters 
are missing</RESPONSE>


DeleteLabResult
<REQUEST action="DeleteLabResult"
client_id="376"
labresult_id="888"></REQUEST>

Returns:

<RESPONSE action="DeleteLabResult" result="SUCCESS" type="DB"><SUCCESS 
labresult_id="5"></SUCCESS></RESPONSE>

or

<RESPONSE action="DeleteLabResult" result="ERROR" type="DB"><ERROR 
labresult_id="888"></ERROR>Record not found</RESPONSE>


HTML & JavaScript Development

This is a bit of an open ended statement, but at this point, the web layout and JavaScript development to read and effect change on the web page need to be implemented. Keep the following in mind when writing the application:

  • Use class names for everything so that the CSS can be worked on independently or at a later date when you are wearing your artistic hat, rather than the engineering hat you need for JavaScript.
  • Minimize the use of HTML. If you are trying to do things like bolding text, adding colors, or changing font sizes, then stop immediately, because you are doing it wrong. The screen should only have input elements, basic text, and possibly tables just because its important to see the screen doing something while you are working on it. At this point, you should not be overly worried about layout. That should come once you get to the CSS part near the end.
  • Wrap DIV tags around blocks of input or edits. DIV tags enable you to move around sections by defining them in CSS later.


Implementing AJAX

There is a lot going on to follow initially, but will be easier to follow once the concepts settles in. Essentially, this is what needs to happen:

  • User types in or clicks on something creating a jQuery event.
  • The event is handled in JavaScript, and Requests data from a PHP appliciaton on the server
  • A POST request is created with parameters within JavaScript using the jQuery AJAX command, and posted to a PHP server page
  • The server page reads all the post items, and formulates an XML document which is then processed later in the server page
    • Note: This has been done to ensure that all requests are posted in XML. There are many reasons for this including extensibilty for use by other services.
  • The server page does work with the database or other sources, and then compiles an XML response.
  • That response is then returned to the JavaScript jQuery AJAX command
  • The XML document is then parsed, and new information is displayed in a DIV, cloned DIV, or cloned table row on the screen. This becomes the dynamic data.

This is a lot of movement of data. For that reason, you will make a tonne of mistakes. The best thing to do is the keep the TFHTTPPost tester program available, and make sure you have a command that is returning data from the server pages that do precisely that.

When you get to the point where you have jQuery AJAX sending requests, you will need to intercept the POST command in the AJAX commands processor, and recreate the XML. You have save it to a file or print it to the screen to compare that you have something which can then be tested via the TFHTTPPost tester again. If it returns results, you are a good way there.

This is where FireBug becomes essential. When running AJAX commands, watch the Console. Here you will see Post events with the Post contents, and most importantly, the Responses. Once you see the responses being returned, you will be able to use JavaScript to break up the XML document and then display it how you wish.

This is where cloning becomes the challenge, as a lot of putting together of data, breaking a part of data, reassigning to new variables and SQL statements and then back out again, etc. It can be overwhelming at worst, and laborious at least.


Why Cloning

Cloning is one of only a few methods which provides new data with event management. For example, if you created a new input field without cloning, and you typed something in that field, no events would fire. This is because you need to let JavaScript know about the events before the page is loaded. The only way around this is to clone a section of HTML that have the events defined. This then tricks JavaScript into processing the event of the template to be cloned, and returns the results accordingly.

This is very clever, but obnoxious to work with.

Cloning using jQuery

jQuery is magic and saves the day. jQuery makes this method simple, so long as there is a good template to start with. The best way to express how to do this is to look at the example code. Essentially, you need to create a DIV with all the events predefined. The DIV can then be cloned, and the events will be duplicated. If you were just to dynamically create new elements, JavaScript is unaware of the events. Cloning: the only way to create new elements that jQuery will be able to function for.

Here is an example of cloning you might see in the JavaScript

// this will grab the last table row.
var clonedRow = $("table tr :last).clone(); 
 
// use the selectors to
// manipulate any element in the clonedRow object.
$("#formField", clonedRow).attr("id", "newID"); 
 
//add the row back to the table end of the table
$("table").append(clonedRow);

With the Bar Codes example, you will see this clone-able template in the code (bc_index_contents.php):

	<table id="barcode_report_table" class="tblTable">
	<body>
		<!-- CLONE TEMPLATE for CLONING-->
		<tr class="tblRow" style="display:none">
			<td id="tblFld00">
				<input type="radio" style="" 
					value="0" 
					name="barcode_report_item" 
					id="barcode_report_item" 
					attr_barcode_zip=""
					attr_barcode_id=""
					attr_barcode_image=""
					attr_barcode_imagesmall="" />
			</td>
			<td id="tblFld01"></td>
			<td id="tblFld02"></td>
			<td id="tblFld03"></td>
		</tr>   		
		<!-- CLONE TEMPLATE for CLONING-->
	</body>
	</table>

This is processed by jQuery in the JavaScript section to create a clone right below it after the AJAX request returns the location of the new image (bc_index.php):

// Generate the field for a table
function generateField(pClone, pId, pClass, pValue)
{
	pClone.find(pId).removeClass().addClass(pClass).text(pValue+' ');  // Space ensures that IE draws a box
}
function generateFieldHTML(pClone, pId, pClass, pValue)
{
	pClone.find(pId).removeClass().addClass(pClass).html(pValue+' ');  // Space ensures that IE draws a box
}
 
/ Build a line to drop into the table
function buildLine(pCloneRow, pDoc, pFile)
{
	// Put in a tracker attribute so we can find later
	pCloneRow.attr("style",""); // Make visible
 
	// Add the values to the Radio button for reference later 	
	pCloneRow.find("input").attr("attr_barcode_id", 			$(pDoc).attr('imagefile'));
	pCloneRow.find("input").attr("attr_barcode_imagesmall", 	$(pDoc).attr('imagefilesmall'));
	pCloneRow.find("input").attr("attr_barcode_zip", 			pFile);
 
	// Do some creation of the fields
	generateFieldHTML(pCloneRow, "#tblFld01", "tblFld01", '<img src="'+$(pDoc).attr('imagefilesmall')+'"/>');
} // buildLine
 
 
//  Set up jQuery - Now is a good timeto see if it will fly / load up the libraries	
//  Interact with PHP system using AJAX
$(document).ready(function()
{
	////////////////////////////////////////////////////////
	// Create Barcode
	////////////////////////////////////////////////////////
	$("#add").click(function()
	{
		// Display work
		$("#spinner").show();
		// Show the report box
		$("#barresults_report_box").show();	
		//alert('he'+$('#txt_updatedate').val());
		$('#barcodes_image_container').fadeOut(50);
 
		// Zip file
		var mZip='bc_'+$('#barcode').val()+'.zip';
 
 
		///////////////////////////////////
		// Now, get the XML for post etc
		///////////////////////////////////			
		$.ajax({ type: "POST", 
				url: "bc_ajax_barcodes_commands.php", 
				data: { command:'GenerateBarCode',
						barcode:$('#barcode').val(),
						zipfilename:mZip,
						gettype:'XML', 
						nocache_rand:Math.random() }, 
				dataType: "xml", 
				success: function(data)
				{	
					// Populate barcode Information
					$(data).find('RESPONSE').each(function()
					{
						// Did we get something
						if ( $(this).attr('result') == 'ERROR')
						{
							//alert("Error");
							$("#msgbox").removeClass().addClass('messageboxerror').text('Failed to create barcode').fadeIn(10);
						}
						else
						{
							mCount=0;
							$(data).find('BARCODE').each(function()
							{
								//alert( $(this).attr('imagefile') );
								mText = '<br /><img src="'+$(this).attr('imagefile')+'"/><br /><br />';
								$('#barcodes_image_container').html(mText).fadeIn(1000);
 
								//////////////////////
								//Report Line
								//////////////////////
								$("#inputHelp").removeClass().addClass('inputinfodiv').text('Ready for use!').fadeIn(10);
 
								// Remove the value
								$('#barcode').val('');
								// Focus the cursor back on the add field
 
								$("#barcode").focus();
 
								//////////////////////
								//Report Line
								//////////////////////
								// Draw a smaller version below
								// *** Clone node assign ID attribute and fade in
								var cloneRow = $("#barcode_report_table tr:last").clone(true);
								cloneRow.attr("id", "barcode_report_entry_clone");
 
 
								// Put in a tracker attribute so we can find later
								cloneRow.attr("track_id", $(this).attr('barcode'));
								// Put in a tracker attribute so we can find later
 
								// Set up the report line with data and styles etc
								buildLine(cloneRow, $(this), mZip);
 
								//cloneRow.insertBefore("#labresults_report_container .itemtemplate:last");
								$("#barcode_report_table").append(cloneRow).fadeIn("fast");
 
								// Display the area
								$("#spacer").show();
 
								// Display the download button
								$("#download").show();
								$("#download").attr("disabled", "true"); // Disable it  for now
								$("#spinner").attr("style","display:none");
						    });
 
						}
					});		
 
				},
				error: function (xhr, desc, exceptionobj) 
				{
					//alert(xhr.responseText);					
					$("#spinner").attr("style","display:none");					
				}
 
		});
 		return false; //not to post the  form physically
	});

At this point for example, you might dynamically populate the attributes with information gathered from XML received from "*_xml.php".

jQuery and IE

jQuery is excellent, and should be learned well. It generally works well against all browsers, however some versions if IE do not work correctly with the following:

  • IE does not understand the "change" event. Make sure you use "click" instead and always.

Testing Commands

It is essential that your XML posts return the data they are expected to, and handle bad information correctly. The Test command is:

http://localhost/engenic_app_root/eng_medicalrelay_xml/xml_medicalcmd.php

In the barcode example:

http://localhost/engenic_app_root/bc_infoweb/bc_ajax_barcodes_commands.php

This command is a full, non-HTML application that accepts XML posts, works with the database or other information sources, and returns the processed results in XML. When building this command, be sure to:

  • Check for minimum mandatory parameters
  • Check for invalid data, and ensure appropriate response
  • Respond with a command Success or Failure method.

And most importantly,

  • Prevent SQL injection attacks

The last points helps make the JavaScript side easy to read and re-usable, and secure. SQL injection is only a concern if you are continuing data into a SQL statement. Attacks are easily prevented by running the data through this function found in library/CalcWorkUnit.php:

// Make SQL safe from SQL injects
function GetSQLSafeValues($theValue)
{
	// Ensure no SQL injections attacks
	return strtr($theValue, array(
	  "\x00" => '\x00',
	  "\n" => '\n', 
	  "\r" => '\r', 
	  '\\' => '\\\\',
	  "'" => "\'", 
	  '"' => '\"', 
	  "\x1a" => '\x1a'
	));
}

Even if your code does not integrate with a database, its a good measure to add this wrapper function to protect future use of the application.

Debug Mode

When adding the Debug flag to the end of the XML request command, you can get details about the SQL statement if it has been coded in

http://localhost/engenic_app_root/eng_medicalrelay_xml/xml_medicalcmd.php?DEBUG=TRUE

Improvements and Shortcuts

JavaScript

JavaScript is an horrendous, nasty, brutal language. Its hard to read, constructed in a strange way, it's hard to spot errors, and it seems to break even if you just look at it funny. Yet, it's actually pretty good, and happens to be the only way to build AJAX applications for the standard browser deployment. Again, the wonderful jQuery library takes a lot of misery out of it... once you become familiar with the incredibly odd manner in which it functions.

Manipulation of strings and date objects are handled differently than other languages, and takes some getting used to. If you are looking for something more conventional, check out a project by Kevin VanZonneveld. He has done something interesting, as he has written many of the PHP functions in JavaScript.

http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_wordwrap/

If you are new to JavaScript, it *might* be worth checking out. If nothing else, it reduces the amount of learning you need to do if you are already familiar with PHP.

Running for the First Time

By the "first time", we mean when you start testing you AJAX application.

DOM Errors

If nothing seems to be happening with the AJAX operations (check using FireBug to see if any results are coming back), and the contents of the response shows this:

"domdocument::domdocument() expects at least 1 parameter, 0 given in ..."

Then in the php.ini needs to be changed on your server environment. You will need to un-comment the following code from this:

; extension php_domxml.dll

to this:

extension=php_domxml.dll

Once done, then restart restart Apache. From a command line:

net stop apache2
net start apache2


CSS

This is probably the easiest and most enjoyable part unless you don't know CSS very well, in which case; prepare to be annoyed! In your CSS, start defining the classes which will define how you want all the elements to look. At this point, colors, font sizes, screen layouts, background graphics and all other beautification should be done now. DIVs should be defined and adjusted to maximize the screen utility.

Helpers

If you don't have it, get:

  • FileZilla Color Picker

This little tool will help you gather and paste colors into your CSS quickly and easily.


Final Touches

Testing Browsers

Before you get too far into any effort updating HTML and CSS, be sure to test in all the common browsers. You will be surprisingly annoyed at how much IE will not reflect what you have built in FireFox. For hints on what to stay away from, search for the words "Broken Box" and "margin" for cross browser development.

Usage
  • for Input Fields, prevent drop down suggest for input fields with: HTML: autocomplete="OFF"

Author

  • Vern Baker (vbaker at various email addresses)
  • engenic
  • Originally written April 2009