In der Anleitung Reiter ist beschrieben, wie ein Screen im S10 Framework in verschiedene Bereiche aufgeteilt wird, zu denen der Benutzer über Reiter (Registerkarten) navigieren kann.
In diesem Tutorial implementieren wir die Technik anhand eines Beispiels und besprechen mögliche Varianten.
Unsere Musteranwendung stellt einige Informationen zum Kunden auf drei Reitern dar:
Das S10 Framework leistet dabei folgendes:
Die Darstellung der Reiter wie oben dargestellt ist einfach und platzsparend, sodass Sie auch im Hochformat ca. 4-5 Reiter ohne Zeilenumbruch unterbringen können:
Falls Sie mehr Reiter benötigen, ist empfehlenswert, statt des Textes ein Icon anzuzeigen. Sie können dabei im Querformat ein Icon plus Text anzeigen und im Hochformat nur das Icon. Das sieht dann in unserem Beispiel wie folgt aus:
Nun zur Implementierung. Wir benötigen erstens die Reiterleiste und zweitens für jeden Reiter einen Bereich, der bei Klick auf den Reiter eingeblendet wird. In unserem Beispiel sieht das wie folgt aus:
<!-- tabstrip --> <table class='tabstrip'> <tr> <td id='tabaddr' class='tabactive'
onclick='S10ActivateTab(this);'> Adresse </td> <td id='tabpart' class='tab'
onclick='S10ActivateTab(this);'> Partner </td> <td id='tabsales' class='tab'
onclick='S10ActivateTab(this);'> Umsatz </td> </tr> </table> <!-- Adresse --> <div class="tabpageactive" id="tabaddr.area"> ... </div> <!-- Partner --> <div class="tabpage" id="tabpart.area"> ... </div> <!-- Umsatz --> <div class="tabpage" id="tabsales.area"> ... </div>
Bitte dabei auf folgendes achten:
Falls Sie ein Icon plus Text anzeigen und wie im Beispiel oben Hochformat und Querformat unterscheiden, wird es etwas komplizierter:
<!-- tabstrip --> <table class='tabstrip' style="height: 36px;"> <tr> <td id='tabaddr' style='width: 120px; height: 36px; --portrait-width: 80px' class='tabactive' onclick='S10ActivateTab(this);'> <img src="../../../icons/home.png" style="height: 28px; vertical-align: bottom;" /> <span class='landscape'>Adresse</span> </td> <td id='tabpart' style='width: 120px; height: 36px; --portrait-width: 80px' class='tab' onclick='S10ActivateTab(this);'> <img src="../../../icons/partners.png" style="height: 28px; vertical-align: bottom;" /> <span class='landscape'>Partner</span> </td> <td id='tabsales' style='width: 120px; height: 36px; --portrait-width: 80px' class='tab' onclick='S10ActivateTab(this);'> <img src="../../../icons/sales.png" style="height: 28px; vertical-align: bottom;" /> <span class='landscape'>Umsatz</span> </td> </tr> </table>
Damit ist das Grundgerüst der HTML-Seite fertig. Das S10 Framework blendet nun bei einem Klick auf einen Reiter den entsprechenden Teil ein und fordert die nötigen Daten vom Backend an.
Auf ABAP-Seite implementieren wir build-Methoden für die anzuzeigenden Elemente. Sie werden durch das S10 Framework automatisch aufgerufen, sobald die Daten gebraucht werden.
Für das Thema "Reiter" kommt es jetzt zwar nicht auf die Details der ABAP-Methoden an, aber trotzdem hier das gesamte nötige ABAP-Coding mit einigen Kommentaren:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
* partnerinfo class partnerinfo definition inheriting from /s10/any. public section. data: parvw type parvw, partnerkey type string, partnername type string, city type string. endclass. * salesinfo class salesinfo definition inheriting from /s10/any. public section. data: prodh type vbrp-prodh, netwr1 type p decimals 0, netwr2 type p decimals 0, percentage type p decimals 1. methods: build_percentage importing netwr1 type p netwr2 type p exporting percentage type p. endclass. class salesinfo implementation. method build_percentage. if netwr1 eq 0. percentage = 0. else. percentage = netwr2 * 100 / netwr1. endif. endmethod. endclass. class kna1_detail definition inheriting from /s10/any. public section. * Kundeninfo (Name, Adresse) data: kunnr type kna1-kunnr, " Debitor name1 type kna1-name1, " Name name2 type kna1-name2, " Name 2 ort01 type kna1-ort01, " Ort pstlz type kna1-pstlz, " Postleitzahl land1 type kna1-land1, " Land using Text stras type kna1-stras, " Straße telf1 type kna1-telf1, " Telefon-1 partners type table of ref to partnerinfo, sales type table of ref to salesinfo. * database table name constants: dbtablename type string value 'kna1'. " for select methods: * partners build_partners importing kunnr type kunnr exporting partners type table, * sales build_sales importing kunnr type kunnr exporting sales type table. endclass. class kna1_detail implementation. * partners method build_partners. refresh partners. data: begin of pt, parvw type knvp-parvw, parnr type knvp-parnr, kunn2 type knvp-kunn2, pernr type knvp-pernr, end of pt, kna1 type kna1, pa0002 type pa0002, line(80) type c. select * from knvp into corresponding fields of pt where kunnr = kunnr and vkorg = '1010' "fixed demo values for sales area and vtweg = '10' and spart = '00' and ( kunn2 ne space or pernr ne space ) order by parvw. data: pi type ref to partnerinfo. create object pi. pi->parvw = pt-parvw. if pt-kunn2 ne space. write pt-kunn2 to line no-zero. pi->partnerkey = line. select single name1 ort01 from kna1 into corresponding fields of kna1 where kunnr = pt-kunn2. pi->partnername = kna1-name1. pi->city = kna1-ort01. endif. if pt-pernr ne space. write pt-pernr to line no-zero. pi->partnerkey = line. clear pa0002. select nachn vorna from pa0002 into corresponding fields of pa0002 where pernr = pt-pernr. endselect. concatenate pa0002-nachn pa0002-vorna into pi->partnername separated by space. endif. append pi to partners. endselect. s10sort( foldername = 'partners' columns = 'parvw' userformat = 'X' ). endmethod. * sales method build_sales. data: year1 type vbrk-gjahr, year2 type vbrk-gjahr. year2 = sy-datum(4). year1 = year2 - 1. data: begin of s, prodh type vbrp-prodh, gjahr type vbrk-gjahr, netwr type vbrp-netwr, end of s, stab like table of s, totals type ref to salesinfo. data: ps type ref to salesinfo. refresh sales. select left( vbrp~prodh, 5 ) as prodh, vbrk~gjahr as gjahr, sum( vbrp~netwr ) as netwr from vbrp inner join vbrk on vbrk~vbeln = vbrp~vbeln where vbrk~kunag = @kunnr and vbrp~posar in (' ','A') and vbrk~gjahr in (@year1,@year2) group by prodh, gjahr order by prodh into corresponding fields of table @stab. create object totals. totals->prodh = '***'. loop at stab into s. at new prodh. create object ps. ps->prodh = s-prodh. endat. case s-gjahr. when year1. ps->netwr1 = s-netwr. when year2. ps->netwr2 = s-netwr. endcase. at end of prodh. append ps to sales. * totals add ps->netwr1 to totals->netwr1. add ps->netwr2 to totals->netwr2. endat. endloop. append totals to sales. * emphasize totals totals->s10addcss( attrname = 'prodh' cssclassname = 'totals' ). totals->s10addcss( attrname = 'netwr1' cssclassname = 'totals' ). totals->s10addcss( attrname = 'netwr2' cssclassname = 'totals' ). totals->s10addcss( attrname = 'percentage' cssclassname = 'totals' ). endmethod. endclass. |
Zeile 2: Die Klasse "partnerinfo" beschreibt die Zeilen der Tabelle "Partner". Sie besteht nur aus der Deklaration, da wir keine Methoden benötigen.
Zeile 16: Entsprechend für die Umsatztabelle die Klasse "salesinfo". Hier ist eine build-Methode zum Berechnen des Prozentsatzes implementiert.
Zeile 50: Hier beginnt die Klasse "kna1-detail", welche die eigentlichen Kundendaten enthält.
Zeilen 66 und 67: Die beiden Tabellen "partners" und "sales"
Zeilen 95 und 162: Die build-Methoden für die beiden Tabellen.
Zeile 225: Um die Umsatzsummen hervorzuheben, ordnen wir den Attributen des Summen-Zeilenobjekts die CSS-Klasse "totals" zu. Sie ist in der HTML-Seite wie folgt definiert:
<style> .totals { color: #0854a0; font-weight: bold; } </style>
Das HTML-Coding für die einzelnen Teile:
Ausgabe der Kundenadresse
<div class="tabpageactive" id="tabaddr.area" style="padding: 10px">
<div class='output' style='font-size: 16px;' name="mykna1.name1"></div> <div class='output' style='font-size: 16px;' name="mykna1.name2"></div> <div class='output' style='font-size: 16px;' name="mykna1.stras"></div> <div> <span class='output' style='font-size: 16px;' name="mykna1.pstlz"></span> <span class='output' style='font-size: 16px;' name="mykna1.ort01"></span> </div> <div class='output' style='font-size: 16px;' name='mykna1.land1@text'></div> </div>
Ausgabe der Partnertabelle
<div class="tabpage" id="tabpart.area">
<div class="colheaders"> <div name="parvw" class='colhead colheadup output' style='width: 60px; --landscape-width: 60px;'> </div> <div name="parvw@text" class='colhead output landscape' style='width: 100px; --landscape-width: 160px;'> </div> <div name="partnerkey" class='colhead landscape' style='width: 70px; --landscape-width: 100px;'> Nummer </div> <div name="partnername" class='colhead' style='max-width: 300px; --portrait-width: calc(100% - 180px); --landscape-width: calc(100% - 460px);'> Name </div> <div name="city" class='colhead' style='width: 120px;'> Ort </div> </div> <form class='table' name='mykna1.partners'> <div class="tablerow"> <div name="parvw" class="outputcelldiv" style='width: 60px; --landscape-width: 60px;'></div> <div name="parvw@text" class="outputcelldiv landscape" style='width: 100px; --landscape-width: 160px;'></div> <div name="partnerkey" class="outputcelldiv landscape" style='width: 70px; --landscape-width: 100px;'> </div> <div name="partnername" class="outputcelldiv" style='max-width: 300px; --portrait-width: calc(100% - 180px); --landscape-width: calc(100% - 460px);'> </div> <div name="city" class="outputcelldiv" style='width: 120px;'></div> </div> </form> </div>
Ausgabe der Umsatztabelle
<div class="tabpage" id="tabsales.area"> <div class="colheaders"> <div class='colhead colheadup' style='width: 50px;' name="prodh">Nr.</div> <div class='colhead' style='max-width: 240px; width: calc(100% - 280px); --portrait-width: calc(100% - 230px);' name="prodh@text"> Produkthierarchie </div> <div class='colhead' style='width: 90px; text-align: right' name="netwr1"> Vorjahr </div> <div class='colhead' style='width: 90px; text-align: right' name="netwr2"> Aktuell </div> <div class='colhead landscape' style='width: 50px; text-align: right' name="percentage">%</div> </div> <form class='table' name='mykna1.sales'> <div class="tablerow"> <div class='outputcelldiv' style='width: 50px;' name="prodh"> </div> <div class='outputcelldiv' style='max-width: 240px; width: calc(100% - 280px); --portrait-width: calc(100% - 230px);' name="prodh@text"> </div> <div class='outputcelldiv' style='width: 90px; text-align: right' name="netwr1"> </div> <div class='outputcelldiv' style='width: 90px; text-align: right' name="netwr2"> </div> <div class='outputcelldiv landscape' style='width: 50px; text-align: right' name="percentage"> </div> </div> </form> </div>