Show TOC

HintergrundSchritt 2: Erstellen von <sf:SimpleForm> Dieses Dokument in der Navigationsstruktur finden

 

Der nächste Schritt nach dem Schritt 1: Verwendung von <htmlb:SimpleFormItem> ist ganz ähnlich. Zuerst muss die einfache Form-Handler-Klasse erweitert werden, um die Einträge nicht sofort herauszuschreiben, sobald sie hinzugefügt wurden. Die Einträge müssen gesammelt und am Ende herausgerendert werden.

Fügen Sie der Klasse CL_BSP_TUTCMPLX_SIMPLE_FORM zwei String-Tabellen als Klassenattribute hinzu:

Name

Art

Sichtbarkeit

Typisierungsart

Bezugstyp

Beschreibung

LABELS

Instanzattribut

private

TYPE

STRING_TABLE

Tabelle von Strings

INPUTFIELDS

Instanzattribut

private

TYPE

STRING_TABLE

Tabelle von Strings

Ändern Sie die ADD_ITEM-Methode, um die Einträge zu sammeln:

Syntax Syntax

  1. method ADD_ITEM .
      APPEND label_html      TO labels.
      APPEND inputField_html TO inputFields.
    
    endmethod.
    
    
Ende des Codes

Achtung Achtung

Beachten Sie, dass eine Elementhandler-Klasse mehrfach wiederverwendet werden kann. Dies wird vom Code-Generator für die BSP ausgelöst. Daher müssen jedes Maldie gesamten lokalen Datenstrukturen zurückgesetzt werden, wenn ein Element erneut gestartet wird.

Ende der Warnung.

Das Coding, das am Anfang ausgeführt wird, muss folgendermaßen geändert werden:

Syntax Syntax

  1. method IF_BSP_ELEMENT~DO_AT_BEGINNING .
    
      CLEAR labels.
      CLEAR inputFields.
      RC = CO_ELEMENT_CONTINUE.
    
    endmethod.
    
    
Ende des Codes

Im letzten Schritt soll das gesamte Rendering am Ende-Tag des Elements durchgeführt werden.

Das Coding für den Output würde also ganz abstrakt folgendermaßen aussehen:

Syntax Syntax

  1. <htmlb:GridLayout ...>
    LOOP AT labels/fields
        <htmlb:GridLayoutCell ...>
          output "label" string
        </htmlb:GridLayoutCell>
    
        <htmlb:GridLayoutCell ...>
          output "inputfield" string
        </htmlb:GridLayoutCell> ENDLOOP.
    
    </htmlb:GridLayout>
    
    
Ende des Codes

Hier ist der interessanteste Aspekt, dass Tags mit Bodys verarbeitet werden müssen. Normalerweise würde die Verarbeitung eines Elements über einer WHILE-Schleife durchgeführt, wobei bis zum Ende PROCESS_ELEMENT aufgerufen wird. Dies führt dazu, dass sowohl das Anfangs- als auch das Ende-Tag verarbeitet werden. Nach dem ersten Verarbeitungsaufruf wurde das Element auf den Verarbeitungsstack geschoben und steht damit zur Verfügung, so als ob der Compiler den Code generiert hätte. Später, nach der Verarbeitung der inneren Tags, wird der zweite Aufruf von PROCESS_ELEMENT für die Verarbeitung des Ende-Tags benötigt.

Im ersten Teil des Codings wird das <htmlb:gridLayout> prozessiert. Danach folgt eine LOOP, in der die ganzen Aufrufe ausgeführt werden, und schließlich muss das Ende-Tag </htmlb:gridLayout> verarbeitet werden. Beachten Sie, dass der gesamte Output auf den akutellen aktiven Writer geschrieben wird.

Das Coding sieht folgendermaßen aus:

Syntax Syntax

  1. 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.
    
    
Ende des Codes

Die Verarbeitung der <htmlb:gridLayoutCell>-Elemente ist etwas komplexer. Dies liegt daran, dass für jede Zelle der aktuelle Body (also der bereits früher gesammelte HTML-String) auf den Output-Stream geschrieben werden muss.

Daher wird das Coding in drei Schritte aufgespalten. Zuerst wird das Anfangs-Tag verarbeitet, dann wird der Body auf den aktuellen Output-Writer geschrieben, und schließlich wird das Ende-Tag verarbeitet. Für den <htmlb:label>-String sieht das Coding folgendermaßen aus:

Syntax Syntax

  1. *   <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 ).
    
    
Ende des Codes

Achtung Achtung

Beachten Sie, dass der aktuelle aktive Output-Writer erst direkt vor seinem Gebrauch erhalten wird. Es ist wichtig, GET_OUT() jedes Mal aufgerufen wird, nachdem ein Element verarbeitet wurde. Jedes Element kann zusätzliche Writer auf den Stack schieben. Auch das BSP-Framework kann von Zeit zu Zeit seine eigenen Writer dem Stack hinzufügen. Wenn zu Beginn der Methode nur ein einziger Writer erhalten wird, ist dies daher wahrscheinlich der Parent-Writer des gridLayout, d.h. der gesamte neue Output wird in den Parent-Writer des gridLayout geschrieben. Deshalb ist es wichtig, nach einem PROCESS_ELEMENT-Aufruf und vor den neuen Output immer den neue aktiven Writer zu erhalten.

Ende der Warnung.

Die Methode PROCESS_ELEMENT ist ausgerichtet auf die Verarbeitung von Elementen auch wenn sie Iteration benötigen. Theoretisch muss daher nach jedem Schreib-/Verarbeitungszyklus explizit nachgesehen werden, ob das Element beendet ist. Im vorliegenden Fall ist jeoch vorgegeben, dass das Element keine Iteration beinhaltet. Daher kann PROCESS_ELEMENT problemlos erneut aufgerufen werden.

In Fällen, in denen nur ein Body herausgeschrieben werden muss, insbesondere wenn der Body bereits als String vorliegt, kann der Body als Parameter der PROCESS_ELEMENT Methode übergeben werden. Dann wird kein Writer benötigt, und der Verarbeitungscode wird automatisch den Body korrekt herausschreiben und die Verarbeitung der Methode korrekt vervollständigen.

Die einfachere Form des Codings sieht folgendermaßen aus (hier dient der Sting inputField als Beispiel):

Syntax Syntax

  1. *   <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 ).
    
Ende des Codes

Achtung Achtung

Beachten Sie, dass das gridLayoutCell-Objekt nicht wiederverwendet wird. Dies ist ausdrücklich verboten. Jedes Mal, wenn ein neues Element benötigt wird, muss es neu kreiert werden.

Ende der Warnung.

Im letzten Schritt nehmen Sie Änderungen am Look & Feel vor.