Altering User Interface Composition at Runtime
In FoxInCloud desktop and web applications, developer can easily adapt the visual display to the context at runtime by either hiding/showing, enabling/disabling, or adding/removing objects.
FoxInCloud supports all these scenarios, with some nuances explained below.
Hide/show, enable/disable objects at run time
Hiding/showing and enabling/disabling objects at runtime only requires that the visible
and/or enabled
property is part of the list in the .wcPropSave
property of the corresponding object(s).
This can be done either at design time, at any class level or in the object itself, or at runtime, in the class or object .Init()
method, with the help of the awPublic.prg!wcPropSaveEdit()
function:
Note that you can add some properties to .wcPropSave
at some class level, and remove them (for optimization), at a lower level of the class and/or object hierarchy if the property always keeps the same value at runtime:
This principle applies to other properties altering object’s aspect such as .Font*
, .Fore*
, .Back*
, .Disabled*
, .Border*
, etc.
Adding/removing objects at runtime
FoxInCloud supports adding/removing objects at runtime with a behavior slightly different in desktop mode and web mode.
Adding/removing objects at .Init()
If you .addObject()
and/or .removeObject()
in any .Init()
method, these objects will or won’t appear in the rendered HTML.
As an alternative to .removeObject()
, you can simply return .F.
or return .T.
in the target object.Init()
depending on the situation; eg remove an object in desktop mode while keeping it in web mode:
Please note that any member you add or remove when form.wlInitFirst
or by return .F.
in members.Init()
will be shared by ALL users; eg. you can’t use a user-related function (such as a role/security function) to determine whether a control should appear or not at runtime.
The form.Init() case
Note that in web mode, form.Init()
has a slightly different behavior from the other base classes.
form.Init()
executes:
- at first time a form is used: FoxInCloud Server instantiates the form and keeps a reference to it for later re-use by other users; in this case,
form.Init()
executes without parameter and should always return .T. - each time a user needs a form, FoxInCloud Server executes
form.Init()
with whatever parameter and context (egparenForm.dataSessionID
when using.dataSession=1 && Default data session
) for this specific user case. In some sense,form.Init()
should more be viewed as a user event than a ‘static’ event.
You can determine whether form.Init()
execution is ‘blank’ or ‘user-based’ by testing thisForm.wlInitFirst
:
Adding/removing objects during a user event
note: in what follows, 'container' means any VFP class that can contain other objects such as form, container, page, etc.
Whenever you need to add or remove objects during a user event, based on some dynamic condition such as the user profile or any other contextual condition, you can take advantage of .wlContentDynamic
:
- set
.wlContentDynamic = .T.
either at design time or incontainer.Init()
- for a container with
.wlContentDynamic = .T.
, calling.addObject()
or.removeObject()
automatically orders FoxInCloud Application Server to re-generate the HTML and JS of this container’s contents, and refresh browser display accordingly:
Be aware that this process implies some overhead:
addObject()
andremoveObject()
per se- re-generating the HTML
note: if your container implements .addObject() and/or .removeObject() methods, make sure to call dodefault() after your code
Scope of .wlContentDynamic
support
.wlContentDynamic
are mainly designed for containers populated with static objects with a limited user interaction (eg segments in a Gantt Chart, list of users, etc.).
If you do need user interaction on such dynamically added objects, make sure to implement a JavaScript handler executing a method of some form member that is permanent – in other words, that all users share –, eg the dynamic container:
note: the FoxInCloud base classes (aw.vcx) implementation of .addObject() and .removeObject() makes sure the object exists or not before attempting to add or remove it; this avoids useless errors in web mode.
tags: code optimization user experience
Watch FoxInCloud Marketing Videos :: Watch FoxInCloud Technical Videos :: Stay tuned on FoxInCloud Roadmap :: Learn how to use FoxInCloud :: Download FoxInCloud Adaptation Assistant for free :: Download FoxInCloud Web Application Studio for free