Exercise 2: AJAXEX2 – Doing Some Simple AJAX
The Steps
- Copy and paste the DHTML-JavaScript code in AJAX Page AJAXEX2.HTM using NOTEPAD and save it into your Framework private working folder as an AJAX page file named AJAXEX2.HTM.
- Copy and paste the AJAX function code in AJAX Function AJAXEX2 into an RDML function named AJAXEX2 into your VL-IDE. Compile RDML function AJAXEX2 so that it is executable on your web server.
- In business object AJAX, snap AJAX page file AJAXEX2.HTM and AJAX function AJAXEX2 into your Framework as the command handler to be associated with command AJAXEX2 like this:
- Save, restart and execute your Framework in a web browser. Select application ‘AJAX Examples’ and then select business object AJAX. This should execute the default command AJAXEX1. Click on the AJAXEX2 tab to execute the AJAXEX2 command:
Enter a number and then click the increment and decrement buttons. The value you enter is sent to the AJAX function on the web server and incremented or decremented as requested. The result is then redisplayed in the AJAX page.
Sending a number to a web server to be incremented or decremented is only to illustrate the foundations upon which all AJAX applications are built, including:
- Sending request to the server
- Receiving responses from the server
- Asynchronous processing
- Dynamic updating of the web page
You should review the JavaScript/DHTML code in AJAXEX2.HTM and the RDML code in AJAX function AJAXEX2 until you understand the basics of what it is doing and how it is doing it.
<HTML>
<HEAD id='HEAD_Tag'>
<link rel='stylesheet' type='text/css' href='vf_vs001.css' >
<script>
/* ======================================================================== */
/* ======================== Handle Page Initialization ==================== */
/* ======================================================================== */
function VF_AJAX_Initialize()
{
/* Insert the variable style sheet (ie: XP, WIN, WEB style) into this page */
{
var objLink = document.createElement("LINK");
objLink.rel = "stylesheet"; objLink.type = "text/css";
objLink.href = STYLESHEET();
document.getElementById("HEAD_Tag").insertAdjacentElement("afterBegin",objLink);
}
/* Finished */
return;
}
/* ======================================================================== */
/* ======================== Handle Page Execution ========================= */
/* ======================================================================== */
function VF_AJAX_Execute()
{
SETBUSY(false);
return;
}
/* ======================================================================== */
/* ======================= Handle Page Termination ======================== */
/* ======================================================================== */
function VF_AJAX_Terminate()
{
return;
}
/* -------------------------------------------------------- */
/* Rationalized virtual clipboard access to name space AJAX */
/* -------------------------------------------------------- */
function Put(val,np2,np3,inst) {AVSAVEVALUE(val,"AJAX",np2,np3,inst);}
function GetN(np2,np3,inst) {return(AVRESTORENVALUE(0,"AJAX",np2,np3,inst));}
/* ---------------------------------------- */
/* Handle a click of button BUTTON_onclick */
/* ---------------------------------------- */
function BUTTON_onclick(strRequest)
{
/* Ignore if already busy doing something else */
if (BUSY()) return;
/* Validate the number and put it onto the clipboard */
{
var floatNumber = parseFloat(NUMBER_Tag.value);
if (isNaN(floatNumber)) { alert("Invalid number entered"); return; }
Put(floatNumber,"NUMBER");
}
/* Make busy now */
SETBUSY(true);
/* Update the message area */
MESSAGE_Tag.innerText = "Processing your request now. Please wait.";
MESSAGE_Tag.style.backgroundColor = "orange";
/* Now send INCREMENT/DECREMENT request the server RDML function named AJAXEV2 */
if (strRequest =="I" ) SENDREQUEST(window,"","INCREMENT","",INCREMENT_response);
else SENDREQUEST(window,"","DECREMENT","",DECREMENT_response);
/* Finished */
return;
}
/* ------------------------------------- */
/* Handle server responding to INCREMENT */
/* ------------------------------------- */
function INCREMENT_response(strFunction,strRequest,strPayload,objObject,flagFatalError,strFatalMessage)
{
/* Handle a fatal error in the server function */
if (flagFatalError) { alert(strFatalMessage); SETBUSY(false); return; }
/* Otherwise display the result to the user */
NUMBER_Tag.value = GetN("NUMBER").toString();
MESSAGE_Tag.innerText = "Increment operation completed normally.";
MESSAGE_Tag.style.backgroundColor = "yellow";
SETBUSY(false);
/* Finished */
return;
}
/* ------------------------------------- */
/* Handle server responding to DECREMENT */
/* ------------------------------------- */
function DECREMENT_response(strFunction,strRequest,strPayload,objObject,flagFatalError,strFatalMessage)
{
/* Handle a fatal error in the server function */
if (flagFatalError) { alert(strFatalMessage); SETBUSY(false); return; }
/* Otherwise display the result to the user */
NUMBER_Tag.value = GetN("NUMBER").toString();
MESSAGE_Tag.innerText = "Decrement operation completed normally.";
MESSAGE_Tag.style.backgroundColor = "aqua";
SETBUSY(false);
/* Finished */
return;
}
</script>
</HEAD>
<BODY id='HEAD_Tag'>
<br/><br/><br/>
<P align='center'>Hello World 2</p>
<span> Input Number ==> </span><input id='NUMBER_Tag' type='text'><span> then click a button ==> </span>
<input id='BUTTON1_Tag' type='button' value='Increment' onclick='BUTTON_onclick("I");'>
<input id='BUTTON2_Tag' type='button' value='Decrement' onclick='BUTTON_onclick("D");'>
<br/><br/><div id='MESSAGE_Tag' align='center'></div>
</BODY>
</HTML>
* This is just a simple RDML function.
* It is NOT a WAM function.
* It is driven by the virtual clipboard
Function Options(*DIRECT *HEAVYUSAGE)
* Define local fields
Define Field(#REQUEST) Reffld(#STD_OBJ)
Define Field(#NUMBER) Type(*DEC) Length(30) Decimals(9)
Define Field(#MSGDTA) Type(*CHAR) Length(132)
* Get the action the Javascript requested in paramter 3
* ..... when it executed this ...
* SENDREQUEST(window,"","INCREMENT",INCREMENT_response);
* ..... or this .....
* SENDREQUEST(window,"","DECREMENT",DECREMENT_response);
Execute Subroutine(GETA) With_Parms(SYSTEM REQUEST 1 #REQUEST)
* Now switch on the requested action
Case Of_Field(#REQUEST)
* Get NUMBER from the clipboard, increment and put back
When Value_Is('= INCREMENT')
Execute Subroutine(GETN) With_Parms(NUMBER ' ' 1 #NUMBER)
Change Field(#NUMBER) To('#NUMBER + 1')
Execute Subroutine(PUTN) With_Parms(NUMBER ' ' 1 #NUMBER)
* Get NUMBER from the clipboard, decrement and put back
When Value_Is('= DECREMENT')
Execute Subroutine(GETN) With_Parms(NUMBER ' ' 1 #NUMBER)
Change Field(#NUMBER) To('#NUMBER - 1')
Execute Subroutine(PUTN) With_Parms(NUMBER ' ' 1 #NUMBER)
Otherwise
Use Builtin(BCONCAT) With_Args('Unknown request' #REQUEST 'received by' *FUNCTION) To_Get(#MSGDTA)
Abort Msgid(DCM9899) Msgf(DC@M01) Msgdta(#MSGDTA)
Endcase
* Finished
Return
* =====================================================
* Rationalized subroutines for virtual clipboard access
* =====================================================
Subroutine Name(PUTA) Parms((#NP2 *RECEIVED) (#NP3 *RECEIVED) (#INST *RECEIVED) (#AVAL *RECEIVED))
Define Field(#NP2) Type(*CHAR) Length(28)
Define Field(#NP3) Type(*CHAR) Length(24)
Define Field(#INST) Type(*DEC) Length(7) Decimals(0)
Define Field(#AVAL) Type(*CHAR) Length(256)
Use Builtin(VF_SAVEAVALUE) With_Args(#AVAL AJAX #NP2 #NP3 #INST)
Endroutine
Subroutine Name(PUTN) Parms((#NP2 *RECEIVED) (#NP3 *RECEIVED) (#INST *RECEIVED) (#NVAL *RECEIVED))
Define Field(#NVAL) Type(*DEC) Length(30) Decimals(9)
Use Builtin(VF_SAVENVALUE) With_Args(#NVAL AJAX #NP2 #NP3 #INST)
Endroutine
Subroutine Name(GETA) Parms((#NP2 *RECEIVED) (#NP3 *RECEIVED) (#INST *RECEIVED) (#AVAL *RETURNED))
Use Builtin(VF_RESTOREAVALUE) With_Args(' ' AJAX #NP2 #NP3 #INST) To_Get(#AVAL)
Endroutine
Subroutine Name(GETN) Parms((#NP2 *RECEIVED) (#NP3 *RECEIVED) (#INST *RECEIVED) (#NVAL *RETURNED))
Use Builtin(VF_RESTORENVALUE) With_Args(0 AJAX #NP2 #NP3 #INST) To_Get(#NVAL)
Endroutine