Changing SAP data is more complex than reading it. The following should be noted:

As an example, we include the change of some fields of the customer address in our application. For this we first define a button within the display of the address, with which the user can switch to the change mode:

In the HTML file the button is defined as follows:

 <!-- Change address -->
 <img src="../../../icons/edit.png" 
    style="width:32px; margin:8px; float:right"  
    onclick="S10Apply('to_change');"/>

That is, we display a suitable png image, move it to the right side with "float:right" and execute the ABAP method "to_change" when clicking on it.

If the application is also intended to be a desktop application, we give the button a tooltip with the option title=, for example <img ... title="Change address" />:

In the ABAP method "to_change" we navigate to a new screen "change". Before that it is necessary

  1. To lock the object, i.e. to set an "enqueue" lock in SAP terminology
  2. to re-read the customer address

since it may be that another user has changed the address while we were on the display screen for a while. In change mode we must always display the actual data, otherwise when we "Save" we overwrite an intermediate change made by another user. So when transitioning to change mode, always lock first, then read again:

* to address change
  method to_change.

* enqueue KNA1
    enqueue( ).

* read data again
    s10databaseread( ).

* to adress change
    s10nextscreen( 'change').

  endmethod.

The SAP system contains generated function modules for locking objects; their names begin with "enqueue_". The easiest way to find out which enqueue module you need to call is to call the relevant SAP change transaction and then use SM12 to see which lock was created with your user name. A double click on the lock entry shows the technical properties and there the "Lock Object name":


In this case we see that the function module "ENQUEUE_EXKNA1" must be called to lock. In our ABAP method "enqueue" we issue a suitable error message if the object is currently locked. The user who has currently locked the object can be found in the system field "sy-msgv1" after calling the enqueue module.

* enqueue KNA1
  method enqueue.
    call function 'ENQUEUE_EXKNA1'
      exporting
        kunnr  = kunnr
      exceptions
        others = 1.

    if sy-subrc ne 0.

      s10errormessage(
         exporting
          text = |Customer is currently being processed by user | && sy-msgv1 ).

    endif.

  endmethod.

If the customer is not locked, s10nextscreen( "change" ) will call the change screen "change":

The address fields are now ready for input and marked as mandatory. The country is selectable via a dropdown field and the functions "Check", "Save" and "Back" are available. The HTML file for this:

  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
<!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>Customer information</title>
</head>
<body style="width: 100%; margin: 0px; padding: 0px;" onload='init();' class="colorscheme9">


    <div class="headerarea" style="width: 100%; padding: 10px;">
        <b>Address change customer
             <span class='output' type="text" name='kunnr'></span>
        </b>
        <br />
        <br />

        <button type="button" class="toolbarbutton" onclick="S10Apply('check');">
            Check
        </button>


        <button type="button" class="toolbarbutton" onclick="S10Apply('save');">
            Save
        </button>


         <button type="button" class="toolbarbutton" onclick="S10Apply('change_to_display');">
            Back
        </button>

    </div>


    <div style="max-width: 800px">

        <!-- Name 1 -->
        <div class="infoblock2" style="height: 50px">
            <label class='label output' name="name1" for='name1'></label>
            <br />
            <input type="text" class="input" required name="name1" id="name1"  style="width: 300px;">
        </div>

        <br />

        <!-- Street -->
        <div class="infoblock2" style="height: 50px">
            <label class='label output' name="stras" for='stras'></label>
            <br />
            <input type="text" class="input" required  name="stras" id="stras"  style="width: 300px;">
        </div>

        <br />

        <!-- Postal code -->
        <div class="infoblock" style="width: 100px; height: 50px;">
            <label class='label output' name="pstlz" for='pstlz'></label>
            <br />
            <input type="text" class="input" required  name="pstlz" id="pstlz" style="width: 80px;">
        </div>

        <!-- City -->
        <div class="infoblock2" style="height: 50px">
            <label class='label output' name="ort01" for='ort01'></label>
            <br />
            <input type="text" class="input" required  name="ort01" id="ort01" style="width: 300px;">
        </div>


        <!-- Country -->
        <div class="infoblock2" style="height: 50px;">
            <label class='label output' name='land1' for='land1'></label>
            <br />
            <select size="1" name='land1' data-s10dropdownlist='land1@dropdownlist' 
                id='land1' class='inputselect'  required style='width: 240px;'>
            </select>
        </div>


    </div>

</body>
</html>
 

Some notes:

We implement "Check" and "Save" via the ABAP technique "Call transaction using...", which we use to execute the SAP transaction in the background, which then also performs all SAP checks.

 For the user it then looks like this, for example:: 

For "Check", we just execute "Enter" instead of "Save" at the end; this way we get the original SAP error messages. To build the batch input session for XD02 we can use the "Recording Mode" in transaction SHDB:

We then convert the recording into ABAP coding by building a batch input session from the current input data:

  method save.
    check_or_save( save = 'X' ).
  endmethod.

  method check.
    check_or_save( save = 'N' ).

    s10infomessage( 'Input data checked' ).
  endmethod.


  method check_or_save.

* bdc data
    data:
      bdcdatawa type bdcdata,
      bdcdata   type table of bdcdata.

* message table for call transaction
    data:
      messtabwa type bdcmsgcoll,
      messtab   type table of bdcmsgcoll.

* create bdc data

* screen 101
    clear bdcdatawa.
    bdcdatawa-program  = 'SAPMF02D'.
    bdcdatawa-dynpro   =  '0101'.
    bdcdatawa-dynbegin = 'X'.
    append bdcdatawa to bdcdata.

    clear bdcdatawa.
    bdcdatawa-fnam = 'RF02D-KUNNR'.
    bdcdatawa-fval = s10getuservalue( 'KUNNR' ).
    append bdcdatawa to bdcdata.

    clear bdcdatawa.
    bdcdatawa-fnam = 'RF02D-D0110'.
    bdcdatawa-fval = 'X'.
    append bdcdatawa to bdcdata.

    clear bdcdatawa.
    bdcdatawa-fnam = 'BDC_OKCODE'.
    bdcdatawa-fval = '/0'.
    append bdcdatawa to bdcdata.

* screen 110
    clear bdcdatawa.
    bdcdatawa-program  = 'SAPMF02D'.
    bdcdatawa-dynpro   =  '0110'.
    bdcdatawa-dynbegin = 'X'.
    append bdcdatawa to bdcdata.

    clear bdcdatawa.
    bdcdatawa-fnam = 'KNA1-NAME1'.
    bdcdatawa-fval = s10getuservalue( 'NAME1' ).
    append bdcdatawa to bdcdata.

    clear bdcdatawa.
    bdcdatawa-fnam = 'KNA1-ORT01'.
    bdcdatawa-fval = s10getuservalue( 'ORT01' ).
    append bdcdatawa to bdcdata.

    clear bdcdatawa.
    bdcdatawa-fnam = 'KNA1-STRAS'.
    bdcdatawa-fval = s10getuservalue( 'STRAS' ).
    append bdcdatawa to bdcdata.

    clear bdcdatawa.
    bdcdatawa-fnam = 'KNA1-PSTLZ'.
    bdcdatawa-fval = s10getuservalue( 'PSTLZ' ).
    append bdcdatawa to bdcdata.

    clear bdcdatawa.
    bdcdatawa-fnam = 'KNA1-LAND1'.
    bdcdatawa-fval = s10getuservalue( 'LAND1' ).
    append bdcdatawa to bdcdata.

    clear bdcdatawa.
    bdcdatawa-fnam = 'BDC_OKCODE'.

    if save = 'X'.
      bdcdatawa-fval = '=UPDA'.
    else.
      bdcdatawa-fval = '/0'.
    endif.
    append bdcdatawa to bdcdata.


* dequeue, otherwise account is locked
    dequeue( ).

    call transaction 'XD02' with authority-check
        using bdcdata
        mode 'N'
        update 'S'
        messages into messtab.

* enqueue again
    enqueue( ).

    data: messagetext type string.
    loop at messtab into messtabwa.

* get message text
      message
        id messtabwa-msgid  type messtabwa-msgtyp number messtabwa-msgnr
        with messtabwa-msgv1 messtabwa-msgv2 messtabwa-msgv3 messtabwa-msgv4
        into messagetext.

      case messtabwa-msgtyp.
        when 'E' or 'A'.

* set focus for known input fields
          case messtabwa-fldname.
            when 'KNA1-LAND1'.  s10setfocus( 'LAND1' ).
            when 'KNA1-PSTLZ'.  s10setfocus( 'PSTLZ' ).
          endcase.

          s10errormessage(  messagetext ).

        when others.

* final message after "save"
          if save = 'X'.
            s10infomessage(  messagetext ).
          endif.

      endcase.

    endloop.
  endmethod.
 

Please note:

The implementation of the function "Back from change mode" is simple in principle: we unlock the object and set the next screen "display". At this point, however, be sure to re-read the data so that in the event of incorrect entries and then "Back", all fields are at the currently saved status.

 method change_to_display.

* dequeue KNA1
    dequeue( ).

* read data again
    s10databaseread( ).

* next screen: display
    s10nextscreen( 'display').

  endmethod.