Administrative Computing Developer Resources
 
S A P Development Standards Web Development Standards Quality Assurance Glossary    

ITS (Internet Transaction Server) Cookbook

The ITS libraries
Anatomy of a template: the TEMPLATE.html model
Submitting an OKcode: image inputs vs. hyperlinks
Search helps: providing input help
CALL TRANSACTION: services that call a secondary service

Overview

The following is a collection of frequently used techniques and coding practices employed in the construction of MIT Administrative Computing: Internet Design & Development Team (IDD) – Web Development Standards compliant ITS templates.

This document assumes the reader is familiar with ITS development concepts and practices. It does not attempt to instruct a novice developer but rather to be a resource to current developers engaged in the development of ITS applications that comply with the MIT Administrative Computing: IDD Web Development Standards.

The ITS libraries

The R/3 development and prototyping environments (SF2 and SF8, respectively) each contain two toolkits for ITS development. These toolkits, also referred to as libraries, are ZSAPWEB, used in the development of ITS applications for the SAPweb product, and ZSAPWEBSS, used in the development of ITS applications for the SAPweb Self Service product. Each library provides a collection of standard, commonly-used objects used in ITS application development and is organized as follows:

Theme 00 directory

The HTML templates directory for Theme 00 contains functions from the S.U.I.T. Javascript API. To use a S.U.I.T. function in an ITS template, the HTML template containing the function definition must be included via bHTML function, `include()`, within the <head></head> section of the calling template.

Example

<head>
<server>
  include(~service="{LIBRARY}",~theme="00",~name="always_js.html");
  include(~service="{LIBRARY}",~theme="00",~name="getObject_js.html");
</server>

</head>
<body onLoad="suit.getObject('objectName').focus()" marginwidth="0" marginheight="0">
.
.
.
<script type="text/javascript">suit.getObject(l_fieldName)</script>

Theme 10 directory

The HTML templates directory for Theme 10 contains functions from a bHTML user-interface (UI) toolkit developed by Administrative Computing: IDD. To use a function from the bHTML toolkit in an ITS template, the HTML template containing the function definition must be included via bHTML function, `include()`, within the <head></head> section of the calling template.

Example

<head>
<server>
  include(~service="{LIBRARY}",~theme="10",~name="func_outputTitle.html");
  include(~service="{LIBRARY}",~theme="10",~name="func_outputHomeHelp.html");
</server>

<title>`outputTitle("")`</title>

</head>
<body marginwidth="0" marginheight="0">
.
.
.
<!-- PRODUCT BANNER -->
`outputTitle("banner")`

<!-- NAVIGATION BAR -->
`outputHomeHelp(l_homeURL,l_helpURL,"l_username_variable")`

Theme 99 directory

The MIME objects directory for Theme 99 contains the master cascading style sheet (CSS) used for the product along with three subdirectories:

  • EXITURL - contains one or more HTML templates that can be used in conjunction with bHTML parameter, `~exitURL`, to redirect a URL upon termination of an ITS session.
  • IMAGES - contains graphics files for commonly used buttons and icons.
  • SEARCHHELP - contains custom search help templates used in the product.

The HTML templates directory for Theme 99 contains a model template, TEMPLATE.html, that can be used as the basis for developing a custom template. The model, intended to both reduce the time required to produce a custom template and promote uniformity of code, may be copied and pasted into an internet service template file and modified locally as needed. Section Anatomy of a template: the TEMPLATE.html model of this document offers an interactive look at the components of the TEMPLATE.html model.

TOP

Anatomy of a template: the TEMPLATE.html model

The ZSAPWEB and ZSAPWEBSS libraries each contain a template model that can be used as the basis for developing a custom template specific to the SAPweb or SAPweb Self Service products. Below is shown a mock-up web page built using the ZSAPWEB TEMPLATE.html model. This mock-up demonstrates the use of the template model components. Clicking on different areas within the mock-up will bring the reader to the section of the model code where that area of the web page is generated.

ZSAPWEB TEMPLATE.html mock-up

 

 

ZSAPWEB TEMPLATE.html model code

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>

<link rel="stylesheet" href="`mimeURL(~service="zsapweb",~language="","styles.css")`" type="text/css">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">

<server>

<!-- Template {NUMBER}: {BRIEF DESCRIPTION OF TEMPLATE PURPOSE} -->

<!-- ZSAPWEB S.U.I.T. JAVASCRIPT INCLUDES -->
include(~service="zsapweb",~theme="00",~name="alwaysjs.html");
include(~service="zsapweb",~theme="00",~name="getObjectjs.html");
include(~service="zsapweb",~theme="00",~name="windowDialogjs.html");

<!-- ZSAPWEB BHTML INCLUDES -->
include(~service="zsapweb",~theme="10",~name="func_outputTitle.html");
include(~service="zsapweb",~theme="10",~name="func_outputMessage.html");
include(~service="zsapweb",~theme="10",~name="func_outputhomehelp.html");
include(~service="zsapweb",~theme="10",~name="func_required.html");
include(~service="zsapweb",~theme="10",~name="func_footer.html");

<!-- LOCAL SERVICE INCLUDES (FULL PATH NEEDED BY CALLER SERVICES) -->
include(~service="{SERVICE}",~theme="99",~name="{TEMPLATE_1}.html");
include(~service="{SERVICE}",~theme="99",~name="{TEMPLATE_2}.html");

l_homeURL = {SAPWEB_TAB_URL};
l_helpURL = {HELP_DOC_URL};

</server>

<title>`outputTitle("")`</title>

</head>

<body marginwidth="0" marginheight="0">

<!-- OPEN FORM -->
<form name="{FORM_NAME}" id="{FORM_NAME}" action="`wGateURL()`" method="post">

<!-- SAPWEB BANNER -->
`outputTitle("banner")`

<!-- NAVIGATION BAR -->
`outputHomeHelp(l_homeURL,l_helpURL,"{USER_NAME_VARIABLE}")`
<br />

<!-- PAGE TITLE -->
<table align="center" width="95%" border="0" cellspacing="2" cellpadding="2">
  <tr>
    <td class="pageTitle">`~windowTitle`</td>
  </tr>
</table>
<br />

<!-- SYSTEM MESSAGES -->
`if ( ~messageline != "" )
  outputMessage(~messageline,"error");
  outputMessage(~messageline,"message");
  write("<br />");
end;`

<!-- PAGE NOTE -->
`if ( {PAGE_NOTE_EXISTS} )
  outputMessage({PAGE_NOTE},"");
  write("<br />");
end;`

<!-- FORM BUTTONS -->
<table align="center" width="95%" border="0" cellspacing="2" cellpadding="2">
  <tr>
    <td nowrap>
      {BUTTON_1}
      {BUTTON_2}
      {BUTTON_3}
    </td>
  </tr>
</table>
<br />

<!-- TABLE LAYOUT OPTION #1 -->
<table border="0" align="center" width="95%" cellspacing="2" cellpadding="2">
  <tr>
    <td class="label" nowrap>{FIELD_LABEL_1}</td>
    <td width="1%">`required()`</td>
    <td class="data" nowrap>`{FIELD_VALUE_1}`</td>
    <td width="99%" /> <!-- FORMATTING -->
  </tr>
  <tr>
    <td class="label" nowrap>{FIELD_LABEL_2}</td>
    <td width="1%" /> <!-- SPACER: FIELD NOT REQUIRED -->
    <td class="data" nowrap>`{FIELD_VALUE_2}`</td>
  </tr>
  <tr>
    <td class="label" nowrap>{FIELD_LABEL_3}</td>
    <td width="1%">`required()`</td>
    <td class="data" nowrap>`{FIELD_VALUE_3}`</td>
  </tr>
</table> <!-- END TABLE LAYOUT OPTION #1 -->

<!-- TABLE LAYOUT OPTION #2 -->
<table border="0" align="center" width="95%" cellspacing="2" cellpadding="2">
  <tr>  
    <!-- TABLE TITLE -->
    <td colspan="{COLSPAN}" class="tableTitle" nowrap>{TABLE_TITLE}</td>
    <!-- SORT BY -->
    <td colspan="{COLSPAN}" class="label" align="right" nowrap>
      Sort by
      <select name="`{SORT_KEY}`" id="`{SORT_KEY}`" onChange="{CUSTOM_SCRIPT}">
        <option value="`{OPTION_VALUE_1}`"> {OPTION_LABEL_1}</option>
        <option value="`{OPTION_VALUE_2}`"> {OPTION_LABEL_2}</option>
      </select>
    </td>
  </tr>
  <tr>
    <!-- RECORDSET BUTTONS -->
    <td colspan="{COLSPAN}" nowrap>
      {RECORDSET_BUTTON_1}
      {RECORDSET_BUTTON_2}
    </td>
    <!-- RECORDSET NAVIGATION -->
    <td colspan="{COLSPAN}" align="right">
      <table width="1%" border="0" cellspacing="0" cellpadding="0">
      <tr>
      <td class="small" nowrap>`{RECORDSET SUMMARY}`</td>
      <td>`{SCROLL_AREA_START}`</td>
      <td>`{SCROLL_BUTTON_FIRST}`</td>
      <td>`{SCROLL_BUTTON_PREVIOUS}`</td>
      <td>`{SCROLL_BUTTON_NEXT}`</td>
      <td>`{SCROLL_BUTTON_LAST}`</td>
      <td>`{SCROLL_AREA_END}`</td>
      </tr>
      </table>
    </td>
  </tr>
  <!-- TABLE COLUMN HEADERS -->
  <tr>
    <th class="tableHead" align="left" nowrap>`{COLUMN_1_LABEL}` &nbsp;</th>
    <th class="tableHead" align="left" nowrap>`{COLUMN_2_LABEL}` &nbsp;</th>
    <th class="tableHead" align="left" nowrap>`{COLUMN_3_LABEL}` &nbsp;</th>
    <td width="99%" /> <!-- FORMATTING -->
  </tr>
  <!-- RECORDSET -->
  `repeat with j from {TABLE_CONTROL}.firstvisible to {TABLE_CONTROL}.lastvisible`
    <tr>
      <td class="data" nowrap>`{COLUMN_1_VALUE[j]}` &nbsp;</td>
      <td class="data" nowrap>`{COLUMN_2_VALUE[j]}` &nbsp;</td>
      <td class="data" nowrap>`{COLUMN_3_VALUE[j]}` &nbsp;</td>
    </tr>
  `end; <!-- end repeat -->`
</table> <!-- END TABLE LAYOUT OPTION #2 -->

<!-- FORM BUTTONS -->
<table align="center" width="95%" border="0" cellspacing="2" cellpadding="2">
  <tr>
    <td nowrap>
      {BUTTON_1}
      {BUTTON_2}
      {BUTTON_3}
    </td>
  </tr>
</table>
<br />

<!-- CLOSE FORM -->
</form>

<!-- SAPWEB FOOTER -->
`footer({PARAMETER_STRING})`

</body>
</html>

TOP

Submitting an OKcode: image inputs vs.hyperlinks

Submitting an OKcode via an image input form element vs. a hyperlink

OKcodes may be submitted to the backend via one of two basic methods. The first approach associates the OKcode with a graphical form element, such as a button, by naming the button, ~okcode(OKCD). An alternative notation, ~okcode=OKCD, may be used and produces the same effect; when a user clicks the graphical form element, ITS submits the HTML form in its entirety and processes the contents of the ITS template according to the screen PAI (post-input) logic.

Notation 1

<input type="image" name="~okcode(OKCD)" id="~okcode(OKCD)" src="..." width="..." height="..." alt="..." title="..." border="0">

Notation 2

<input type="image" name="~okcode=OKCD" id="~okcode=OKCD" src="..." width="..." height="..." alt="..." title="..." border="0">

Example

example

<input type="image" name="~okCode(NEWP)" id="~okCode(NEWP)" src="`mimeURL(...)`" border="0" width="85" height="17" alt="Add a Person" title="">

<input type="image" name="~okCode(DELP)" id="~okCode(DELP)" src="`mimeURL(...)`" border="0" width="99" height="17" alt="Delete Selected" title="">

The second approach associates the OKcode with a hypertext link. In this approach, standard business-HTML (bHTML) function, `wGateURL()` is embedded within the href attribute of an opening HTML <a> tag. The `wGateURL()` function generates a dynamic URL based on the current system, ITS session, and other information.

A URL may be generated in this manner for either a single hyperlink or for a series of hyperlinks output in a repeating loop.

Notation 1

<a href="`wGateURL(~okcode="OKCD")`"> `TABLE-FIELD.value`</a>

Notation 2

`repeat with j from l_firstVisble to l_lastVisible`
  <a href="`wGateURL(~okcode="OKCD",'G_HTML_INDEX'=j)`">
  `TABLE-FIELD[j].value`</a>
`end;`

In notation 2, l_firstVisble and l_lastVisble represent the first and last records of either an internal table or a table control housing the data to be output, and G_HTML_INDEX represents an ABAP variable used in the PAI (post-input) logic to determine the selected table index.

Example

example

`repeat with j from l_first_record to l_last_record`
  <tr>
    <td align="center" width="1%" nowrap>
      `checkbox_mode("T_ROOM-SELECT",j,"")`
    </td>
    <td class="data" nowrap>
      <a href="#" onclick="drillDown('hazmat3000','XROM',`j`);
      return false;"
> `T_ROOM-NUMBER[j].value`</a>
    </td>
    <td class="data" nowrap>
      `T_ROOM-TYPETEXT[j].value`
    </td>
    .
    .
    .
  </tr>
`end; <!-- end repeat -->`

Note that the example uses a combination of:

  • cascading style sheet elements   class="data"
  • local bHTML variables   l_first_record
  • ZSAPWEB bHTML function calls   `checkbox_mode(...)`
  • javascript events   onclick="..."
  • local javascript function calls   drillDown(...)

to output the data for this repeat loop. This is a good example of how ITS development uses an assortment of different coding and scripting components in the design of a good application screen.

 

Using a hyperlink to both submit an OKcode and trigger a form submit

Hyperlinks do not trigger a form submit. When a user clicks a hyperlink:

<a href="`wGateURL(~okcode="OKCD")` ">`TABLE-FIELD.value`</a>

the OKcode is processed according to screen PAI (post-input) logic, however the contents of the HTML form are not submitted back to the server. Notice what the function call is requesting: ~okcode="OKCD" is submitted to the server via the WGate, but no other fields are included in the request. If a template contains both form input fields and hyperlinks, any changes a user makes to input fields will be lost when the user clicks a hyperlink.

To avoid losing user changes, when an ITS template contains both hyperlinks and form input fields, it is necessary to implement a mechanism to submit the HTML form in its entirety when a hyperlink is clicked. More than one mechanism is possible; the mechanism used in standard Web Services practice requires three components:

HTML

A hidden form element must be included within the form for bHTML parameter, ~okcode. This parameter maps to ABAP system variable, sy-ucomm, and will hold the OKcode to be submitted when the hyperlink is clicked.

<!-- HIDDEN FORM DATA -->
<input type="hidden" name="~okcode" id="~okcode" value="">

Javascript

A locally defined function must write the OKcode value into the hidden form element and trigger a form submit when the hyperlink is clicked. In this example, the fieldChange() and formSubmit() functions from the SUIT API are used by the locally defined function.

<script type="text/javascript">
  function drillDown(p_form,p_ok)
  {
    suit.fieldChange("~okcode",p_ok);
    suit.formSubmit(p_form);
  }
</script>
.
.
.
<a href="#"
onclick="drillDown('formName','OKCD');
return false;">`TABLE-FIELD.value`</a>

ABAP

Per usual, PAI (post-input) logic must recognize and process the value for the OKcode that is submitted.

TOP

Search helps: providing input help

The ZSAPWEB and ZSAPWEBSS libraries provide bHTML function, `matchCode()`, to output a standard searchHelp button for an input field. This function makes use of an SAP-delivered macro called ~searchhelp to output a button that, when clicked, generates a field-specific searchHelp screen. Note that in order to use the ~searchhelp macro, the field must have an associated searchHelp on the GUI screen.

Function `matchCode()` requires two parameters. The first contains the literal name of the field for which the searchHelp is generated. The second may be used to specify the table index of the field when multiple searchHelps are output via a loop statement. The second parameter is left empty for a searchHelp output as an individual field.

Example

Individual field
example

<td nowrap>
  .
  .
  .
  <input type="text" name="`WA_ROOM-NUMBER.name`"
  id="`WA_ROOM-NUMBER.name`" value="`WA_ROOM-NUMBER.value`"
  maxlength="20" size="20">

  `matchCode("WA_ROOM-NUMBER","")`
</td>

Multiple fields via a loop
example

`repeat with j from TC_ROOM.firstvisible to TC_ROOM.lastvisible`
  <tr>
    <td nowrap>
      .
      .
      .
      <input type="text" name="`T_ROOM-NUMBER[j].name`"
      id="`T_ROOM-NUMBER[j].name`" value="`T_ROOM-NUMBER[j].value`"
      maxlength="20" size="20">

     `matchCode("T_ROOM-NUMBER",j)`
    </td>
  </tr>
`end; <!-- end repeat -->`

TOP

CALL TRANSACTION: services that call a secondary service

The back-end GUI transaction associated with an internet service may call a secondary transaction through ABAP statement, CALL TRANSACTION:

CALL TRANSACTION l_secondary_transaction.

To duplicate this functionality in an ITS service, secondary transaction l_secondary_transaction must have an associated internet service whose templates are included in the main Theme folder of the primary service.

Example

example

In this example, ZVERI is the primary internet service and is associated with program SAPMZVERI, which has a single screen, 100. During processing of this screen, the following ABAP statement may be executed depending on user action:

CALL TRANSACTION 'Z_TRANSACTION' AND SKIP FIRST SCREEN.

Transaction Z_TRANSACTION has its own internet service, Z_SERVICE, which may be executed independently or may be called from another service.

Here, primary service ZVERI accommodates the CALL TRANSACTION ABAP statement by including in its main Theme folder the ITS templates for secondary service Z_SERVICE. Each secondary template included may either completely redefine the template for its own purposes in the primary service or may simply contain a call to include the original template as-is directly from the secondary service:

`include(~service="Z_SERVICE",~theme="99",~name="SAPMZGLWEBJV_100.html")`

In addition to including the templates from the secondary service, the primary service should declare ITS service parameter ~sources. This service parameter is not required, but is recommended, when an internet service uses templates from multiple sources.

example

TOP

M I T
I S and T

© Copyright 2002 by the Massachusetts Institute of Technology, Cambridge, MA, USA.
View the full Copyright Notice and Disclaimer.