How to refresh SDF combo list

Posted by bkroghru on 22-Nov-2006 14:02

Hi everybody,

I am looking for a way to refresh SDF combos and its list-item-pairs property. I have tried to get the cache to update itself (even cleared it) and to trigger some sort of rebuild of the specific combo list. I post this question because I would like to be able to do this refreshing without having to specify parent fields etc. for the combo and thus using standard behavior. Is there for instance one single procedure/function to refresh the data?

All Replies

Posted by Håvard Danielsen on 29-Nov-2006 08:08

If you clear the cache then the combo will actually be refreshed on the next request, but there is not going to be another request unless the query has changed, which typically only is the case when a parent value is changed.

Some background:

There are 3 steps required in fetching data for dyncombos;

Each step has to be performed in all combos, before the next step is executed, so the SDF subscribes to prepareField and displayField of the Viewer, allowing the Viewer to reach all of them with a publish.

(Note that this describes the "NEW Lookup API".)

procedure displayFields:

  ...

  Run retrieveFieldData in target-procedure.

  ...

  Publish “displayField” from target-procedure.

end.

procedure retrieveFieldData:

  publish “prepareField” from target-procedure.

  run retrieveData in SDFCacheManager

end.

There is currently no direct way to ask the combo to refresh data unconditionally, but there is a 'refresh' field in the internal temp-table. You could add your own method to the combo class as follows (This example does not have an input parameter as there really is no need to set it to NO and is a procedure for publish from viewer):

procedure makeFieldQueryRefreshable:

  define variable hCombo as handle no-undo.

  hCombo = DYNAMIC-FUNCT('returnComboBuffer' in target-procedure).

  hCombo::lRefreshQuery = YES.

end.

Add this new "event" to the combo’s ContainerSourceEvents property (Repository or combocustom.i) and you can implement a refreshFieldData in the Viewer as follows:

procedure refreshFieldData:

  def var hCF as handle no-undo.

  publish “makeFieldQueryRefreshable” from target-procedure .

  hCF = dynamic-func("getManagerHandle":U in target-procedure,"SDFCacheManager":U).

  run retrieveData in hCF.

  publish “displayField” from target-procedure.

end.

There is currently no way to clear the cache for only one combo, but you can use the existing setUseCache to tell it to ignore the current cache, but the cache would remain stale.

Disclaimer: This is based on code inspection and has not been tested, so let me know if I'm overlooking something...

Posted by bkroghru on 11-Dec-2006 10:29

Thanks for the reply Haavard.

The problem with displayField is that it resets all the other combo-boxes in the viewer. So if there are other combos in the viewer they reset to the initial value (record value). I guess I can save the screen values of those combos and apply the (screen) values after the displayField has been done? Or is there perhaps a better way?

Message was edited by:

bkroghru

Posted by Håvard Danielsen on 14-Dec-2006 15:02

Yes, displayField is in effect showing the data from the viewer's datasource. The combo has a buildCombo function that possibly could be used instead, but there would be some work to make the viewer call it in all combos. (wrap in a procedure, that is subscribed and published from the viewer)

This is probably overkill if you really only want to refresh a single combo. You could implement a reopen method in the combo based on the method explained above, that sets the combo refreshable. This is still assuming the cache has been cleared. You could actually set UseCache to False in the combo also in this method to bypass the cache, but the cache would remain stale.

procedure reopenCombo:

  def var hCf as handle no-undo.

  run makeFieldQueryRefreshable in target-procedure.

  hCF = dynamic-func("getManagerHandle":U in target procedure,"SDFCacheManager":U).

  run retrieveData in hCF.

  .

   /* Run displayField in target-procedure. */

End.

I would probaby use buildCombo instead of displayField inside of the combo, since it allows you turn redisplay on or off.

There’s many alternatives to this, but they would all be based on the 3 steps. –

- prepare (in our case set refresh flag true directly)

- call the manager

- refresh visualization

The reason they are separate steps is that you need to be able to prepare many before the retrieval and show many after the retrieval. It is possible to have dedicated method that takes a list of combos also. (See notifyFields in adm2/lookupfield.p. -- It is hard to override notifyFields since it is using temp-tables, but returnCombobuffer allows you to retrieve it and write dynamic code)

You should perhaps question whether caching is necessary/correct if the cache has a risk of becoming stale...

Posted by bkroghru on 23-Jan-2007 01:49

Thanks for the useful input.

I actually based my solution on the first suggestion - running displayField.

I also find the returnComboBuffer function to be quite useful, as it provides a direct access to the settings of the combo. There is a similar function for lookups, returnLookupBuffer, that can be used to manipulate the lookup SDF.

This thread is closed