Add a custom control to the work item form
TFS 2018
Custom controls allow you to change how users view and interact with a field on the work item form. The following article walks you through how this sample custom control was built. Learn how to build your own custom control.
Tip
Check out our newest documentation on extension development using the Azure DevOps Extension SDK.
Add the custom control
To add a control to the main page, add a contribution to your extension manifest. The type of contribution should be ms.vss-work-web.work-item-form-control
and it should target the ms.vss-work-web.work-item-form
contribution.
"contributions": [
{
"id": "sample-work-item-form-control",
"type": "ms.vss-work-web.work-item-form-control",
"description": "Custom work item form control",
"targets": [
"ms.vss-work-web.work-item-form"
],
"properties": {
"name": "My Control",
"uri": "workItemControl.html",
"height": 600
}
}
]
The work item form adds an IFrame to host the custom control.
Properties
Property | Description |
---|---|
name |
Text that appears on the group. |
uri |
URI to a page that hosts the html that is loaded by the IFrame. |
height |
(Optional) Defines the height of the IFrame. When omitted, it's 50 pixels. |
inputs |
The values a user provides within the form. |
If you want to dynamically resize the IFrame, you can use the resize method
available in the client SDK.
A custom control on the work item form is another type of contribution, like group & page contribution. The main difference is that a control contribution can take a set of user inputs while group and page contributions can't.
Control contribution inputs
To define the inputs for your control contribution, use the inputs
property in the contribution object in the manifest.
In the following sample you see two inputs: FieldName
and Colors
. FieldName
specifies with which field the control associates. Colors
configures which colors map to which values in the control.
The values for the inputs get provided by the users when they add to the work item form. These values get passed to the control contribution when it's loaded on the form.
"inputs": [
{
"id": "FieldName",
"description": "The field associated with the control.",
"type": "WorkItemField",
"properties": {
"workItemFieldTypes": ["String"]
},
"validation": {
"dataType": "String",
"isRequired": true
}
},
{
"id": "Colors",
"description": "The colors that match the values in the control.",
"validation": {
"dataType": "String",
"isRequired": false
}
}
]
The following properties define a user input that the contribution can use:
- id - A unique ID for the input.
- description - A few sentences describing the input.
- type (optional) - The type of input.
- Valid values:
WorkItemField
- Indicates that the input is a Work Item field. The value provided by the user for this input should be a reference name for the valid work item field.
- Valid values:
- properties (optional) - Custom properties for the input.
- Valid keys:
workItemFieldTypes
- Defines an array of field types that this input supports. Valid values:String
Integer
DateTime
PlainText
HTML
TreePath
History
Double
Guid
Boolean
Identity
PicklistString
PicklistInteger
PicklistDouble
- Valid keys:
- validation - A set of properties that defines which values are considered valid for the input.
- Valid keys:
dataType
- Defines the data type of the input value. Valid values for this property:String
Number
Boolean
Field
isRequired
- A boolean value, which indicates whether the input is required to have a value.
- Valid keys:
JavaScript sample
A control extension works like a group or page extension with one difference that it can take certain user inputs. To read the user input values, use VSS.getConfiguration().witInputs
. The following sample shows how to register an object that's called when events occur on the work item form that may affect your contributed control. It also shows how to read input values provided by user for this control.
import { Control } from "control";
import * as ExtensionContracts from "TFS/WorkItemTracking/ExtensionContracts";
var control: Control;
var provider = () => {
return {
onLoaded: (workItemLoadedArgs: ExtensionContracts.IWorkItemLoadedArgs) => {
// create the control
var fieldName = VSS.getConfiguration().witInputs["FieldName"];
var colors = VSS.getConfiguration().witInputs["Colors"];
control = new Control(fieldName, colors);
},
onFieldChanged: (fieldChangedArgs: ExtensionContracts.IWorkItemFieldChangedArgs) => {
var changedValue = fieldChangedArgs.changedFields[control.getFieldName()];
if (changedValue !== undefined) {
control.updateExternal(changedValue);
}
}
}
};
VSS.register(VSS.getContribution().id, provider);
The following screenshot shows a sample custom work item control for the Priority field.