Dynamic drop-down entry fields (1)

When you implement a data entry screen as HTML page with the GuiXT Viewer component, you can use drop-down entry fields with a fixed option list. For example, when the user needs to enter a "Company Code", you can offer him a drop-down field by copying the list of valid company codes and their texts from the SAP system into your HTML page.

A disadvantage of this approach is that future changes in the SAP system, e.g. a new company code or a text change, will  require a correction in your HTML coding.  You also need to copy the texts for all languages that are used in the system.

In this article we describe a way to use dynamic drop-down lists that are generated at runtime, reading the SAP customizing tables.

Our  example shows how you replace a single entry field (company code in FB01) with a drop down list.

 


SAP standard

 


Customized with GuiXT: drop-down field for company code

 


The company code list is read at runtime from the SAP system

 

Since we want to provide excellent response times for the user when he displays the drop down list, we use the following approach:

  • The company code list is read only once for each SAP mode
  • The View window for the drop down list is kept when the user leaves the screen, and is reused the next time (option id="..." in View command).

A further optimization could be to use the generated list for all SAP modes (using shared GuiXT text variables), or to generate an HTML file periodically into a folder that is shared by all users and that includes the company code list.

The implementation under discussion here requires advanced HTML and InputAssistant skills.

 

HTML page

The HTML page consists of a drop-down field for the company code with the option list empty. When the user changes a value, we call a JavaScript routine that sends the new value to the SAP screen:

<select size="1" name="cc" id="cc" style="width:240px; font-family:sans-serif; font-size:9pt; color:#525252" onchange="cc_select(this);"></select>
 

JavaScript routine that sends the value to the SAP screen, using the SAP_URL mechanism of GuiXT Viewer:

// Send changed value to SAP screen
function cc_select(f)
{
  if (f && typeof(f.value) == 'string')
  {
    window.location = "SAP://Company Code:" + f.value + ";";
  };
}

This mechanism works even when the original SAP entry field "Company Code" is deleted from the Screen via GuiXT.

We also need a way to build the company code list in the HTML page. Here we use a hidden field and a button that we can address with the "ConnectHTML" statement. For performance reasons it is important that we do not send each single company code with a separate ConnectHTML statement. Since "ConnectHTML" reparses the HTML DOM, this would be too slow if a large number of values need to be sent. Instead, we block the values sending long strings that contain a number of entries (up to 100 in our implementation), separated by a special string "~~~" that does not occur in the value list.

<div style='visibility:hidden'>
  <input type="text" id="optionstring" name="optionstring" size="8">
  <input type="button" name="AcceptOptions" value="AcceptOptions" size="8" onclick="DoAcceptOptions();" >
</div>

 

JavaScript routine:

// Receive company codes from SAP and generate drop-down list
function DoAcceptOptions()
{
  var f = document.getElementById('cc');
  var optlist = f.options;
  var opt = document.getElementById('optionstring');

  var s = new Array();
  s = opt.value.split("~~~");

  for (var i = 0; i<s.length-1; i +=2)
  {
    optlist[optlist.length] = new Option(s[i+1], s[i]);
  };
};
 

Here is a copy of the whole HTML page "ccdropdown.html":

 

GuiXT script

The GuiXT deletes the entry field for the company code and displays the HTML page instead. The coordinates in the "View" statement  use negative numbers and decimal places in order to fit the View area correctly into the SAP screen.

Since the SAP screen can come up with a default value for the company code (user specific value or value entered in previous transaction), we need to set the current value of F[Company Code] into the drop-down HTML field.

The first time the drop-down field is displayed, we generate the value list using a separate include file.

The whole GuiXT script:

del F[Company Code] -value
View (-0.5,63.4) (0.5,97.4) "ccdropdown.html" returnwindow="hwnd_fb01_cc_dropdown" id="fb01_ccdropdown"

if not V[ccdropdown_initialized]
  include "build_select_companycode.txt"
endif

Set HTML[select_cc] "&F[Company Code]"

 

Generation of the value list

We need an ABAP function module that reads all company codes with their texts from the SAP system. This can be a special function module that you write for this purpose, or you can use a general one like the SAP function "RFC_READ_TABLE".

In our case here we use a function "Z_S10_SEARCHHELP" that has been written by Synactive as part of the Synactive S10 system (http://www.synactives10.com/s10forum). It reads searchhelp lists from the SAP system and can easily be used in GuiXT scripts.

The script reads all values into a text variable and then sends the values to the HTML page. For performance reasons, 100 entries are concatenated each time into a single string and then sent.

-> For large lists, it is currently not possible to send all values in a single string because of  a capacity limit of the statement length in GuiXT (4000 characters). For this reason, a blocking of 100 values each time is used.

GuiXT script "build_select_companycode.txt":


// Indicate: initialized
Set V[ccdropdown_initialized] "X"


// read values from SAP
Call "Z_S10_SEARCHHELP" in.SEARCHHELP="H_T001" in.COLUMNS="BUKRS(4),BUTXT(25)" table.DATA="data"

set V[i] 1
set V[k] 1
set V[cc_option] ""
set Text[options] ""

label cc_next

CopyText fromText="data" toString="line" line=&V[i]
if not Q[ok]
  goto cc_done
endif

Set V[cc_code] "&V[line](1-4)"
Set V[cc_text] "&V[line](5-29)"
Set V[cc_option] "&V[cc_code]~~~&V[cc_code] &V[cc_text]~~~"

CopyText fromString="cc_option" toText="options" -append

Set V[i] &V[i] + 1
Set V[k] &V[k] + 1
 

// send 100 entries
if V[k=100]
  CopyText fromText="options" toString="cc_option"
  set Text[options] ""
  Set HTML[text_optionstring] "&V[cc_option]"
  connectHTML click="button_AcceptOptions" window="&V[hwnd_fb01_cc_dropdown]"
  Set V[k] 1
endif

goto cc_next

label cc_done
 

// send remaining entries
CopyText fromText="options" toString="cc_option"
set Text[options] ""
Set HTML[text_optionstring] "&V[cc_option]"

connectHTML click="button_AcceptOptions" window="&V[hwnd_fb01_cc_dropdown]"