Basic Enterprise Application Realm

Basic Enterprise Application Realm Documentation

  • 1 PHP Reference
    • 1.1 Introduction
    • 1.2 shared_lib.php
    • 1.3 ac_tables.php
    • 1.4 ac_email.php
  • 2 Javascript Reference
    • 2.1 Introduction
    • 2.2 ac_ajax
    • 2.3 ac_event
    • 2.4 ac_filter
    • 2.5 ac_menu
    • 2.6 ac_panel
    • 2.7 ac_select
    • 2.8 ac_toc
  • 3 Forms
    • 3.1 Introduction
    • 3.2 How It Works
    • 3.3 AJAX
    • 3.4 form_processor_v2
    • 3.5 form_processor

3.3 AJAX

January 22nd, 2026

The recommended method for handling form submission is via the built-in AJAX mechanism exposed by the ac_ajax Javascript class. This class provides a simple method for registering a form and handling common server responses such as validation errors as well as enough flexibility to update other page elements.

Nearly all the Javascript bundled with BEAR is intentionally coded to require only DOM Level 0 (or extremely well supported functions). This provides the maximum amount of backwards browser compatibility.

There are a number of other Javascript libraries built into BEAR. Although these are not necessarily required for AJAX forms, they are commonly used with forms to provide an enriched user experience. These are documented in the Javascript section of the Developer Toolkit.

3.3.1 Logical flow

The ac_ajax class sends form data to the server's responder.php URI. However, unlike most other AJAX implementations the responses are neither JSON or XML. A subset of the proprietary SWAPI protocol is used for passing information back to the ac_ajax class. This has two benefits:

  • It is more secure than JSON because it requires explicit parsing and validation of content. The entire SWAPI payload must be both valid and refer to existing named IDs in the HTML otherwise the entire AJAX call will fail (preferred).
  • It is lighter and faster than XML.

If you are building a package called "my_app" and coding a user registration form, then the end-to-end exchange might be structured as follows:

Fig 1. Process and file relationships for AJAX

AJAX form processing

In this example the following happens:

  1. The browser requests the web page http://<domain>/my_app/register.acx`.
  2. Any pre-processing that is part of the embedded non HTML code in register.acx is handled on the application server (not shown in the diagram since this is not directly relevant to the AJAX discussion).
  3. The browser also loads in the ac_ajax class file (in this case from http://<domain>/javascript/ac_ajax_2.0.js`) and sets up the AJAX handler as an ac_ajax object. At this point, everything is running solely on the user's browser in whatever process space it uses.
  4. On form submission, the ac_ajax class within ac_ajax_2.0.js submits a request to http://<domain>/responder.php`.
  5. responder.php creates a new process/thread on BEAR and, according to the processing instructions passed from the ac_ajax object, it includes my_app/html_filters/register.php from the CGI directory (not exposed via HTTP), which in turn extends and includes the form_processor.php to provide generic form functionality.
  6. [OPTIONAL] If required, non HTML specific functions may be contained in other files to be included. Most commonly this would be in a monolithic class file my_app.php but could be different.
  7. The form input is processed and some action is taken together with generating some result to pass back the ac_ajax object running on the user's browser.
  8. responder.php takes a set of expected public properties from the class and method it called in my_app/html_filters/register.php and converts these to SWAPI protocol before sending this back to the browser.
  9. The ac_ajax object parses the SWAPI response which contains simple instructions for updating HTML on certain elements of the original register.acx code.

3.3.2 Creating the server-side form handler

As shown above, the developer needs to provide at least a class file (or add methods to an existing class file) for processing the form. Although not mandatory, it is assumed that in all cases, such a class will extend the built-in form_processor class.

The form_processor class is generic (not AJAX specific). Making use of the class is described in How It All Works.

Since AJAX is handled within HTML from Javascript, your form will need to be a file located within a directory called html_filters under your package's CGI directory. In the "my_app" example, all form handling class files would be located under:

/bear/web_applications/cgi/my_app/html_filters/

There is no recommendation on how many form processing class files to create. You could create one file per form; one file per logical group of forms or even one monolithic file containing methods for processing every form in your web application. All of these approaches have trade-offs in terms of performance and manageability. You are free to use whichever approach works best for you.

Using the user registration scenario, we allow users to register with just a username and password and minimal validation. The sample below shows our class file. Some AJAX required properties and libraries are inherited from the base class form_processor but are still shown here commented out so that you can see how everything works.

<?php /* CLASS FILE FILENAME: my_app/html_filters/register.php CLASS: register_user AUTHOR: Joey Dobias COPYRIGHT: Copyright (c) 2015 Joey Dobias LAST MODIFIED: 2015-02-03 DESCRIPTION: Provides user regsitration functionality. */ include_once('shared_lib/form_processor_v2.php'); // include('shared_lib.php'); class register extends form_processor { // public $message; // (str) Display text at head after processing. // public $hints; // (ary) Correct user input hints to display. // public $status=0; // (int) Exit code. 0=SUCESS, 1=WARN, 2=ERROR, 3=NULL // public $ns; // (str) Form namespace used by AJAX responses. // public $next_url; // (str) URL to go to next. // public $anchor; // (str) Anchor to forward the current page to. // public $redraw; // (ary) HTML to be substituted in the AJAX response. // protected $input; // (ary) All user input from the HTML form. /* -- METHOD (void) construct(request(str), sub request(str)) -- MANDATORY ------------------------------------------------------ Main logic switch for processing forms. ------------------------------------------------------ */ protected function construct($request,$subrequest){ $this->ns=&$request; switch($this->ns){ case 'register': $this->run_register(); break; case 'img_upload': // Place holder for image upload form break; default: die("Unknown request '$request' passed to developer->construct()."); break; } } /* -- METHOD (bool) run_register() -- ------------------------------------------------------ Processes the user regsitration form ------------------------------------------------------ */ protected function run_register(){ $this->hints=array( 'username'=>NULL, 'password'=>NULL ); if((isset($this->input['username']))&&(strlen($this->input['username'])!==0)){ $this->hints['username']='username required'; $this->status=2; } if((isset($this->input['password']))&&(strlen($this->input['password'])!==0)){ $this->hints['password']='password required'; $this->status=2; } if($this->status===0){ // SOME CODE TO REGISTER USERE HERE $this->message='User registration complete'; return TRUE; }else{ $this->message='Input error. Please try again.'; return FALSE; } } } ?>

In the sample code above, the class register contains a number of properties used by AJAX. In reality these are registered automatically by the base form_processor class. How these are set changes how responder.php instructs the ac_ajax class to behave. In the example:

  1. responder.php would instantiate a register_user object and pass the request instruction to it (in this example, we ignore the subrequest). This request string is used to determine which form to process.
  2. Since the request is "register", the constructor calls the run_register() method.
  3. This method validates that a username and password exist and are not empty. If they are empty then a hint is passed in the hints property.
  4. Finally, if there were no problems (the status=0), then the message is set to something positive like "User registration complete" and the method returns TRUE. Otherwise a message is set to some error text and returns FALSE.
  5. The message and the hints (if any) result in changes to the HTML via AJAX.

Fig 2. form_processor() interface

Item Property / Method [P/M] Mandatory [Y/N] Usage
construct M Y Not to be confused with the PHP class constructor __construct() (which already exists in the base form_processor class). This method is always called when the object is instantiated and must support 2 arguments. These represent a form request string and a subrequest string. Whether subrequests are used or not depends on if you specify such a string in the HTML form action. In many cases, forms will just send a single request. If you are building one class file per form, then the entire processing for the form may be contained in this construct() method (in which case, the request string is arbitrary). If a single class supports multiple forms, then you will generally use a branching statement like switch to call separate form processing methods as required.
message P N A string which instructs ac_ajax to display some text upon completion of the form processing. The responder.php script will prepend the required namespaces before passing back to ac_ajax.
status P Y An integer which instructs ac_ajax the overall result of the form processing. This also affects the visual display style of any text contained in the message property. Valid values are: 0 = Success; 1 = Completed with warnings; 2 = Error (such as invalid user input); 3 = Do nothing (used when handling a mixture of AJAX and file uploads)
ns P Y This is the namespace string of the form elements. This is not an XML namespace but corresponds to a named prefix in the HTML element IDs so that changes via AJAX are unambiguous. For example, two forms on the same page may have empty <div> tags for displaying a processing message. They cannot both be called "message". The ns property provides a way to indicate the ID prefix. Commonly, the construct method's request argument is assigned to ns but any string can be used as long as it corresponds to the IDs in the HTML.
hints P N This array can contain strings which are displayed next to form input fields indicating the nature of the user input error. Each key is a string corresponding to the HTML form input element name. The values are the text to display (usually between one and 3 words long). The responder.php script will prepend the required namespaces before passing back to ac_ajax.
next_url P N This string contains an URL which instructs ac_ajax to forward the user's browser only if the value of the status property is zero (success).
Sending changes to the browser

The responder.php will automatically take care of updating the form processing status message and adding any validation hints if required. These are common components of BEAR forms and exposed via the form_processor base class. Beyond that, it is also possible to change any other element of the HTML dynamically by sending chunks of HTML with label that corresponds to an existing HTML element ID in the main HTML of your web page. Any HTML tag that supports a unique ID attribute can be used. However, for consistency only the following are recommended:

  • <div>
    For labelling whole blocks of HTML to be replaceable via AJAX.
  • <span>
    For labelling inline text HTML to be replaceable via AJAX.

This is handled via the public property redraw which is a multidimensional array of HTML IDs and replacement HTML. The responder.php script looks for this public property in your class and, if found, sends the list of HTML replacements back to the browser as SWAPI variables to be parsed by the ac_ajax object.

For example, a simple form displays the text "Hello World" via AJAX after the user submits the form. The HTML contains the following empty (and therefore invisible) tag:

<div id="greeting"></div>

The code run in your form processing class assigns the following to the public redraw property:

$this->redraw[]=array('greeting','<h1>Hello World</h1>');

Once this gets passed back to the ac_ajax object (automatically by responder.php), the HTML in the user's browser is updated as follows:

<div id="greeting"><h1>Hello World</h1></div>

As long as the supplied HTML is valid, you can make as elaborate a change to the HTML on the user's screen as required.

ac_ajax does not validate whether your HTML is valid or not. It merely makes the replacement. Therefore, if the display is unexpected, please check your HTML.

3.3.3 Creating the AJAX form in the HTML

Creating an AJAX compatible form for use with the ac_ajax class is very simple. Javascript instructions are kept separate from the HTML so very little special care is required other than some attention to the HTML element IDs and some proprietary attributes added to existing HTML tags. Creation of the form can be broken up into 3 basic areas:

  1. Creating the HTML form
  2. Registering the form as an ac_ajax object
  3. Creating (optional) additional HTML placeholders for areas that support dynamic AJAX updates.
Creating the HTML form

An ac_ajax HTML form is not significantly different from a standard HTML URI handled form. It still contains a <form> tag, various <input> elements, and at least one submit button.

  1. Create the <form> tag
    The action attribute, which usually contains the URI of the receiving script is replaced with a URL query string which actually is used to instruct ac_ajax how to handle the form.

<form action="appid=my_app&filter=register&class=register&run=register_user" method="post" enctype="application/x-www-form-urlencoded" name="user_add" id="user_add" target="_self"> <!-- YOUR FORM CONTENT GOES HERE /--> </form>

The example above would instruct the ac_ajax object to process the form using the register class in register.php which was discussed earlier. This makes more sense when the supported arguments are described in the following table.

Fig 3. AJAX form query string fields

Argument Mandatory [Y/N] Usage
appid Y Indicates the package name that the form belongs to. This allows responder.php to locate the correct application folder in the CGI directory.
filter Y Indicates the name of the filter to be used from the package's html_filters directory. This basically corresponds to the class filename minus the *.php extension.
class Y The name of the class to instantiate from the class file specified by filter.
run Y The run command to pass to the object constructor.
sub N A sub run request (not shown in the example above). Often this is not added to the action attribute but dynamically changed using other Javascript (such as the ac_event class) when a user clicks a different type of submit button (such as a single form with multiple submit buttons designed to do different things).
  1. Add the <input> elements
    Within the <form> element, add all the form input elements required. This is fairly simple, but remember that ac_ajax also supports user hints. For example, our username and password input fields may look like the following:

<p>Username: <input type="text" name="username" id="username"> <span id="register_user_hint_username"></span></p> <p>Password: <input type="text" name="password" id="password"> <span id="register_user_hint_password"></span></p>

There is nothing special here except that there are two empty <span> tags. These are the place holders for the hints that might be returned if there is a problem with user input. The ID of these <span> tags is always formatted as <namespace>_hint_<input_tag_name>. Remember, the convention is to usually derive the namespace from the run argument in the <form> tag's action attribute.

  1. Add the input error tracking hidden field
    To track errors that are currently shown, a hidden field is used with an empty value (this is populated and managed by ac_ajax). The ID naming convention is always <namespace>_last_errors.

<input type="hidden" name="register_user_last_errors" id="register_user_last_errors" value="">

  1. Add the form submission tracker
    To prevent automated form submission and ensure that the form being submitted is the instance of the form being served, add the following tag somewhere within the <form> block where the passed string is the namespace of the form. This will result in a hidden field being added to the HTML that a form_processor object will evaluate with the is_submitted boolean property.

<?php set_form('register') ?>

  1. Add the processing message place holder
    Finally, add a placeholder where the processing message will be displayed. This can be outside of the <form> element if required. The ID of this tag is always <namespace>_message. This is shown in the example below.

<div id="register_user_message"></div>

Registering the form as an ac_ajax object

Once the form is created, simply include the Javascript file containing the ac_ajax class and register an instance of the class as a form object.

<script type="text/javascript" src="../../javascript/ac_ajax_v2.js"></script> <script type="text/javascript" src="../../javascript/ac_event_v2.js"></script> <script type="text/javascript"> window.onload=function(){ ac_ajax.addForm('user_add',false); } </script>

The ac_event class file is required by almost all BEAR Javascript libraries so this is also included. The AJAX form is registered with the ac_ajax.addForm() method which supports a number of arguments though technically only the form name is required. The other supported arguments are as follows.

Fig 4. ac_ajax.addForm() arguments.

Argument Mandatory {Y/N] Usage
form name Y A string that registers the HTML form an ac_ajax object.
asynchronous N A boolean value indicating whether the form is asynchronous or not. If FALSE then while the form is being processed on the application server, the user cannot interect with other forms on the screen. If TRUE then form processing runs in the background.
loading element ID N A string that is the ID of an HTML element to make visible while the form is being processed. This is described in more detail in the section about Displaying a loading graphic.
file N If the form requires a file upload, this string corresponds to the inline frame ID and <form> name of the file upload. This is described in more detail in the section about Handling file uploads.
top N A boolean value that, if TRUE causes the page to scroll to the top on completion of form processing. This is useful for long forms where the processing message might be near the top of the screen where the user might not see it otherwise.
Creating (optional) additional HTML placeholders

As explained earlier, the form processing method can send HTML back to ac_ajax to replace the child elements of any HTML tag with a unique ID. Therefore, you give a <table> tag an ID like id="my_table" and send just the table row <tr> tags to ac_ajax for it to redraw the content of the table. However, this is not recommended. To keep things simple for the developer and the HTML designer, giving IDs to only the following two tags is recommended:

  • <div>
  • <span>

This can be placed anywhere on the page and can reside outside of the <form> element.

Displaying a loading graphic

It is possible to display a loading graphic which automatically disappears when the AJAX response has been received and parsed from the server. The code for this is trivial and there are even two visual HTML templates for this bundled with BEAR. The only requirement is that these are set with the CSS class "hidden" when embedded on the page. When form processing starts, this CSS class is set to an empty value which exposes the HTML contained within it.

For example, your HTML may contain the following hidden loading graphic markup:

<div class="hidden" id="processingHolder"> <div class="processing"><span class="processing_line">Updating hosts configuration. <br> Please wait...</span></div> </div>

To allow ac_ajax to turn this on when the form is submitted and hide it again on completion, the Javascript used to instantiate the object adds the ID name as the third argument:

ac_ajax.addForm('user_add',false,'processingHolder');

Handling file uploads

File uploads are handled as hybrid AJAX and non AJAX requests. Forms that contain a file upload must be effectively broken into two forms with the file upload portion of the form being contained in its own inline frame <iframe> element. This allows user input to be validated first (quickly) and then for the file upload to proceed only if there was no user input errors with the standard form elements. This prevents the user from waiting for a large file to upload only to be told they forget to add a password (for example) and start again. If properly designed, this should all appear as a single form to the user.

  1. Create the <iframe> for the file upload fields
    In place of standard <input> tags, create a suitable sized <iframe> to contain the file upload form. In our user registration scenario, we pretend that we allow the user to upload an image.

<iframe name="file_upload" id="file_upload" src="image_upload.acx" width="738" height="90" scrolling="no" frameborder="no"></iframe>

  1. Register the form as a new ac_ajax object
    This is the same as for non file-upload forms except that an additional fourth parameter to define the file upload frame is required.

<script type="text/javascript" src="../../javascript/ac_ajax_v2.js"></script> <script type="text/javascript" src="../../javascript/ac_event_v2.js"></script> <script type="text/javascript"> window.onload=function(){ ac_ajax.addForm('user_add',false,'processingHolder','file_upload'); } </script>

  1. Create the file for the <iframe>
    Since your inline frame shows another web page, create a file with the correct filename so that it gets loaded by the <iframe>. In our example we need to create a file called image_upload.acx.
  1. Create the <form> in the frame file
    The newly created image_upload.acx is technically just an HTML page with a standard form (not AJAX) that self processes. So we create the form as normal for HTML where file uploads are used:

<form action="image_upload.acx" method="post" enctype="multipart/form-data" name="file_upload" id="file_upload">

Note, that the form name is the same as the parent <iframe> that hosts the image_upload.acx file.

  1. Add the file upload <input> elements
    The file upload elements are also normal but since they are not AJAX, any hints need to be done via PHP markup.

<p>File: <input type="file" name="mugshot" id="mugshot"><?php html::show_hint($form,'package') ?></p>

  1. Add the ac_ajax object index
    For the ac_ajax object in the parent page to detect and pass back response data to the parent form (such as the final status and processing message) we include a hidden <input> field. No modification is required so this can be copied as is.

<input type="hidden" name="ac_index" id="ac_index" value="">

  1. Add PHP code the file head to process the form
    Instead of registering the form as a javascript ac_ajax object, the PHP In the head of the file calls the appropriate PHP class file and executes the required run request. This is essentially the same as how ac_ajax handles forms but bypasses the responder.php script.

<?php include_once('my_app/html_filters/register.php'); include_once('shared_lib/html_forms.php'); $form=new regsiter_user('img_upload'); ?>

  1. Add PHP code to the HTML <head> element to pass processing results to parent frame via Javascript
    Although the form is processed via HTTP submission instead of AJAX, it has to communicate with the form in the parent frame which is AJAX. The PHP html class provides a method generating the required Javascript dynamically. The following should be somewhere in the HTML <head> element.

<?php html::file_upload_response($form,'register') ?>

In this example, "register" is the prefix for elements in the parent AJAX form.

Auto submitting forms on a timed interval

There is an additional method called addInterval() is supplied in ac_ajax which allows setup a timed trigger for a form. This is commonly used with elements which should not require user interaction to update. A good example might be a stock value which updates every 10 seconds with the latest stock prices.

The example below shows how you would set a form to auto submit ion from the Javascript header portion of the HTML file.

<script type="text/javascript" src="../../javascript/ac_ajax_v2.js"></script> <script type="text/javascript" src="../../javascript/ac_event_v2.js"></script> <script type="text/javascript"> window.onload=function(){ ac_ajax.addForm('stock_update',true); ac_ajax.addInterval('appid=my_app&filter=register&class=register&run=register_user'); } </script>

The use of addInterval() is not dependent on calling addForm(). Therefore, it can also be used in a non AJAX context.

The addInterval() function is defined as follows.

Fig 5. ac_event.addEvent() arguments

Argument Mandatory {Y/N] Usage
form name Y A string that registers the HTML form to a timer.
interval Y An integer that indicates the number of seconds between submissions.

3.3.4 Requesting a post page load AJAX update

Another use of AJAX is to rapidly display a page that contains sections of slow to generate content by initially just inputting a place holder, such as a loading animation, and then get their HTML merged in later when it is ready. For example, if you have a table on a page that takes 20 seconds to generate in the back end, writing that HTML at initial load time will effectively cause the page to hang for 20 seconds until complete. By using postLoad() method calls, you can easily tell the server to fetch HTML for those sections after the main body has loaded.

The call is made simply like this.

<script type="text/javascript" src="../../javascript/ac_ajax_v2.js"></script> <script type="text/javascript"> window.onload=function(){ ac_ajax.postLoad('appid=my_app&filter=tables&class=tables&run=show_big_table'); } </script>

The string passed is equivalent to the HTML <form> action attribute we use for ac_ajax forms. However, there is no form behind it and nothing but the query string is passed. We have already described how the AJAX dynamic updates are handled in Sending updates to the browser.

3.3.5 Troubleshooting AJAX responses

The simplest way to troubleshoot the ac_ajax implementation is to view the responses coming from the application server using your browser's developer tools. However, there are multiple methods for tracing these responses:

  • Use your browser's built-in developer tools to view the raw SAWPI responses.
  • Use BEAR Debug Mode to turn on AJAX SWAPI responses in the browser. Each call will now result in the results being displayed as a plain text popup window.
  • Use BEAR Debug Mode to turn on AJAX SWAPI response tracing to a file on the server (/bear/web_applications/logs/trace.out).
    99% of all ac_ajax failures (where it just hangs with no update to the screen) are caused by the same two common problems:
  • A coding error in your PHP on the application server is causing a PHP error or notice to be passed with the SWAPI response. This causes SWAPI parsing to fail and for AJAX to break.
  • A HTML element ID or namespace contains a typo on either the HTML page or the backend PHP class file. This causes ac_ajax to fail when it cannot find the element being referenced.
previous: How It Works next: form_processor_v2