Infrastructure Perspective: The Controls
Typically each control is associated to one of the fields of the database query underlying the page. For eg. in the people page, one control is associated to the login ID of the person, one to the full name of the person (which is a concatenation of three fields on the table underlying the query) and so on.
Almost any where you can have a control, you can have a plain string. One should think of a plain string as a control which in DISP shape outputs itself and in FORM shapes does not output anything. To get the opposite effect use a CommentControl.
Some examples of normal controls include:
- CommentControl: displays nothing when in DISP shape and a string (which is given as part of the constructor) in FORM shape.
- TextFieldControl: displays the value of a field in DISP shape and generates a TextBox where you can edit the value of the field in FORM mode.
- TextAreaControl: is just like TextFieldControl, except that the data can be larger and hence it displays it in a TextArea as opposed to a TextBox.
- NoEditControl: displays the value of a field in both DISP and FORM shape. This is useful to display data which should not be modified. eg. when one is editing the information about a course, one should not be allowed to change the course number.
- SingleLinkControl: creates a clickable link in DISP shape, where the URL as well as the LinkText can be generated by other controls. If they are plain-strings then these string are percent-substituted
- EmailControl: in FORM shape allows one to edit an email address, and in DISP shape displays a clickable email address.
- StaticStringControl: Used to display a fixed string, which may include HTML. For more info see StaticStrings
For more of these see utils/controls/singlecontrols and utils/controls/multiplecontrols.
Instead of having controls which output a textfield if some condition is true, and another control which outputs a textarea if some condition is true... one abstracts it one level. These conditional controls typically take other controls (called sub-controls) as parameters (as part of the constructor) and activate the sub-controls when the condition is satisfied. So a conditional control, when asked to generate the output, evaluates the condition and if the condition evaluated to true, asks the sub-controls to generate their output and gives that as its output.
Some examples include:
- IfModeControl: takes two sets of sub-controls, and a set of modes as inputs. If the current mode belongs to the given set of modes, it activates one set of sub-controls, and otherwise activates the other set.
- IfFieldControl: activates one set of controls if some particular field value (given in the constructor) evaluated by the query underlying the page is non-empty, otherwise activates the other set.
- IfThenElseControl: the grand daddy of all conditional controls. Defines two methods condition_disp and condition_form (which has to be over ridden by any descendant) and activates one of four possible sets of controls depending on the current shape and whether the corresponding condition evaluated to reu or not.
The simplest example of a container control is a CoalesceControl whose output is simply the concatenation of the outputs of all its subcontrols. This is very useful and helps one masquerade several controls as one.
Another example of a container control is the TableContainerControl, which outputs an entire table. It has as subcontrols RowContainerControls which output rows of a table. So the output of a TableContainerControl is just a pair of <TABLE> ... </TABLE> where ... is the output of all the RowContainerControls. Well almost since it is the TableContainerControl which is incharge of outputting the table header and the table attributes. In our implementation of a TableContainerControl, it even messes with the RowContainerControls it contains.
For more example of container controls, see utils/controls/containercontrols.