/program/lib/dialoglib.php - useful functions for manipulating dialogs
This file provides various utility routines for creating and validating user dialogs.
A dialog is a collection of input elements grouped together in a form. An input element (or field) has at least a type (e.g. F_ALPHANUMERIC or F_DATETIME) and a name (e.g. 'title' or 'expiry') and optionally one or more of the other possible properties. The name of an input element uniquely identifies the field in the dialog; it can be used to retrieve the data entered by the user from the global $_POST array.
Note that it is also possible to choose a field name ending in '[]'. This eventually yields an array within the $_POST array. This is used in the multiple file upload feature.
A dialog can be defined via a 0-based or associative array, where every array element is separate input element. Each of the input elements is in itself an associative array with property-value-pairs. The recognition of a property depends on the type, e.g. the number of decimals is irrelevant for a string-type input element.
Here is an overview of properties and field types to which they apply. An 'x' means required, an 'o' means optional and a '-' means don't care.
type | name | | value | | | rows | | | | columns | | | | | minlength | | | | | | maxlength | | | | | | | decimals | | | | | | | | minvalue | | | | | | | | | maxvalue | | | | | | | | | | options | | | | | | | | | | | label | | | | | | | | | | | | accesskey | | | | | | | | | | | | | alt | | | | | | | | | | | | | | class | | | | | | | | | | | | | | | multiple | | | | | | | | | | | | | | | | viewonly | | | | | | | | | | | | | | | | | tabindex | | | | | | | | | | | | | | | | | | title | | | | | | | | | | | | | | | | | | | hidden | | | | | | | | | | | | | | | | | | | | autocomplete [1] | | | | | | | | | | | | | | | | | | | | | id | | | | | | | | | | | | | | | | | | | | | | F_ALPHANUMERIC x x o o o o o - - - - o o o o - o o o o o o F_INTEGER x x o - o o o - o o - o o o o - o o o o o o F_REAL x x o - o o o o o o - o o o o - o o o o o o F_DATE x x o - o o o - o o - o o o o - o o o o o o F_TIME x x o - o o o - o o - o o o o - o o o o o o F_DATETIME x x o - o o o - o o - o o o o - o o o o o o F_PASSWORD x x o - o o o - - - - o o o o - o o o o o o F_CHECKBOX x x o - - - - - - - x o o o o - o o o o - o F_LISTBOX x x o o - - - - - - x o o o o - o o o o - o F_RADIO x x o - - - - - - - x o o o o - o o o o - o F_FILE x x o - o - - - - - - o o o o o o o o - - o F_SUBMIT x x x - - - - - - - - - o o o - o o o - - o F_RICHTEXT x x o o o o o - - - - o o o o - o o o o - o F_CSRFTOKEN x x x - - - - - - - - - - - - - - - - x - -
There are two more properties: 'errors' and 'error_messages'. These properties can be set whenever the validation of the input yields an error. If all is well, 'errors' is either not set or equal to 0.
[1] Note that autocomplete is a non-standard function that doesn't work in every browser.
Here is a description of the various properties.
return the ASCII-character that follows the first tilde in a string
this returns the ASCII-character that follows the first tilde in the string (if any). This is the character that could be added as an accesskey to some HTML tag, e.g. a label or an input. The character is converted to upper case.
Note that a tilde followed by a UTF-8 sequence of 2 or more bytes does NOT yield a hotkey at all but an empty string instead.
replace tilde+character with emphasised character to indicate accesskey
this replaces the combination of a tilde and the character following it with $tag_open followed by the character followed by $tag_close.
Example: accesskey_tilde_to_underline("~Username") yields "<u>U</u>sername" accesskey_tilde_to_underline("Pass~word",'','') yields "Password" accesskey_tilde_to_underline("~Role",'','') yields "Role"
Note that we only accept ASCII here: if a tilde is followed by a non-ASCII-character (e.g. the first byte of a multibyte UTF-8 sequence) we silently ignore and still 'eat' the tilde.
shortcut for generating a dialogdef for a button
this constructs an array describing a button. The button definition is bare bones but it includes name, class, value and optionally a title. If no $value is specified, a translated value is retrieved for the button. If no $title is specified, a title indicating the hotkey is constructed. This more or less works around the problem that hotkeys cannot be visualised in an input type="submit" button (It is possible in a button tag, but we don't use that because it requires HTML 4. Maybe later...)
If $button_type is not one of the defined values BUTTON_* the variable itself is used as name, class and as a key for the translation of value unless a $value is specified.
Typical use:
$dialogdef = array(...,'button_ok' => dialog_buttondef(BUTTON_OK));
Another example defining a non-standard button:
$button = dialog_buttondef('button_foo','~Foo','Do not press this button!');
shortcut for generating a dialogdef for a csrftoken
this constructs an array describing the csrftoken. Basically we are constructing a hidden field already filled with data from the current session (see get_csrftoken()). Since get_csrftoken() already fills in the 'name' and 'value', we only have to add the 'type' and set the field to 'hidden'.
construct a space-delimited list of classes that apply to this item
this constructs a string with applicable classes for this element. if the item has validation errors, the class ATTR_CLASS_ERROR is added, if the item is viewonly, the class ATTR_CLASS_VIEWONLY is added. This allows for the CSS to change the style depending on these situations.
construct a label for a dialog input element
this constructs the label for an input. It is built inside a label-tag, possibly with these attributes: id, for, accesskey, class, title. The class is a special case: if there were errors the class 'ATTR_CLASS_ERROR' is added to the class attribute, in case of viewonly the class ATTR_CLASS_VIEWONLY' is added too. (Note that the latter shouldn't happen: how can a viewonly field yield any errors at all unless someone is trying to crack the program?)
Because some browsers require that the label of a listbox is linked to the select tag (done via 'id' and 'for'), we MUST have some 'id' for that particular tag. If it is not there, we generate one and add it automagically.
construct an actual HTML input widget for dialog input element
this constructs the actual HTML-code for a dialog input element. If the input element is 'hidden', we generate a minimalistic hidden field with no labels, accesskeys or whatever: basically just a name-value-pair to communicate to a subsequent form. Note that we force a field of type F_CSRFTOKEN to be hidden too, even if it isn't set to be hidden.
If the item is genuine (it has a name and a type), we construct the input using a workhorse routine.
construct an input field for file upload
this constructs an input widget for uploading files. This usually includes a button to browse the user's local file system (depends on browser).
Note that it is NOT possible to 'preload' a value in this input field; any predefined value is ignored by the browser. As a workaround we _could_ show the $value to the user using an additional comment, e.g. by adding it to the label or something. For now, we simply do nothing with the value.
The properties recognised translate to the following HTML-code/attributes
name : name value : value (see note above) accesskey : accesskey columns : cols (textarea) or size (input type="text") alt : alt class : class (also depends on viewonly and errors) tabindex : tabindex id : id title : title multiple : multiple viewonly : disabled AND addition of ATTR_CLASS_ERROR to class list (if viewonly == TRUE) errors : addition of ATTR_CLASS_ERROR to class list (if errors > 0)
construct a listbox
this constructs a listbox
The number of lines in the result depends on the number of items in the options array in $item. The result always starts with a SELECT opening tag, followed by N OPTION tags and finally a SELECT closing tag.
There are two different ways to specify the options. The simple way is to have a single options array with 'value' => 'option text' pairs. In this case the available properties such as title, class and viewonly are copied from the corresonding generic properties in the $item array,
The other way is to have an array of arrays like this:
This allows for setting properties of individual options, e.g. one of the options could be made viewonly while the others are still selectable.
The properties recognised translate to the following HTML-code/attributes
name : name value : value AND perhaps 'selected' if value matches option value accesskey : accesskey alt : alt class : class (also depends on viewonly and errors) tabindex : tabindex id : id title : title viewonly : disabled AND addition of ATTR_CLASS_ERROR to class list (if viewonly == TRUE) errors : addition of ATTR_CLASS_ERROR to class list (if errors > 0) label : tilde+letter may change the accesskey
Note that the options within the SELECT tag are indented 2 spaces for readability.
construct a checkbox or 1 or more radiobuttons
this constructs a checkbox or a list of radiobuttons.
Note: because a checkbox and radionbuttons are very similar, they are handled in the same workhorse routine. Maybe we should split this in the name of code clarity. Oh well...
If we are generating a checkbox, the result looks something like this:
<input type="checkbox" value="1" checked ...><label ...>option text<label>
If we are generating radiobuttons, the result looks something like this:
<input type="radio" value="1" checked ...><label ...>option 1 text<label> <input type="radio" value="2" ...><label ...>option 2 text<label> <input type="radio" value="3" ...><label ...>option 3 text<label>
The number of lines in the result depends on the number of items in the options array in $item. In case of a checkbox there should only be one, in case of radiobuttons there should be more than 1.
There are two different ways to specify the options. The simple way is to have a single options array with 'value' => 'option text' pairs. In this case the available properties such as title, class and viewonly are copied from the corresonding properties in the $item array,
The other way is to have an array of arrays like this:
This allows for setting properties of individual options, e.g. one of the radio buttons could be made viewonly while the others are still selectable.
Note that such a non-simple array of arrays doesn't make much sense for a single, simple checkbox.
The properties recognised translate to the following HTML-code/attributes
name : name value : value AND perhaps 'checked' if value matches option value accesskey : accesskey alt : alt class : class (also depends on viewonly and errors) tabindex : tabindex id : id title : title viewonly : disabled AND addition of ATTR_CLASS_ERROR to class list (if viewonly == TRUE) errors : addition of ATTR_CLASS_ERROR to class list (if errors > 0) label : tilde+letter may change the accesskey
Note: In case of radiobuttons, the document-wide unique id is constructed from the specified id by appending an underscore and an indexnumber (except for the first item in te list). This id can be overruled by an id specified in the options array-of-arrays.
Even when an item has an explicit accesskey, the access key can be overruled by the the 'hotkey' derived from a tilde+letter combination in the options array, either in the simple case or in case of and array-of-arrays.
Note that also the generic title can be overruled by a title that is defined in the options array-of-arrays.
construct an input field using the user's preferred editor
this constructs an input for rich text like a page with HTML-code. Most users will probably have selected the CKeditor. However, there is also the option to use the so-called 'plain' editor, which is nothing more than a textarea in disguise.
The properties recognised translate to the following HTML-code/attributes
name : name value : value accesskey : accesskey rows : rows columns : cols maxlength : maxlength alt : alt class : class (also depends on viewonly and errors) tabindex : tabindex id : id title : title viewonly : disabled AND addition of ATTR_CLASS_ERROR to class list (if viewonly == TRUE) errors : addition of ATTR_CLASS_ERROR to class list (if errors > 0)
For maximum compatibility we not only retain FCKEditor 2.6.5 (2359) but also CKEditor 3.6.6.2 (7696) next to CKEditor 4.4.5 (25cdcad). The actual editor to use depends on the system wide choice and user preference. For compatibility the latest editor is configured to be 'ckeditor' whereas the older version 3 is now selected with 'ckeditor3'. This means that existing 'ckeditor'-users will be moved to CKEditor4 whereas 'plain' and 'fckeditor' users will see no change. (November 2014).
construct a submit button
this constructs a submit button. For compatibiliy we use a simple input of type submit because the button widget is only available since HTML 4. We may change that in the future, and force everyone to use at least HTML 4. For now it is as it is.
Note that the label of the button is retrieved from $value rather than from the label property. We do use the $value as a string possibly containing hotkeys (via prepending a letter with a tilde) and we also set the accesskey to that value. However, it is different from other widgets because an input cannot display underlines (a button can).
The properties recognised translate to the following HTML-code/attributes
name : name value : value accesskey : accesskey alt : alt class : class (also depends on viewonly and errors) tabindex : tabindex id : id title : title viewonly : disabled AND addition of ATTR_CLASS_ERROR to class list (if viewonly == TRUE) errors : addition of ATTR_CLASS_ERROR to class list (if errors > 0)
construct an input field, usually for text input OR a textarea for multiline input
this constructs most variations on text fields, including password fields Many of the defined field types (the F_* constants) can be handled via a simple input of type text. The semantics of the field (eg. is it an integer, a real) have no impact on the HTML-input: at that level it is still plain text. However, for a password we use the password type in order to make the value display as asterisks. If the number of rows is more than 1, the input element becomes a text area. Note that is generally only applies to F_ALPHANUMERIC but that is not enforced here (you can make a multiline F_DATE, even though it doesn't make much sense).
The properties recognised translate to the following HTML-code/attributes
name : name value : value accesskey : accesskey rows : rows (textarea only) columns : cols (textarea) or size (input type="text") maxlength : maxlength alt : alt class : class (also depends on viewonly and errors) tabindex : tabindex id : id title : title autocomplete : autocomplete [1] viewonly : disabled AND addition of ATTR_CLASS_ERROR to class list (if viewonly == TRUE) errors : addition of ATTR_CLASS_ERROR to class list (if errors > 0)
[1] Note that autocomplete is a non-standard function that doesn't work in every browser.
construct a generic form with a dialog
this constructs an HTML form with a simple dialog where
validate and check values that were submitted via a user dialog
this steps through the definition of a dialog and retrieves the values submitted by the user via $_POST[]. The values are checked against the constraints (e.g. minimum string length, date range, etc.). If the submitted value is considered valid, it is stored in the corresponding value of the dialogdef element, maybe properly reformatted (in case of dates/times/datetimes). If there were errors, these are recorded in the dialog definition element, in the form of one or more readable error messages. Also the error count (per element) is incremented. This makes it easy to
Update 2009-03-17: We no longer validate the view-only fields because these fields are not POST'ed by the browser and hence cannot be validated. This also means that there is no value set from $_POST for those fields.
Update 2011-09-29: added UTF-8 validation, replace with U+FFFD (Unicode replacement character) on fail
check validity of date, time or datetime
this checks the validity of dates and times. If all tests are passed successfully, the input value is reformatted in the standard format corresponding with that field type:
Valid values for times are between 00:00:00 and 23:59:59. Note that we don't deal with leap seconds or other fancy stuff (this is not rocket science): KISS. Usually we only need times to determine an embargo date/time anyway.
Also, this routine doesn't know about time zones and daylight savings time.
Documentation generated on Tue, 28 Jun 2016 19:09:10 +0200 by phpDocumentor 1.4.0