extc Web Developer Rapid Web Application Development and Ajax Framework Version 3.0.546 Using Ajax Background extc Web Developer (EWD) is a rapid application development environment for building and maintaining web applications, running under a number of environments including PHP, Java Server Pages (JSP) and Caché Server Pages (CSP).. The JSP and PHP implementations rely on, and make use of the MGWSI gateway respectively, allowing JSP and PHP pages to communicate with the Caché or GT.M databases. EWD includes advanced functionality that allows you to make use of the Asynchronous Javascript & XML (Ajax) techniques that form the basis of the Web 2.0 generation of web applications. This functionality is known as the EWD Ajax Framework. EWD's Ajax capabilities are extremely easy to use, yet they allow you to design your pages using some of the most complex and sophisticated Ajax techniques that are available anywhere. Once you begin to explore EWD's Ajax Framework, you'll almost certainly begin to move away from the more tradtional request/response HTTP-based web application techniques and start to exploit the very slick and sophisticated techniques that Ajax provides. Your web applications will never look the same again! This document is a reference guide to using EWD's Ajax framework. Pre-requisites This guide assumes that you have read the extc Web Developer Overview, the Installation Guide and Tutorial documents. You should also have the main EWD API Guide at hand. 1
The EWD Ajax Framework The underlying concept of EWD's core Ajax framework is very simple. When a specified event occurs within the browser (eg an onclick event within a <div> tag that contains some text), a request is made to an EWD page whose content replaces the innerhtml property of a target tag within your page. The target tag is uniquely identified by its id attribute this is known as the targetid. The EWD page that you request is a special type of page, known as a page fragment. The contents of the page fragment will replace whatever markup was previously inside the target tag. Page Fragments Unlike standard EWD pages, a page fragment is not a complete page of HTML: it does not contain <html>, <head> or <body> tags. It just contains the HTML and any other markup that will be used to replace the innerhtml of the target tag. However, page fragments othewise behave just like any other EWD page. They can have a pre-page script and can make use of templates, <ewd:include> blocks, variables (session and local), and custom tags (both EWD's built-in custom tags and your own). This is what makes EWD's Ajax framework so flexible and powerful. The figure below summarises how the EWD Ajax framework works. Using this technique, it would be quite possible to write an entire application that used a single container page and lots of page fragments that modified its DOM. 2
An EWD Ajax page fragment must be declared by adding the attribute pagetype= ajax to its <ewd:config> tag. Here's an example of a very simple Ajax Page Fragment. <ewd:config pagetype= ajax applytemplate= false > <div>hello Ajax World!</div> You would save this just like any other EWD page in your application, eg as myajaxexample.ewd. Defining the Target Tag Defining the target tag whose innerhtml will be replaced by the EWD Ajax page fragment is very simple: just add an id attribute to it with a unique value. For example: <div id= mytag >This is going to get replaced!</div> The idea of EWD's Ajax functionality is that anything inside this <div> tag (defined in DHTML terms as its innerhtml property) will get replaced by the contents of a page fragment. So, in this case, the text This is going to get replaced! will disappear and be replaced with the incoming markup from the page fragment. Defining the Ajax Event Now that we have created an Ajax page fragment and defined a target tag, we can now define the Ajax event that will make it all happen. An Ajax event is triggered by any event that can be handled within the browser. Common events that are used to trigger Ajax events are: an onclick event triggered by an <input type= button > tag an onclick event triggered within a <div> or any other tag that supports this event. an onchange event within an <input type= text > tag an onmouseover event within any tag that supports this event an onkeydown event within any tag that supports this event. Having decided on the event that will trigger the Ajax process, just add the following attributes to the tag that will include the event handler, eg: event: specify the event handler you want to use ajaxpage: specify the name of the page fragment you want to request when the event occurs 3
targetid: specify the id of the target tag whose innerhtml is to be replaced by the page fragment. For example: <input type= button name= button1 value= Click me event= onclick ajaxpage= myajaxexample targetid= mytag > This will create a button within your web page. When you click it, the innerhtml of the tag whose id is mytag will be replaced with the contents of the page fragment named myajaxexample. 4
Simple Ajax Example So let's put this together into a simple working example. Here's your main page: <ewd:config applytemplate= false > <html> <head> <title>ajax Example</title> </head> <body> <input type= button name= button1 value= Click me event= onclick ajaxpage= myajaxexample targetid= mytag > <hr /> <div id= mytag >This text will be replaced when you click the button</div> <hr /> </body> </html> Save this page, eg as first.ewd. This main page is known as a container page, since it will act as a container for one or more Ajax page fragments. The contents of the page fragment named myajaxexample.ewd is as follows: <ewd:config pagetype= ajax applytemplate= false > <div>hello Ajax World!</div> Compile these two pages and run the main page, eg: http://127.0.0.1/php/ajaxexample/first.php When you click the button, you should see the text change. What has happened is that the original <div> tag which was as follows: will now contain: <div id= mytag >This text will be replaced when you click the button</div> <div id= mytag ><div>hello Ajax World!</div></div> Note that if you use the browser's View/Source mechanism to view the page after you click the button, it will still show the original page exactly as it was loaded, not how it now looks after the Ajax event. 5
Complex Ajax Events By extending this simple example, you'll quickly be in a position to begin implementing some of the most sophisticated Ajax effects imaginable. The important things to realise are: the page fragment can be as complex as you like. Evenrything it contains will replace what's currently inside the target tag. The effect the user will see is that just one section of the web page will change. The original page remains in place in the browser. Ajax therefore moves you away from the traditional web approach where the entire page was swapped for another. With Ajax you can begin to move into a much more client/server oriented look and feel. A page fragment can have a pre-page script which fetches data and creates session variables and/or arrays which the page fragment can then process. The page fragment can therefore be completely data-driven. A page fragment can make use of templates and/or ewd:include blocks and also custom tags. A page fragment can include further Ajax triggers and target tags, so you can build up a complex page bit by bit as successive fragments are added to the original container page, each delivering their own new events and targets. Then, by refiring the first Ajax event, all those later page fragments can be made to disappear immediately. Ajax can therefore drastically simplify page navigation logic that would otherwise be nightmarishly complex to implement by traditional web techniques. Timed Ajax Events In addition to Ajax Events that are triggered by a user creating an in-browser event, EWD also allows you to define one or more Ajax events that will be automatically triggered each time a specified time period has elapsed. This is useful for system monitoring applications, but has applications elsewhere too. To define a timed Ajax event, just use: event= ontimer time= the number of seconds between each Ajax event firing. For example: <div id="timer1id" ajaxpage="page4j" event="ontimer" time="5">this will be replaced every 5 seconds</div> 6
Passing name/value pairs into the Ajax page fragment. You can use the standard EWD technique for adding name/value pairs to the request for the Ajax page fragment, for example: ajaxpage= mypage.ewd?a=1&b=2 In this example, by the time the prepage script of mypage.ewd has been invoked, session variables named a and b will be available with values of 1 and 2 respectively. You can also pass session variables and local in-page variables, eg: ajaxpage= mypage.ewd?a=#svar1&b=$lvar2 In this example, the current value of the session variable named svar1 will be passed as name a, and the value of the local variable $lvar2 will be passed as name b. If the value of #svar1 was abc and the value of $lvar2 was 23, then by the time the prepage script of mypage.ewd has been invoked, session variables named a and b will be available with values of abc and 23 respectively. Additionally, you can pass Javascript values from your container page, eg ajaxpage= mypage.ewd?a=document.getelementbyid('abc').value&b=javascript.this.name Note that any value that commences document. is automatically assumed by EWD to be a Javascript object reference. Any other Javascipt reference must be prefixed javascript. in order to instruct the compiler to treat the value as a Javascript reference. In this example, a and b will again be automatically instantiated as session variables when the Ajax event occurs. Your name/value pair list can include any or all of the above types. For example: <div id="timer1id" ajaxpage="page4j.ewd?h=javascript.k&a=1" event="ontimer" time="5">this will be replaced every 5 seconds</div> In this example, the value of a Javascript variable named k will be passed to the Ajax page and instantiated as a session variable named h, whilst a session variable named a will be created with a value of 1. Note that when passing name/value pairs, you should add the page extension (.ewd) to the page reference. This extension is not needed if you aren't passing any name/value pairs to the page fragment. 7
Submitting forms via Ajax Normally, HTML forms are handled by submitting them (via an HTTP POST), the result of which is a response page of HTML which either replaces the current page or a specified frame or window target. EWD provides a mechanism for submitting a form via Ajax, in such a way that the response is an EWD page fragment which replaces the contents of a target tag in the container page. Simply modify the <input type= submit > button as follows: <form method= post action= ewd >...etc <input type= submit name= mysub value= Save action= savedata^myrou nextpage= mypage2 ajax= true targetid= mytag > </form> You can still use an action script to validate the submitted form field values: the action script logic is just the same as for standard EWD forms. The nextpage in this example is a page fragment, denoted by the attribute ajax= true, and its content will replace the innerhtml of the tag with id= mytag. Note that EWD page fragments can contain <form> tags and associated form fields (<input>, <select>, <textarea>), but if so, the form should be submitted via Ajax rather than a standard HTTP POST. Also, be careful not to deliver a <form> tag via an Ajax page fragment into a container page tag so that it nests inside another <form> tag. Browsers do not cope with nested <form> tags! Note also that the Ajax form submit mechanism should only be used with forms that are contained within a page fragment. Forms that are defined within a container page can use the Ajax submit mechanism if necessary, but they are unable to alert the user if validation errors occur within the action script. Javascript functions within Ajax Page Fragments An EWD Ajax page fragment can include <script language= javascript> tags that contain one or more Javascript functions. These will be loaded and activated into the container page when the Ajax event occurs. Invoking Ajax Events from within Javascript functions In order to support more complex situations, and to allow several Ajax events to fire one after the other, the EWD Ajax framework also allows you to trigger Ajax events from within Javascrpt functions. Simply use a pseudo-function named ewd.ajaxrequest. 8
This pseudo-function is expanded by EWD's compiler, but provides you with a very simple interface. The function's parameters are as follows: ewd.ajaxrequest(ajaxpagename,targetid,namevaluepairlist) ; The name/value pair list is optional, but the page name and targetid must be defined. For example: <script language= javascript > function mytrigger1() { ewd.ajaxrequest( mypage, myid1 ) ; function mytrigger2(myno) { var target = myid + myno ; ewd.ajaxrequest( mypage,target) ; function mytrigger3() { ewd.ajaxrequest( mypage1, myid1 ) ; ewd.ajaxrequest( mypage2, myid2, a=123 ) ; ewd.ajaxrequest( mypage3, myid3 ) ; function mytrigger4(myno) { if (myno == 1 ) { ewd.ajaxrequest( mypage1, myid1 ) ; else { ewd.ajaxrequest( mypage2, myid2 ) ; function mytrigger5() { var nvp = abc=<?= #svar1?> ; ewd.ajaxrequest( mypage, myid1,nvp) ; </script> In this example, the Javascript function mytrigger1() can be called to invoke an Ajax request for page fragment mypage.ewd to replace the innerhtml of the target tag with id= myid1. The second function mytrigger2() demonstrates that the target ID can be variable. The third function mytrigger3() demonstrates how multiple Ajax events can be fired from within a single Javascript function. You can imagine how powerful this technique can be! Note the second Ajax request passes a name/value pair (a=123) into the ajax page. Function 4 demonstrates how you can conditionalise your Ajax events. Note that whilst the targetid can be variable, the page name must be a pre-defined literal value. 9
This is due to EWD's tight control over page security. See later for mechanisms for redirecting to different Ajax page fragments under programmatic control. Function 5 demonstrates how a name/value pair can be passed to the Ajax page fragment using a session variable. In all five cases, these functions can be triggered via standard event handers, eg: <input type= button name= button1 value= Click 1 onclick= mytrigger1() > <input type= button name= button2 value= Click 2 onclick= mytrigger2('12') > <input type= button name= button3 value= Click 3 onclick= mytrigger3() > <input type= button name= button4 value= Click 4 onclick= mytrigger4( 1 ) > <input type= button name= button5 value= Click 5 onclick= mytrigger5() > Note that if you pass name/value pairs into the ewd.ajaxrequest() pseudo function, EWD is unable to automatically instantiate them as session variables when the Ajax event occurs. They will, however, be available as request variables, so, in the prepage script of your Ajax page fragment, you can get their values using the getrequestvalue () method For example, to process the name/value pair sent via the mytrigger5() function, your prepage Script might look like the following: myscript(sessid) new abc set abc=$$getrequestvalue^%zewdapi( abc,sessid) ;...etc QUIT The <ewd:ajaxonload> Event Handler Yet more sophistication can be added to your Ajax events by using a pseudo onload event hander in your Ajax page fragments. This allows you define a block of Javascript code that will be invoked after the page fragment content has replaced the target tag in the container page. Note that the asynchronous nature of Ajax events means that anything you invoke after an ewd.ajaxrequest function call will fire immediately rather than after the Ajax request has completed. If you want something to occur immediately after the Ajax request has completed, you must use the <ewd:ajaxonload> mechanism. Using this facility is very straightforward. Simply add the <ewd:ajaxonload> tag to your Ajax page fragment and add any Javascript that you wish to be invoked, for example: 10
<ewd:config pagetype= ajax applytemplate= false > <ewd:ajaxonload> alert( ajax event completed! ) ; </ewd:ajaxonload> <div>hello Ajax World!</div> Although you can place the <ewd:ajaxonload> tag anywhere within your Ajax page fragment, by convention you should put it immediately after the <ewd:config> tag. The <ewd:ajaxonload> tag is extremely powerful because you can not only access session variables within the Javascript code, but you can also make calls to the ewd.ajaxrequest() function. For example: <ewd:config pagetype= ajax applytemplate= false > <ewd:ajaxonload> var myvar = <?= #svar1?> ; var nvp = abc= + myvar ; ewd.ajaxrequest( mypage2, x123,nvp) ; </ewd:ajaxonload> <div>hello Ajax World!</div> In this example, as soon as this page fragment is loaded, it will trigger another Ajax event which will also pass the value of a session variable back into the next Ajax page fragment. Using this technique, you can chain Ajax events, each one triggering a subsequent Ajax event in a controlled sequence. Breaking down Complex Pages By using EWD's Ajax features, you can break down what would have previously been very complex pages into small manageable chunks. The main container page can initially be nothing more than an empty framework of <div> tags that are populated one by one by a sequence of Ajax events. Each page fragment can bring with it the markup that describes in detail a section of the overall web page, including other Ajax triggers. In this way you can break down a page into multiple simple page fragments that each perform simple functions, but whose overall effect is one of great visual complexity and sophistication. You can also, if required, assign different functions and page fragments to members of your development team. 11
Debugging Ajax Events There are four main techniques you should use when debugging your Ajax events. Add some tracing code into the pre-page script of the Ajax page fragment. This will help you determine whether or not the event fired at all and whether EWD managed to run the page fragment. You can also determine whether or not any additional name/value pairs were successfully transferred into Cache. In the tag where you are triggering the Ajax event, add the attribute trace= alert, eg: <input type= button name= button1 value= Click me event= onclick ajaxpage= myajaxexample targetid= mytag trace= alert > When the page fragment's contents are delivered to the browser, an alert will pop up containing the raw markup that has been generated by the page fragment. In the tag where you are triggering the Ajax event, add the attribute trace= window, eg: <input type= button name= button1 value= Click me event= onclick ajaxpage= myajaxexample targetid= mytag trace= window > This technique is useful if the content being delivered by the page fragment is very large and is beyond the scope of an alert to display. If you use this mode, EWD compiles in a textarea field into your page, and copies the raw page fragment contents into it. If none of the above mechanisms are suitable, then you can, if necessary, modify the ewdscripts.js file. Make sure you're editing the version that is actually loaded into the user's browser, and look for the lines: function ajaxreplacecontent(http_request,id,traceflag) { if (http_request.readystate == 4) { if (http_request.status == 200) { var text = http_request.responsetext ; The last line is the point at which the raw page fragment response content is available in the variable text. You can modify the ewdscripts.js file to display this text. The simplest way is to add an alert, eg: function ajaxreplacecontent(http_request,id,traceflag) { 12
if (http_request.readystate == 4) { if (http_request.status == 200) { var text = http_request.responsetext ; alert(text) ; This will cause an alert window to pop up whenever a page fragment returns its contents to the browser. By modifying your logic, you can, for example, conditionalise the generation of the alert to occur only when the text variable contains certain strings of characters. Note: if you use this approach and modify ewdscripts.js, then you will need to force the browser to refresh its cached version of the js file and use your new edited version. Hitting the browser refresh button is usually sufficient. Also note that when you recompile a complete EWD application (using compileall^%zewdapi), the ewdscripts.js file is regenerated, so you may want to save a copy containing any of your debugging logic before recompiling. Conclusions Despite such a simple framework, EWD's Ajax functionality allows you to add almost unlimited power and sophistication to your web applications, yet it is incredibly easy to use and maintain. This functionality makes EWD one of the most powerful Ajax and Web 2.0 development toolsets. We hope you enjoy using the Ajax technology within EWD! 13