Wir beginnen mit der folgenden kleinen Anwendung: Der Benutzer meldet sich an, gibt eine Kundennummer ein, drückt einen Button "Anzeigen" und erhält dann Namen und Adresse des Kunden. 

Anmeldung

 

Eingabe der Kundennummer und Drücken des "Anzeigen" Buttons

 

Anzeige von Namen und Adresse

Wir implementieren dazu eine ABAP-Klasse "customer" sowie drei HTML-Dateien "logon", "start" und "display" , welche den drei Screenshots oben entsprechen.

1.  Die ABAP-Klasse "customer"

Wir legen die Klasse lokal in einem ABAP-Programm mit dem Namen "ZZS10_CUSTOMER" an, wobei der Programname frei wählbar ist. Auch globale ABAP-Klassen (SE24) sind möglich. Als Attribute geben wir die Kundennummer, den Namen und die gewünschten Adressfelder an. Die Methoden sind "logon" und "display":

 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
program zzs10_customer.

class customer definition inheriting from /s10/any.

  public section.
    data:
      kunnr type kna1-kunnr, " Customer number
      land1 type kna1-land1, " Country
      name1 type kna1-name1, " Name
      ort01 type kna1-ort01, " City
      pstlz type kna1-pstlz, " Postal code
      stras type kna1-stras. " Street

* database table name
    constants:
      dbtablename type string value 'kna1'. " for s10databaseread

    methods:
      logon,
      display.

endclass.

class customer implementation.

* logon user
  method logon.

* set S10 license
    s10setlicense( 'Synactive GmbH demo license number=100 role=s10demo_role maxusers=10 signature=821.126.87.7' ).

* set start screen
    s10nextscreen( 'start').

  endmethod.

* display customer data
  method display.
    if not s10databaseread( ).
      s10errormessage( 'Bitte eine gültige Kundennummer eingeben' ).
    endif.

    s10nextscreen( 'display').

  endmethod.

endclass.


Einige Erläuterungen hierzu:

 

Bemerkung:

Mit der S10-Utility-Transaktion /s10/util können Sie sich derartige Klassen und ganze Anzeigetransaktionen inclusiv der HTML-Dateien generieren lassen, was bei Verwendung vieler Tabellenfelder sehr bequem und zeitsparend ist. Für unsere Tutorials verwenden wir die Generierung nicht, um die S10-Logik besser kennenzulernen.

 

ABAP Debugging

Sie können den ABAP Debugger in vollem Umfang nutzen. Setzen Sie dazu einen "externen Breakpoint" im ABAP Editor an der Stelle, an der Sie anhalten möchten:

Danach führen Sie die S10 Anwendung aus. Der ABAP Debugger wird aktiv, sobald die markierte Stelle im Coding erreicht wird:

Jetzt können Sie z.B. Variablen anzeigen oder schrittweise weitergehen.

Bitte beim Einschalten beachten, dass der externe Breakpoint nur wirksam wird, wenn es bei Einschalten des Debuggers (SAP GUI Session) und bei der Anmeldung in der S10 Anwendung um den gleichen Benutzernamen handelt. Falls Sie z.B. zur Klärung von Berechtigungsproblemen das Debuggen für einen anderen S10-Benutzernamen verwenden wollen, können Sie diesen in den Debugger-Einstellungen angeben:

 

 

2. Der Logon-Screen

Der logon-Screen ist als HTML-Datei immer in der Klasse "user" für die  Sprache Englisch abgelegt. In einem späteren Tutorial beschreiben wir, wie Sie dynamisch auf die im Browser eingestellte Sprache des Benutzers wechseln können, falls Sie das logon-Bild mehrsprachig halten möchten.

Bei den Screenshots für die Ablage der HTML-Dateien gehen wir davon aus, dass Sie diese lokal auf Ihrem PC entwickeln wie in Lokale Entwicklung beschrieben  und erst später in das SAP MIME Repository hochladen.


Sie können den Logon-Screen frei gestalten; nur einige Elemente zur Verknüpfung mit dem S10 Framework sind nötig. Falls Sie eine Anwendung in das Fiori-Launchpad integrieren, wird der Logon-Screen nie angezeigt, da die Anmeldung über die Launchpad-Anmeldung geschieht.

  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
<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=400">
    <link href="../../../style/s10.style.css" rel="stylesheet" type="text/css">
    <link rel='stylesheet' type='text/css' href='../../../style/custom.style.css'>
    <script src="../../synactiveS10/synactiveS10.java.js"></script>

    <title>Anmeldung</title>

</head>

<body onload="init();" style="width: 410px;" class="colorscheme9">

    <div style="width: 300px; background-color: #076399; margin: 10px;">
        <h2 style="padding-left: 16px; color: white;">Kundendaten</h2>
    </div>


    <div style="width: 300px; padding: 15px; border-radius: 12px; 
                  background: #f1f5fb; margin: 10px;">

        <label class="label" for="user">Benutzer</label><br>
        <input class="input" id="user" name="user"
            style="width: 160px;" type="text">

        <br />
        <label class="label" for="user">Kennwort</label><br>
        <input class="input" id="password" name="password"
            style="width: 160px;" type="password">

        <br />
        <button class="button" id="LogonButton"
            style="width: 160px; margin-top: 10px;"
            onclick="dologon(this);return false;">
            Anmelden
        </button>

    </div>

    <script>

        function dologon(f) {

            var logon_user = document.getElementById('user').value.trim();
            var logon_password = document.getElementById('password').value.trim();
            var logon_client = '100';
            var logon_language = 'de';

            var classname = "customer";
            var progname = "zzs10_customer";

            // Benutzername eingegeben?
            if (logon_user == '') {
                S10ErrorMessage(f, "Bitte den Benutzernamen eingeben");
                return;
            };

            // Kennwort eingegeben?
            if (logon_password == '') {
                S10ErrorMessage(f, "Bitte das Kennwort eingeben");
                return;
            };

            // S10 Anwendung starten
            S10Logon(logon_client, logon_user, logon_password,
                logon_language, classname, progname);
        };

    </script>

</body>

</html>


Erläuterungen:

 

3. Der "start"-Screen

Der mit s10nextscreen( 'start' ) in der ABAP-Methode "logon" gesetzte Screen ist als HTML-Datei der aktiven Klasse "customer" zugeordnet. Er wird in der bei der Anmeldung gesetzten Sprache gesucht, also z.B. "de" für Deutsch:

  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
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=400">
    <link rel='stylesheet' type='text/css' href='../../../style/s10.style.css'>
    <link rel='stylesheet' type='text/css' href='../../../style/custom.style.css'>
    <script src='../../synactiveS10/synactiveS10.java.js'></script>

    <title>Kundendaten</title>
</head>
<body style="width:100%; margin:0px; padding:0px;" onload='init();' class="colorscheme9">

    <div class="headerarea" style="width: 100%; padding:10px;">
        <b>Kundendaten</b>
         <br />
         <br />

         <button type="button" class="toolbarbutton" onclick="S10Apply('display');">
            Anzeigen
        </button>

        <button type="button" class="toolbarbutton"  onclick="S10Logoff();">
            Beenden
        </button>

    </div>


    <div style="padding:10px">
        <label class="label output" name="kunnr" for="kunnr"></label><br>
        <input type="text" class="input"  required name="kunnr" 
                      id="kunnr" style="width: 140px;">
    </div>

</body>
</html>


Erläuterungen:

 

4. Der "display"-Screen

Wenn der Benutzer den "Anzeigen" Button drückt, wird die ABAP-Methode "display" durch onclick=S10Apply( "display" ) aufgerufen und dort dann durch s10nextscreen( 'display' ) der Folgescreen "display" gesetzt. Er ist als HTML-Datei ebenfalls der aktiven Klasse "customer" zugeordnet:

Generell wird immer das ABAP-Objekt, das s10nextscreen() aufruft, das aktive ABAP-Objekt. In unserer kleinen Anwendung hier spielt das noch keine Rolle, da wir nur mit einem einzigen Objekt arbeiten; in komplexeren Anwendung kann es aber wichtig sein, bei der Navigation durch verschiedene Anwendungsteile das aktive ABAP-Objekt zu wechseln, zum Beispiel zur Anzeige eines Kundenauftrag svon "customer" zu "order" zu wechseln, indem man ein Objekt der Klasse "order" verwendet und in diesem dann s10nextscreen() aufruft.

Die HTML-Datei sieht wie folgt aus:

  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
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=400">
    <link rel='stylesheet' type='text/css' href='../../../style/s10.style.css'>
    <link rel='stylesheet' type='text/css' href='../../../style/custom.style.css'>
    <script src='../../synactiveS10/synactiveS10.java.js'></script>

    <title>Kundendaten</title>
</head>
<body style="width: 100%; margin: 0px; padding: 0px;" onload='init();' class="colorscheme9">

    <div class="headerarea" style="width: 100%; padding: 10px;">
        <b>Kundendaten</b>
        <br />
        <br />

        <button type="button" class="toolbarbutton" onclick="S10Logoff();">
            Beenden
        </button>

    </div>

    <div>

        <!-- Debitor -->
        <div class="infoblock">
            <label class='label output' name="kunnr"></label>
            <br />
            <span class='output' name='kunnr'></span>
        </div>


        <!-- Name -->
        <div class="infoblock">
            <label class='label output' name="name1"></label>
            <br />
            <span class='output' name='name1'></span>
        </div>

        <!-- Ort -->
        <div class="infoblock">
            <label class='label output' name="ort01"></label>
            <br />
            <span class='output' name='ort01'></span>
        </div>

        <!-- Postleitzahl -->
        <div class="infoblock">
            <label class='label output' name="pstlz"></label>
            <br />
            <span class='output' name='pstlz'></span>
        </div>

        <!-- Strasse -->
        <div class="infoblock">
            <label class='label output' name="stras"></label>
            <br />
            <span class='output' name='stras'></span>
        </div>

        <!-- Land -->
        <div class="infoblock">
            <label class='label output' name="land1"></label>
            <br />
            <span class='output' name='land1'></span>
            <span class='output' name='land1@text'></span>
        </div>


    </div>

</body>
</html>

Erläuterungen: