|
|
Every field is created with the current default field type. The initial ETI default field type is a no_validation field. Any data may occupy it. (This default can be changed as described below.) To change a field's type from the default, ETI provides the following functions for manipulating a field's (data) type.
SYNOPSIS
int set_field_type (field, type, [arg_1, arg_2, ...]) FIELD field; FIELDTYPE type;The function set_field_type takes a FIELDTYPE pointer and a variable number of arguments depending on the field type. The field type ensures that the field is validated as your end-user enters characters into the field or attempts to leave it.FIELDTYPE field_type (field) FIELD field;
char field_arg (field) FIELD field;
The form driver (described in ``Form driver processing'') validates the data in a field only when data is entered by your end-user. Validation does not occur when
If successful, set_field_type returns E_OK. If not, it returns the following:
If the function set_field_type is not applied to a field, the field type is the current default.
You can change the ETI default by giving function set_field_type a NULL field pointer. Suppose, for instance, that you want to change the system default field type to a minimum 10-character field of type TYPE_ALNUM. As described below, this field type accepts alphanumeric data -- every entered character must be a digit or an alphabetic (not a special) character. You can write
set_field_type ((FIELD *) 0, TYPE_ALNUM, 10);ETI provides several generic field types besides TYPE_ALNUM. Moreover, you can define your own field types, as described in ``Creating and manipulating programmer-defined field types''. The following sections describe all ETI generic field types.
The form driver restricts a field of this type to alphabetic data.
SYNOPSIS
set_field_type (field, TYPE_ALPHA, width); int width; /* minimum token width */TYPE_ALPHA takes one additional argument, the minimum width specification of the field. Note that when you previously create a field with function new_field, your cols argument is the maximum width specification of the field. With TYPE_ALPHA (and TYPE_ALNUM as well), your specification width must be less than or equal to cols. If not, the form driver cannot validate the field.
To set a middlename field, for instance, to TYPE_ALPHA with a minimum of 0 characters (in effect, to make the end-user's completing the field optional), you can write
FIELD * middlename;set_field_type (middlename, TYPE_ALPHA, 0);
This type restricts the set field to alphanumeric data, alphabetic characters (upper- or lower-case) and digits.
SYNOPSIS
set_field_type (field, TYPE_ALNUM, width); int width; /* minimum token width */
Like TYPE_ALPHA, TYPE_ALNUM takes one additional argument, the field's minimum width specification.
To set a field, say partnumber, to receive alphanumeric data at least eight characters wide, you write
FIELD * partnumber;set_field_type (partnumber, TYPE_ALNUM, 8);
This field type enables you to restrict the valid data for a field to a set of enumerated values. The type takes three arguments beyond the minimum two that set_field_type requires.
SYNOPSIS
set_field_type (field, TYPE_ENUM, keyword_list, checkcase, checkunique); char keyword_list; /* list of acceptable values */ int checkcase; /* check character case */ int checkunique; /* check for unique match */The argument keyword_list is a NULL-terminated array of pointers to character strings that are the acceptable enumeration values. Argument checkcase is a Boolean flag that indicates whether upper- or lower-case is significant during match operations. Finally, checkunique is a Boolean flag indicating whether a unique match is required. If it is off and your end-user enters only part of an acceptable value, the validation procedure completes the field value automatically with the first matching value in the type. If it is on, the validation procedure completes the field value automatically only when enough characters have been entered to make a unique match.
To create a field, say response, with valid responses of yes (y) or no (n) in upper- or lower-case, you write:
char * yesno[] = { "yes", "no", (char *)0 }; FIELD * response;For an example that sets the last field (checkunique) to TRUE, see ``Setting a field to TYPE_ENUM of colors'' which sets the TYPE_ENUM of field color to a list of colors.set_field_type (response, TYPE_ENUM, yesno, FALSE, FALSE);
char * colors[13] = { "Black", "Charcoal", "Light Gray", "Brown", "Camel", "Navy", "Light Blue", "Hunter Green", "Gold", "Burgundy", "Rust", "White", (char *) 0 }; FIELD * color;set_field_type (color, TYPE_ENUM, colors, FALSE, TRUE);
Setting a field to TYPE_ENUM of colors
Setting the field to TRUE requires the user to enter the seventh character of the color name in certain cases (Light Blue and Light Gray) before a unique match is made.
This type enables you to restrict the data in a field to integers.
SYNOPSIS
set_field_type (field, TYPE_INTEGER, precision, vmin, vmax); int precision; /* width for left padding with 0's */ long vmin; /* minimum acceptable value */ long vmax; /* maximum acceptable value */TYPE_INTEGER takes three additional arguments: a precision specification, a minimum acceptable value, and a maximum acceptable value.
As your end-user enters characters, they are checked for validity. A TYPE_INTEGER value is valid if it consists of an optional minus sign followed by some number of digits. As the end-user tries to leave the field, the range check is applied.
If the range check is passed, the integer is padded on the left with zeros to the precision specification. For instance, if the current value were 18, a precision of 3 would display
018whereas a precision of 4 would display
0018For more on ETI's handling of precision, see the manual page fprintf(3S).
As an example of how to use set_field_type with TYPE_INTEGER, the following might represent a month, padded to two digits:
FIELD * month;Note the requirement that the minimum and maximum values be converted to type long with the L.set_field_type (month, TYPE_INTEGER, 2, 1L, 12L); /* displays single digit months with leading 0 */
This type restricts the data for the set field to decimal numbers.
SYNOPSIS
set_field_type (field, TYPE_NUMERIC, precision, vmin, vmax); int precision; /* digits to right of the decimal point */ double vmin; /* minimum acceptable value */ double vmax; /* maximum acceptable value */TYPE_NUMERIC takes three additional arguments: a precision specification, a minimum acceptable value, and a maximum acceptable value.
As your end-user enters characters, they are checked for validity as decimal numbers. A TYPE_NUMERIC value is valid if it consists of an optional minus sign, some number of digits, a decimal point, and some additional digits.
The precision is not used in validation; it is used only in determining the output format. See fprintf(3S) for more on precision. As the end-user tries to leave the field, the range check is applied.
As with TYPE_INTEGER, if the maximum value is less than or equal to the minimum value, the range check is ignored.
For instance, to set a maximum value of $100.00 for a monetary field amount, you write:
FIELD * amount;set_field_type (amount, TYPE_NUMERIC, 2, 0.00, 100.00);
This type enables you to determine whether the data entered into a field matches
a specific regular expression.
SYNOPSIS
set_field_type (field, TYPE_REGEXP, expression); char expression; /* regular expression */TYPE_REGEXP takes one additional argument, the regular expression. See regcmp(3G) or ``Regular expressions'' for more information.
Consider, for example, how you might create a field that represents a part number with an upper- or lower-case letter followed by exactly 4 digits:
FIELD * partnumber;Note that this example assumes the field is five characters wide. If not, you may want to change the pattern to accept blanks on either side, thus:set_field_type (partnumber, TYPE_REGEXP, "^[A-Za-z][0-9]{4}$");
FIELD * partnumber;set_field_type (partnumber, TYPE_REGEXP, "^ *[A-Za-z][0-9]{4} *$");