The documentation Tabs describes how a screen in the S10 Framework is divided into different areas to which the user can navigate via tabs.
In this tutorial we implement the technique with an example and discuss possible variations.
Our sample application presents some information about the client on three tabs:
The S10 framework does the following:
The display of the tabs as shown above is simple and space-saving, so that you can also accommodate approx. 4 or 5 tabs in portrait format without line breaks:
If you need more tabs we recommended you display an icon instead of the text. You can display an icon plus text in landscape format and only the icon in portrait format. In our example, it looks like this:
Now for the implementation. Firstly, we need the tab bar and secondly, an area for each tab that is displayed when the tab is clicked. In our example, it looks like this:
<!-- tabstrip --> <table class='tabstrip'> <tr> <td id='tabaddr' class='tabactive'
onclick='S10ActivateTab(this);'> Address </td> <td id='tabpart' class='tab'
onclick='S10ActivateTab(this);'> Partners </td> <td id='tabsales' class='tab'
onclick='S10ActivateTab(this);'> Sales </td> </tr> </table> <!-- Adress --> <div class="tabpageactive" id="tabaddr.area"> ... </div> <!-- Partners --> <div class="tabpage" id="tabpart.area"> ... </div> <!-- Sales --> <div class="tabpage" id="tabsales.area"> ... </div>
Pay attention to the following:
If you display an icon plus text and distinguish between portrait and landscape format, as in the example above, it gets a bit more complicated:
<!-- 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'>Address</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'>Partners</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'>Sales</span> </td> </tr> </table>
The basic structure of the HTML page is now ready. When you click on a tab, the S10 Framework now displays the corresponding part and requests the necessary data from the backend.
On the ABAP side, we implement build methods for the elements to be displayed. They are called automatically by the S10 framework as soon as the data is needed.
For the topic "tabs", the details of the ABAP methods are not important, but here is all the necessary ABAP coding with some comments:
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. * client info (name, address) data: kunnr type kna1-kunnr, " client number name1 type kna1-name1, " name name2 type kna1-name2, " name 2 ort01 type kna1-ort01, " city pstlz type kna1-pstlz, " postal code land1 type kna1-land1, " country stras type kna1-stras, " street telf1 type kna1-telf1, " phone number 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 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. |
Line 2: The class "partnerinfo" describes the rows of the table "Partner". It consists only of the declaration, as we do not need any methods.
Line 16: Accordingly, the class "salesinfo" for the sales table. A build method for calculating the percentage is implemented here.
Line 50: Here begins the class "kna1-detail", which contains the actual customer data.
Lines 66 and 67: The two tables "partners" and "sales"
Lines 95 and 162: The build methods for the two tables.
Line 225: To highlight the turnover totals, we assign the CSS class "totals" to the attributes of the totals line object. It is defined in the HTML page as follows:
<style> .totals { color: #0854a0; font-weight: bold; } </style>
The HTML coding for the individual parts:
Output of the customer address
<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>
Output of the partner table
<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;'> Number </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;'> City </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>
Output of the sales table
<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"> Product hierarchy </div> <div class='colhead' style='width: 90px; text-align: right' name="netwr1"> Prev. year </div> <div class='colhead' style='width: 90px; text-align: right' name="netwr2"> Current </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>