| 42 | Note that the options are hidden, not removed. The user will still be able to select the option in most browsers by using keyboard shortcuts. Use a Warden rule to restrict the values accepted when a ticket is submitted, if that is what is needed. |
| 43 | |
| 44 | === Updating the contents of fields automatically |
| 45 | |
| 46 | The 'update' attribute of a field defines a rule for automatically updating the field's content. Normally, it is re-evaluated whenever one of the fields used to determine the outcome of the rule is changed. |
| 47 | |
| 48 | For example, take the rule: |
| 49 | {{{ |
| 50 | priority.update = (effort > 5) ? 'high' : 'low' |
| 51 | }}} |
| 52 | This assumes that a custom field named 'effort' is defined. If the 'effort' field is changed to a value greater than 5, then the priority field is set to 'high'. Otherwise it is set to low. |
| 53 | |
| 54 | Sometimes it's necessary to update a field only under certain conditions. In that case, the optional 'update.when' attribute can be used to define those conditions. |
| 55 | |
| 56 | For example: |
| 57 | {{{ |
| 58 | priority.update.when = milestone == 'Build 42' |
| 59 | }}} |
| 60 | Now the rule stated previously will be applied when the milestone is changed to 'Build 42', not when the 'effort' field is changed. The 'update.when' rule is re-evaluated whenever one of the fields used to determine the outcome of the rule is changed. |
| 61 | |
44 | | TBD |
45 | | |
46 | | === Updating the contents of fields automatically |
47 | | |
48 | | TBD |
| 64 | The 'template' attribute on a field assigns a name to a block of template text that could be used to pre-populate the field. The 'available' attribute for that name then defines the condition under which the field will be populated with that text. |
| 65 | |
| 66 | For example: |
| 67 | {{{ |
| 68 | evaluation.template.change = '=== Description ===\\nDescribe the change fully...' |
| 69 | evaluation.available.change = evaluation_template == 'Change' |
| 70 | evaluation.template.fault = '=== Description ===\\nDescribe the fault fully...' |
| 71 | evaluation.available.fault = evaluation_template == 'Fault' |
| 72 | evaluation.template.none = '' |
| 73 | evaluation.available.none = evaluation_template == 'None' |
| 74 | }}} |
| 75 | |
| 76 | This assumes that a custom field named 'evaluation_template' is defined (either a Select or a Radio field) with options 'None', 'Change' and 'Fault'. 'evaluation' is a Textarea field. When 'evaluation_template' is set to 'Change', the 'evaluation' field will be initialised with the value of the 'evaluation.template.change' option (shown here in a cut-down form; it would normally contain template entries for all the items of information that might be wanted in a Change evaluation). Similarly for 'evaluation_template' values of 'Fault' or 'None'. |
| 77 | |
| 78 | A field is only initialised from a template if it is currently either empty or unchanged from one of the alternative template values. Template fields can be preferred over the use of automatically-updated fields because of this behaviour. |
| 121 | |
| 122 | == Expression syntax |
| 123 | |
| 124 | In expressions, field names evaluate to the current value of the corresponding field, except for the special names `status`, which evaluates to the ticket status, `authname`, which evaluates to the current username, `true` which evaluates True and `false`, which evaluates False. If the field name is prefixed with an underscore, it evaluates to the value of the field at the time the page was loaded. |
| 125 | |
| 126 | Text-type fields evaluate to their contents, checkboxes evaluate to true if checked or false if not, and Select or Radio fields evaluate to the selected item if an item is selected or undefined if no item is selected. |
| 127 | |
| 128 | The full grammar of the expressions is: |
| 129 | {{{ |
| 130 | expression ::= or_expression |
| 131 | | or_expression "?" expression ":" expression |
| 132 | or_expression ::= and_expression |
| 133 | | and_expression "||" or_expression |
| 134 | and_expression ::= equality |
| 135 | | equality "&&" and_expression |
| 136 | equality ::= comparison |
| 137 | | comparison "==" | "!=" | "~=" equality |
| 138 | comparison ::= sum |
| 139 | | sum "<" | ">" | "<=" | ">=" comparison |
| 140 | sum ::= product |
| 141 | | product "+" | "-" sum |
| 142 | product ::= negation |
| 143 | | negation "*" | "/" product |
| 144 | negation ::= func_term |
| 145 | | "-" | "!" negation |
| 146 | func_term ::= term |
| 147 | | term "in" cmp_list |
| 148 | | <function_name> "(" param_list ")" |
| 149 | cmp_list ::= "(" cmp_list ")" |
| 150 | | func_term |
| 151 | | func_term "," cmp_list |
| 152 | param_list ::= *empty* |
| 153 | | term |
| 154 | | term "," param_list |
| 155 | term ::= "(" expression ")" |
| 156 | | <number> |
| 157 | | <field> |
| 158 | | "'" <string> "'" |
| 159 | }}} |
| 160 | `~=` is an operator that returns True only if the value on the left is matched by the regular expression on the right. `in` is an operator that returns True only if the value on the left appears in the list on the right. The operators `!`, `==`, `!=`, `||` and `&&` are negation, equality, inequality, OR and AND respectively. |
| 161 | |
| 162 | Note that the `&&` and `||` operators evaluate in the same way as the Javascript operators (or the Python `and` and `or` operators). So 'x && y' evaluates to 'x' if 'x' is false; 'y' if 'x' is true. [[span('x || y')]] evaluates to 'x' if 'x' is true; 'y' if 'x' is false. |