cObject
---cWebObject
------cWebBaseUIObject
---------cWebBaseDEOServer
------------cWebBaseControl
---------------cWebDynamicObjectContainer
cWebDynamicObjectContainer is a Container Class for dynamic web objects.
Currently, dynamic web objects cannot be data-aware.
Creating an instance of this object works just like instantiating any other type of object. The class functions like a cWebGroup and therefore supports basic container properties such as pbScroll and piColumnCount.
This sample shows an example of a cWebDynamicObjectContainer instance. Please note that the container itself should not contain any static child objects: these will be added at runtime.
Object oContainer is a cWebDynamicObjectContainer Set piColumnSpan to 12 Set piColumnCount to 12 End_Object
To define object-specific behavior for dynamic objects, you have to create a subclass of the object you wish to implement create dynamically. You then use this subclass to outline the specific behavior the dynamic object should have. Later, dynamic objects will be created according to this subclass definition and thus inherit the behavior. Inside the subclass you can also define new properties. All dynamic objects of that subclass will support the new properties.
This sample shows a subclass definition for a button with a single new property called piCounter. This is achieved by simply extending the existing cWebButton class.
Class cMyWebButton is a cWebButton Procedure Construct_Object Forward Send Construct_Object { WebProperty=Client } Property Integer piCounter 0 Set piColumnSpan to 8 End_Procedure End_Class
Once a dynamic container is set up and the dynamic objects have a definition, dynamic objects can be registered. This phase is called the creation phase. Simply use the CreateDynamicObject function defined in the cWebDynamicObjectContainer class, to register a dynamic object.
Get CreateDynamicObject of oContainer (RefClass(cMyWebButton)) "oMyWebButton" "" to hoObj
During the creation phase all dynamic objects you create will be added sequentially. That means that if you want object A to be displayed before object B (under the same parent), it should be created first.
By using dynamic properties, it is possible to create multiple dynamic objects based on the same subclass that each have a distinct properties. For regular DataFlex objects, properties are often defined inside the Construct_Object procedure or during the actual object creation. This is not possible for dynamic objects, due to their dynamic nature. Their property values might not be known at compile time. The Dynamic Object Library supports dynamic properties to solve this issue. Dynamic properties contain property values that are different from the default values set in the subclass definition. The procedure used to set a dynamic property value is InitDynamicProp, defined in the cWebObject class.
This sample demonstrates how to create two buttons based on the same subclass, but with different captions. Both buttons will be created from the class definition cMyWebButton we created earlier, but their properties will differ.
Get CreateDynamicObject of oContainer (RefClass(cWebGroup)) "oGroup1" "" to hoGroup1 Send InitDynamicProp of hoGroup1 "piColumnCount" 8 Get CreateDynamicObject of oContainer (RefClass(cMyWebButton)) "oButton1" "" to hoButton1 Send InitDynamicProp of hoButton1 "psCaption" "Button 1" Get CreateDynamicObject of oContainer (RefClass(cMyWebButton)) "oButton2" "" to hoButton2 Send InitDynamicProp of hoButton2 "psCaption" "Button 2"
The final step in the process of creating dynamic objects is rendering the objects. To do this, simply call Procedure Activate. This method will send the contents of the dynamic container to the client, which will, in turn, render all the objects.
Inserting a new dynamic object is fairly similar to registering one in the creation phase. First, the dynamic object needs to be registered and created. Then the dynamic properties should be set. At this point, the object is ready to be inserted. If it has child objects, these should also be created now. Please be aware that only a single dynamic object (and all its children) can be inserted at once. This means that in order to insert multiple dynamic objects that are not nested inside each other, InsertDynamicObject has to be called multiple times.
Get CreateDynamicObject of oContainer (RefClass(cWebGroup)) "oGroup2" "" to hoGroup2 Send InitDynamicProp of hoGroup "piColumnCount" 8 Get CreateDynamicObject of oContainer (RefClass(cWebForm)) "oForm" "oGroup2" to hoForm Send InitDynamicProp of hoForm "piColumnSpan" 8 Send InitDynamicProp of hoForm "psLabel" "Test Input" Send InsertDynamicObject of oContainer "oGroup2" "oGroup1"
There might be cases where you want to insert a newly created dynamic object at a very specific location, for instance as the fifth element in a list of other elements. For these cases, use InsertDynamicObjectAtIndex.
Keep in mind that this procedure is slightly more dangerous to use, because the framework assumes you know what you are doing. In most cases, usage of InsertDynamicObject should suffice.
PrependDynamicObject will always prepend a dynamic object to its parent's list of children.
Use AppendDynamicObject to append new dynamic objects at the end of its parent's list of children.
MoveDynamicObject requires the object that is being moved to already exist inside the container. Furthermore, the moved object inherits the parent structure of the object it is moved after.
This sample shows how to move the dynamic object "Group 1" after the object called "Group 2" (assume that "Group 1" is positioned before "Group 2" at the start).
Send MoveDynamicObject of oContainer "Group 1" "Group 2"
To allow for more complex operations, it is also possible to move a dynamic object to a specific index in its parent's list of children using MoveDynamicObjectToIndex. This is especially useful in cases where you manually keep track of locations of objects inside a certain list.
DestroyDynamicObject allows for destruction of a dynamic objects, which means completely removing it from the container. This includes removal of all its properties and children.
After having created and registered dynamic objects they can be used in your application. In a regular application, one would execute a method of an object by simply writing 'Send ProcedureName of hoObj'. In the case of dynamic objects, there must be one extra intermediate step. Dynamic objects are not always present in the memory of the web server due to process pooling. Therefore, the actual object (hoObj in this example) on which you want to call a procedure should be retrieved from the dynamic container first. You can do so using DynamicObject.
Getting and setting properties remains the same for dynamic objects. One can simply use WebGet and WebSet to get and set property values. The framework will handle synchronization between the server and the client.
This sample extends the subclass definition of cMyWebButton with an OnClick procedure that increments a synchronized property.
Class cMyWebButton is a cWebButton Procedure Construct_Object Forward Send Construct_Object { WebProperty=Client } Property Integer piCounter 0 Set piColumnSpan to 8 End_Procedure Procedure IncrementCounter Integer iCounter WebGet piCounter to iCounter Increment iCounter WebSet piCounter to iCounter End_Procedure Procedure OnClick Send IncrementCounter End_Procedure End_Class
Dynamic objects can be loaded anytime. Simply follow the steps laid out previously to load dynamic objects into your application. If you want your dynamic objects to show up as soon as a view is loaded, there are a few things you can do.
If you are using a drilldown theme style, define the creation of your dynamic objects inside Procedure OnBeforeShow, defined in the cWebView class. If you are using a regular theme style, you can simply define the creation of your dynamic objects inside Procedure OnLoad of any of your regular web objects.