The Tables documentation describes the general table technique of the S10 framework. In this tutorial we want to get to know the technique by means of an example: Damaged stock items are to be entered in a table. The input mask looks as follows:
To enter the material number, a barcode or QR code can be photographed in addition to the keyboard input. The columns "Quantity" (number of damaged items) and "Damage type" (dropdown list) are entered manually. The material short text, stockkeeping unit and warehouse stock are read from the SAP system.
The application can be operated on the smartphone in landscape format as shown above or also in portrait format. In portrait mode, the display columns "Material short text", "Stock" and "ME" (unit of measure) are hidden, but data entry is still possible without any problems:
If additional information is to be displayed or entered, such as a batch or serial number or the exact storage location, the table can be supplemented with a multi-line output or a separately callable detail screen per line. We limit ourselves here to the single-line view.
We start the development by defining a local ABAP class to describe the table row. In general, the table representation in the S10 framework is based on assigning an ABAP object to each table row. This has the advantage that the techniques of the "build" and "validate" methods (tutorials 2 and 4) are now available per table row, to which we will use in a moment.
We can either enter the local class for the table rows by hand or use the class generator from the S10 utilities. The class looks like this:
The class name, here "mdr" for "Material Damage Report" is freely selectable. The constants "unit_speme" and "unit_labst" ensure that the output is made with the appropriate number of decimal places for the unit of measure.
Compared to the displayed table, we have
We can output the material text directly in HTML using the notation "matnr@text", see s10standardname, so we do not need a separate class attribute for this.
The information "Plant" and "Storage location" are intended for database access to the storage location data of the material (SAP table MARD). Alternatively, we could also place a reference to the header object in each table line and access the plant and storage location via this.
The stockkeeping unit and the current stock level are read from SAP tables. For this purpose, we implement two "build" methods as described in Tutorial 2, which we give the names "build_meins" and "build_labst":
The two build methods are automatically called by the S10 framework per table row. This ensures that the unit of measure and the stock level are each correctly obtained and displayed for the material number entered.
Each material number entered is to be checked for validity, which we achieve by implementing the following method "validate_matnr" (see Tutorial 4):
In the error message we work with the S10 method "s10getuservalue" to display the material number correctly formatted, for example "98" instead of the internal format "00000000000098". Positioning the message on the correct line and setting the input focus on the invalid material number is done automatically by the S10 framework, which knows the connection between the table line and the mdr object:
Now for the definition of the table in ABAP. It is done in a separate class, which we call "mdr_manager"; the name can be chosen arbitrarily.
"delrow" is called by the user by clicking on the icon on the right side of the table row. In the method, to delete the correct row, we need to know in which row the user clicked. This can be done by calling s10contextinfo( ):
At "check" we check for all occupied rows of the table whether quantity and damage type have been entered:
Two details are interesting here:
In the where condition of the loop statement, we can access the line object in ABAP through "table_line":
The call to s10setfocus is made via the row object:
If instead we just call s10setfocus( 'speme' ), the S10 framework tries to find an input field "speme" of the current object of the class "mdr_manager", which does not exist. The error message then appears at the triggering "check" button, making it difficult for the user to associate it with the missing quantity input:
The "save" method is not detailed for the tutorial, as we are concerned with the dialog technique of the entry table at the moment:
Conceivable here is the call of the SAP-BAPI "BAPI_GOODSMVT_CREATE" to create a material document.
The HTML page "create" contains the header with title, the pushbuttons "Check", "Save" and "Logoff", the plant and the storage location, then the entry table and the "New row" button. Since creating the HTML file involves some typing, you can use the S10 generation tool to do this and have it generate a reasonably suitable table as a starting point. Almost all HTML options are HTML5 standard. The S10 framework only interprets the specific CSS classes of the elements to connect to the ABAP objects.The entry table starts in row 59 with the column headings.
Row 59: <div class="colheaders nosort">
The "nosort" option ensures that the re-sorting of table rows, which is normally possible by clicking on a column heading, is omitted. With entry tables, it usually doesn't make much sense to offer re-sorting, and the arrow for the sort order uses up some space in the heading.
Row 63: <div class='colhead output ' style="width: 100px;" name="matnr"></div>
For the CSS class "colhead output" the S10 framework takes the heading from the SAP repository according to the class attribute specified with name= .
Row 64 <div class='colhead output landscape'
style="width: 180px;" name="matnr@text">
With "landscape" this column is not displayed in portrait format
Row 93 <form class='table' name='tabmdr'>After the headings now the actual table, which is introduced by a <form> tag with class='table'. With name= we specify the ABAP name of the table, here "tabmdr". All elements in the following table row are repeated per table row and filled with the values of the table row object.
From line 96 the individual columns of the table. It is important here that the width is exactly the same as the width of the respective column header. For portrait and landscape format you can choose different widths, or suppress columns completely. This is described in the Responsive Webdesign" tutorial.
Row 96 <input type="text" class="inputcell valuehelp" name="matnr"
style="float: left; width: 100px;">
The column "matnr" is ready for input and allows the selection via a search help, see the instructions "Search help".
Row 99 <div class='outputcelldiv landscape'
style="width: 180px; font-size: 13px; font-weight: normal;"
The short text for the entered material number is displayed by name="matnr@text" in this column. In portrait format the column is suppressed because of the CSS class "landscape".
Row 107 <select class="inputcellselect" name="ecode"
style="float: left; width: 170px;">
<optgroup label="Water damage">
<option value="W01">Water damage</option>
<option value="W02">Water traces</option>
<option value="V01">Packing damaged</option>
<option value="V02">Packing dirty</option>
<option value="V03">Packing missing</option>
<option value="V04">Packing empty</option>
<option value="S01">Other damage</option>
Input via a 2-level dropdown list hard-coded in the HTML page. Alternatively, you can also provide dropdown lists in ABAP or take the S10 repository as a basis, see the "Dropdown lists" tutorial. .
Row 129 <div class='outputcelldiv landscape'
style="width: 60px;" name="meins@text">
For the unit of measure, we output the language-dependent label provided by name="meins.text" by the S10 framework.
<!-- delete row -->
<img style="width: 16px; height: 16px; margin-left: 10px;"
Output of an icon for deleting the line. Via S10Apply( "delrow" ) the ABAP method "delrow" is called.
Row 142 <button type="button" class="button-small"
style='margin: 4px; background-color: #937a7a; color: white;'
The "Add row" button that appears following the entry table. Alternatively, we can add an icon "Insert new row" in each table row and then insert a new row before the row in question. Since the order of the captured materials is not important in this application, we have limited ourselves to the space-saving variant of always adding rows at the end.