ADM2 SDO Readonly switch

Posted by Ham on 08-Nov-2014 03:38

I’ve got a question about ADM2 and SDO.


I’m trying to implement a switch to set the SDO Readonly based on external criteria.

E.g. a person related to a specific plant may update the plant’s information. The same person can *see* the data from other plants but may not update them.

The idea I’ve got in mind is a property in the SDO to set / get Readonly of the SDO.

When a person selects “his” plant, update is enabled and the SDO’s Readonly property is set to FALSE.

When a different plant is selected, the SDO’s Readonly property is set to TRUE and NO UPDATES ARE ALLOWED OR ENABLED.


What’s the best way to implement this?


I was thinking of:

  1. Add a new property to every SDO: Readonly
  2. Functions to set/get the property should either
    1. Make all fields readonly
    2. Remove update link

Question is how to relink SDO with the other objects.

 Anyone can help on this?

All Replies

Posted by Håvard Danielsen on 10-Nov-2014 12:17


This can be be managed by removing and adding the Update link combined with some code to ensure that the visual object that is the UpdateSource is enabled or disabled accordingly by calling enableFields and disableFields("All"). The visual object will remain in the disabled state as long as the update link is missing.  

There are two problem with this approach,  first, the link cannot be removed before the visual object is initialized and second, you need to keep track of at least one of the objects in the link, since the info is lost when the update link is removed.  You still have a data link, but the SDO can have many data targets, but only one of them can be the update source, so you cannot guess which is the supposed update source.

These are all resolvable issues, but I tried a different approach that seems to work without additional properties.  

1. Added getReadOnly to the SDO. This can check current record so that the read-only setting can change per record  Simple example from sports2000 Salesrep:

function getReadOnly returns logical 
  (  ):     
   define variable cRegion as character   no-undo.
   cRegion = {fnarg columnValue 'region'}.
   return cRegion = "central" or cregion = "southern" .
end function.

2. Override CanUpdate in the visual object to return false if read-only to allow the toolbar to reflect the read-only state

function canUpdate returns logical  (   ):
  define variable updateTarget as handle no-undo.
  if super( ) then
      {get UpdateTarget updateTarget}.
      return not {fn getReadOnly updateTarget}.
  return false.
end function.

3. Override displayRecord to enable or disable the UI based on the SDO's read-only  (or canUpdate)

procedure displayRecord:
   define variable updateTarget as handle no-undo.   
   {get UpdateTarget updateTarget}.
    /* skip if no target  */
   if valid-handle(updateTarget) then
       if {fn getReadOnly updateTarget} then
           run disableFields in target-procedure("All").
           run enableFields in target-procedure.
   run super.
end procedure.

4. Override UpdateMode to disable the automatic enabling (when TableIOSource Save is true):

procedure updateMode:
  define input parameter pcMode as character no-undo.
  if pcMode = "Modify" then
      if not {fn canUpdate} then
  run super(pcMode).

end procedure.

5. Optional: Override initializeObject to change the toolbar ADD action to be enabled also when read-only. This is done by removing CanUpdate() from the rules. One should probably add a CanAdd() for full control.

procedure initializeObject:
  define variable tableiotarget as handle no-undo.
  run super.
  {get TableIOSource tableiotarget}.
  dynamic-function ("defineAction" in tableiotarget,"ADD","EnableRule,Order",
                "RecordState=RecordAvailable,NoRecordAvailable and Editable and DataModified=no and canNavigate() ":U
                + chr(1)  
                + "1").

end procedure.


Posted by Håvard Danielsen on 10-Nov-2014 12:42


All the overrides (2 - 5) would be in the visual object. The examples call everything in target-procedure in order to work if implemented in a super procedure like dataviscustom.p. If this is added to a common/general super procedure getReadOnly would also need to be added to all SDOs.  

This should in theory also work for an updateable browser, but I did not test this.  

This thread is closed