Sunday, June 08, 2008

Work Item Customization tidbits: conditional field behavior (part 2 of X)

In the previous installment I started talking about FIELDS section definitions. While basics were covered, there are still more advanced scenarios to be discussed; such as making certain field rule/behavior (or group of those) conditional based on user or other conditions.

To scope certain rule for specific users, there are for and not attributes exposed on rule elements. Those attributes accept Team Foundation Server group names; for example changing our example in the following way

<FIELD name="Issue" refname="Microsoft.VSTS.Common.Issue" type="String">
    <REQUIRED for="[Project]\Testers" not="[Project]\Developers"/>

makes the field mandatory only for the users in Team Project specific Testers group (and optional for Developers). The possible values for these attributes may be Team Foundation Server global groups (such as "Valid Users"), Team Project specific groups or Active Directory domain groups/users. If users from several groups need to be specified, common approach is to create TFS group combining those, and use it in the field definitions.

While giving plenty of leverage in scoping the fields' behavior to user groups, those attributes do not provide mechanism for creating dependencies between different fields' values. That kind of conditional behavior is handled by WHEN* elements; there are following elements available:

  • WHEN/WHENNOT – the elements are used to specify pattern "if field A has value B then …, else …" (however, the wording is somewhat different: "when field A has value B then …, when field A has not value B then …")
  • WHENCHANGED/WHENNOTCHANGED – the elements are used to provide logic similar to WHEN/WHENNOT pair; only the logic is tied to the certain field value changing rather than to the field being set to specific value

WHEN* elements are placed under FIELD elements and are used to group certain rules together for the same condition. The following snippet from the Bug template sets "State Change Date" field value to system time when "State" field value changes, and makes sure that the date field cannot be changed in the meanwhile by specifying read-only constraint:

<FIELD name="State Change Date" refname="Microsoft.VSTS.Common.StateChangeDate" type="DateTime">
    <WHENCHANGED field="System.State">
        <SERVERDEFAULT from="clock" />
    <WHENNOTCHANGED field="System.State">
        <READONLY />

This conditional logic in addition to basic rules provides a whole lot of flexibility. However, it also adds significant amount of complexity. If we consider rules that affect field values (namely DEFAULT and COPY rules) together with WHEN* conditional formatting, it is possible to create unintended chaining of rules (and the way WIT engine handles the rule logic is not that simple to start with).

That about gives very brief overview of how FIELDS section is defined (with the exceptions of data warehouse integration and global lists to be handled later). Next stop is WORKFLOW section – dealing with states and transitions should be pretty exciting!


Tanya said...

Hi! Can I create multiple conditions using WHEN ?
For example:
When State=QA and Category=X
copy from field A
when State=QA and Categoty=Y
copy from field B

Thank you! I have not seen such examples. Is it possible ?

Tanya said...

Can I use "When" to include mutiple fields in the conditional rule?

For example:
When State=X and Category=Y
copy from field A
When State=X and Category=Z
copy from field B

eugenez said...


You can have multiple WHEN clauses per field. However, you can specify only single driving field per WHEN clause. Additionally, WHEN clauses cannot be nested.

Hope that makes sense.

klevis said...

Hi, how can I use this custom controls to combine the sum of values of 2 integer fields into one.
So, if I have a field that has 2 as a value and another field that has 3. How can I have another field that will output 5 (3+2). I have been looking everywhere and nobody seems to know how to do that.
Please help!!!

Withers said...

Is there a way to blank out the Assigned to on state change?
We have several people that code review and QA. We'd like to blank out the assigned to whenever a task changes to these states to create a Queue essentially.