Adding Content Files to Work Item Custom Control Extension Package

In the previous 2 posts, we talked about how you can develop and deploy work item custom controls using the new architecture of TF Web Access 2012. In the previous posts we developed work item custom controls using HTML and JavaScript. However, in a real world scenario, developers will often need to use content files like images or css for a custom control. This post is about how to include these files in a WICC extension package.

We will continue to use VoteButton as the sample custom control and add an icon to the button.

First thing you need to do is have a reference to the base URL of the module. This URL is used to construct a reference to the content files included in the extension package. Defining the base URL module scoped is better because it will be available to all the controls inside that module:

 TFS.module("ACME.VoteButton", ["TFS.WorkItemTracking.Controls", "TFS.WorkItemTracking", "TFS.Core"], function () {
    var WITOM = TFS.WorkItemTracking,
        WITCONTROLS = TFS.WorkItemTracking.Controls,
        delegate = TFS.Core.delegate,
        moduleBaseUrl = TFS.getModuleBase("ACME.VoteButton");

    // Constructor for VoteButton
    function VoteButton(container, options, workItemType) {, container, options, workItemType);

Using this base URL, it is really easy to construct the URL to access any content file using the name specified in the extension package.

 _init: function () {

    // Create vote button
    this._control = $("<button type='submit' />").appendTo(this._container).bind("click", delegate(this, this._onClick));

    // Add vote icon
    $("<img />").attr("src", moduleBaseUrl + "vote.png").attr("align", "absMiddle").prependTo(this._control);

    // Add button text
    this._buttonText = $("<span />").text("Vote").appendTo(this._control);

The following changes also need to be made in order to have the control work correctly.

 // Update the control data
// Framework calls this method when the control needs to update itself, such as when:
//  - work item form is bound to a specific work item
//  - underlying field value has changed due to rules or another control logic
invalidate: function (flushing) {

    // Get the vote count from the underlying field
    var voteCount = this._getField().getValue() || 0;

    // Display the number of votes if any
    if (voteCount > 1) {
        this._buttonText.text(voteCount + " votes");
    } else if (voteCount == 1) {
        this._buttonText.text(voteCount + " vote");
    } else {

// Clear the control data
// Framework calls this method when the control needs to reset its state to "blank", such as when:
//  - work item form is unbound from a specific work item
clear: function () {

Then the extension package is recreated by including the content file as well.


After uploading the package to TFS, VoteButton should be seen with an icon.


Beside images, you can have your own css file inside the package. With the following JavaScript trick, it is possible to get css file working for the document.

 $("<link />").attr("href", moduleBaseUrl + "my.css")
    .attr("type", "text/css")
    .attr("rel", "stylesheet")

Let us know if you have any questions or feedback.