
The next step after Step 1: Using <htmlb:SimpleFormItem> is similar. You must first enhance the simple form handler class so that the entries are not written as soon as they are added. The entries must be collected and rendered at the end.
Add two string tables as class attributes to class CL_BSP_TUTCMPLX_SIMPLE_FORM:
|
Name |
Type |
Visibility |
Typing Kind |
Reference Type |
Description |
|
LABELS |
instance attribute |
private |
TYPE |
STRING_TABLE |
Table of strings |
|
INPUTFIELDS |
instance attribute |
private |
TYPE |
STRING_TABLE |
Table of strings |
Change the ADD_ITEM method to collect the entries:
method ADD_ITEM .
APPEND label_html TO labels.
APPEND inputField_html TO inputFields.
endmethod.
Ensure that an element handler class can be reused several times. This is triggered by the code generator for the BSP. This is why the whole local data structure must be reset each time that a new element is restarted.
The coding that is executed at the beginning must be changed as follows:
method IF_BSP_ELEMENT~DO_AT_BEGINNING .
CLEAR labels.
CLEAR inputFields.
RC = CO_ELEMENT_CONTINUE.
endmethod.
In the last step, the whole rendering should be executed at the end tag of the element.
The coding for the output would therefore be as follows:
<htmlb:GridLayout ...>
LOOP AT labels/fields
<htmlb:GridLayoutCell ...>
output "label" string
</htmlb:GridLayoutCell>
<htmlb:GridLayoutCell ...>
output "inputfield" string
</htmlb:GridLayoutCell> ENDLOOP.
</htmlb:GridLayout>
Here, the most interesting point is that tags must be processed with bodies. An element would usually be processed by a WHILE loop, while PROCESS_ELEMENT is called at the end. As a result, both the start and the end tag are processed. After the first processing call, the element was pushed on the processing stack and is therefore available as if the compiler had generated the code. After the inner tag has been processed, the second call of PROCESS_ELEMENT is required for processing the end tag.
The <htmlb:gridLayout> is processed in the first part of the coding. There then follows a LOOP, in which all of the calls are executed, and finally the end tag </htmlb:gridLayout> must be processed. Ensure that the whole output is written to the currently active writer.
The coding is as follows:
method IF_BSP_ELEMENT~DO_AT_END .
* <htmlb:gridLayout>
DATA: gridLayout TYPE REF TO CL_HTMLB_GRIDLAYOUT.
CREATE OBJECT gridLayout.
gridLayout->id = me->id.
gridLayout->cellSpacing = '0'.
gridLayout->cellPadding = '2'.
gridLayout->rowSize = lines( labels ).
gridLayout->columnSize = 2.
gridLayout->width = '100%'.
m_page_context->ELEMENT_PROCESS( element = gridLayout ).
* Output all cells.
DATA: label TYPE STRING,
inputField TYPE STRING.
LOOP AT labels INTO label.
READ TABLE inputFields INTO inputField INDEX sy-tabix.
....code to process gridLayoutCell for label and for inputField
ENDLOOP.
* </htmlb:gridLayout>
m_page_context->ELEMENT_PROCESS( element = gridLayout ).
rc = CO_PAGE_CONTINUE.
endmethod.
Processing the <htmlb:gridLayoutCell> element is slightly more complex. The reason for this is that for each cell, the current body (the HTML string that was previously collected) must be written to the output stream.
The coding is therefore split into three steps. First the start tag is processed, then the body is written to the current output writer, and finally the end tag is processed. For the <htmlb:label> string, the coding is as follows:
* <htmlb:gridLayoutCell> for label
DATA: gridLayoutCell TYPE REF TO CL_HTMLB_GRIDLAYOUTCELL.
CREATE OBJECT gridLayoutCell.
gridLayoutCell->rowIndex = sy-tabix.
gridLayoutCell->columnIndex = 1.
gridLayoutCell->horizontalAlignment = 'LEFT'.
gridLayoutCell->verticalAlignment = 'MIDDLE'.
m_page_context->ELEMENT_PROCESS( element = gridLayoutCell ).
* print content
DATA: out TYPE REF TO IF_BSP_WRITER.
out = me->m_page_context->GET_OUT( ).
out->PRINT_STRING( label ).
* </htmlb:gridLayoutCell>
m_page_context->ELEMENT_PROCESS( element = gridLayoutCell ).
Ensure that the output writer that is currently active is not received until just before it is used. It is important that GET_OUT() is called each time an element is processed. Every element can push additional writers on the stack, even the BSP framework can add its own writer to the stack from time to time. If only one single writer is received at the start of the method, this is therefore probably the parent writer of the gridLayout, that is, all of the new output is written to the parent writer of the gridLayout. It is therefore important that the new active writer is always received after a PROCESS_ELEMENT call and before the new output.
The method PROCESS_ELEMENT is aligned with element processing, even if they require iteration. In theory, after every write/processing cycle the system should check explicitly whether the element has finished. In this case, the element does not include iteration. PROCESS_ELEMENT can therefore be called again without any problems.
In cases where only one body must be written, particularly if the body is already present as a string, the body can be transferred as a parameter of the PROCESS_ELEMENT method. A writer is not required, and the processing code automatically writes the body correctly and finished processing the method.
The more simple coding is as follows (here string inputField is used as an example):
* <htmlb:gridLayoutCell/> for inputField
CREATE OBJECT gridLayoutCell.
gridLayoutCell->rowIndex = sy-tabix.
gridLayoutCell->columnIndex = 2.
gridLayoutCell->horizontalAlignment = 'LEFT'.
gridLayoutCell->verticalAlignment = 'MIDDLE'.
m_page_context->ELEMENT_PROCESS( element = gridLayoutCell body = inputField ).
Ensure that the gridLayoutCell object is not reused. This is expressly forbidden. It must be newly created each time a new element is required.
In the last step, you make changes to the look and feel.