This post is just the javascript code for timesheet work item plugin in tfs web portal, the entire instruction to make the plugin work is in my post here.
TimeSheetControl.WorkItemTimeSheetControl.debug.js
{
TFS.module("TimeSheetControl.WorkItemTimeSheetControl",
[
"TFS.WorkItemTracking.Controls",
"TFS.WorkItemTracking",
"TFS.Core"
],
function () {
var WITOM = TFS.WorkItemTracking,
WITCONTROLS = TFS.WorkItemTracking.Controls,
delegate = TFS.Core.delegate;
var timesheet;
var timesheetXMLDoc;
var backupTimesheet = timesheet;
function WorkItemTimeSheetControl(container, options, workItemType) {
this.baseConstructor.call(this, container, options, workItemType);
}
WorkItemTimeSheetControl.inherit(WITCONTROLS.WorkItemControl, {
_control: null,
_init: function () {
this._base();
var dateHTML = "<label>Date:</label> <input type='text' id=\"date\" size='8' value='"+$.datepicker.formatDate('yy-mm-dd', new Date())+"'>";
var hourHTML = " Hours: <input type='number' id=\"hours\" value='1.00' size='3' min='0' max='24'>";
var commentsHTML = " Comments: <textarea rows='1' cols='25' id=\"comments\"></textarea>";
var addButtomHTML = " <input type='button' id='addButton' value='Add'>";
this._control = $(dateHTML + hourHTML + commentsHTML + addButtomHTML).appendTo(this._container);
$('#addButton').bind("click", delegate(this, this.addButtonClick));
this._control = $("<p><label id=\"messages\"></label></p>").appendTo(this._container);
$("<style type='text/css'> .ui-datepicker{ background-color: #FFF;} #timesheetTable{border-collapse: collapse;border: 1px solid #e6e6e6;} th {text-align: left;} #hours{width:50px;} #date{width:80px;}</style> ").appendTo("head");
$.getScript('//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js', function(){
$("#date").datepicker({dateFormat: "yy-mm-dd"});
});
},
invalidate: function (flushing) {
timesheet = this._workItem.getFieldValue("TimesheetRawData");
if(timesheet===""||timesheet==="[]")
timesheet = "<?xml version=\"1.0\"?><ArrayOfTimeSheetEntry xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"></ArrayOfTimeSheetEntry>";
try{
timesheetXMLDoc = $.parseXML(timesheet);
}
catch(err){
document.getElementById("messages").innerHTML = err.message;
}
this.printTable(timesheetXMLDoc);
},
clear: function () {
timesheet = backupTimesheet;
},
addButtonClick: function () {
var todayDate = new Date();
var year = todayDate.getFullYear();
var day = todayDate.getDate();
var month = todayDate.getMonth()+1;
var hour = (todayDate.getHours()<10)?"0"+todayDate.getHours():todayDate.getHours();
var minute = (todayDate.getMinutes()<10)?"0"+todayDate.getMinutes():todayDate.getMinutes();
var second = (todayDate.getSeconds()<10)?"0"+todayDate.getSeconds():todayDate.getSeconds();
var miliSecond = todayDate.getMilliseconds();
var createdDate = year+"-"+month+"-"+day+"T"+hour+":"+minute+":"+second+"."+miliSecond;
var TSDTmp = document.getElementById("date").value;
var timesheetDate = TSDTmp+"T00:00:00";
var minutes = document.getElementById("hours").value * 60;
if(minutes > 1440) minutes = 1440;
else if(minutes < 0) minutes = 0;
var comments = document.getElementById("comments").value;
var currentUser = this._workItem.store.getCurrentUser();
var newNode = timesheetXMLDoc.createElement("TimeSheetEntry");
newNode.setAttribute("CreatedDate", createdDate);
newNode.setAttribute("CreatedBy", currentUser);
newNode.setAttribute("TimeSheetDate", timesheetDate);
newNode.setAttribute("Minutes", minutes);
newNode.setAttribute("Comments", comments);
timesheetXMLDoc.documentElement.appendChild(newNode);
this._workItem.setFieldValue("TimesheetRawData",new XMLSerializer().serializeToString(timesheetXMLDoc));
var completedWork = this.getCompletedWork() + minutes/60;
var remainingWork = this.getRemainingWork()- minutes/60;
if (remainingWork < 0)
remainingWork = 0;
this.setRemainingWork(remainingWork);
this.setCompletedWork(completedWork);
document.getElementById("date").value=$.datepicker.formatDate('yy-mm-dd', new Date());
document.getElementById("comments").value="";
document.getElementById("hours").value="1.00";
},
deleteButtonClick: function(event){
var index = event.data.indexParam;
if(index.length === 0 || index < 0 || index > (timesheetXMLDoc.documentElement.getElementsByTagName("TimeSheetEntry").length-1))
alert("Invalid item index!");
else{
var removeItem = timesheetXMLDoc.documentElement.getElementsByTagName("TimeSheetEntry")[index];
var minutes = removeItem.getAttribute("Minutes");
timesheetXMLDoc.documentElement.removeChild(removeItem);
var self = event.data.o;
self._workItem.setFieldValue("TimesheetRawData",new XMLSerializer().serializeToString(timesheetXMLDoc));
var completedWork = self.getCompletedWork() - minutes/60;
var remainingWork = self.getRemainingWork() + minutes/60;
if (completedWork < 0)
completedWork = 0;
self.setRemainingWork(remainingWork);
self.setCompletedWork(completedWork);
}
},
printTable :function(timesheetXMLDoc)
{
if(this._container.children("table")!=''){
this._container.children("table").remove();
}
var tableSource = "<table id=\"timesheetTable\"><col width='70'><col width='80'><col width='30'><col width='270'><col width='50'>";
tableSource += "<tr bgcolor='#cce0ff' align='left'><th>User</th><th>Date</th><th>Hour</th><th>Comments</th><th>Delete</th></tr>";
try {
var nodeList = timesheetXMLDoc.getElementsByTagName("TimeSheetEntry");
for (var i = 0; i < nodeList.length; i++) {
tr = ((i%2)===0)?"<tr>":"<tr bgcolor='#e5efff'>";
tr += "<td>" + nodeList[i].getAttribute("CreatedBy")+ "</td>";
var dateRaw = nodeList[i].getAttribute("TimeSheetDate");
tr += "<td>" + dateRaw.substring(5,7)+"/"+dateRaw.substring(8,10)+"/"+dateRaw.substring(0,4) + "</td>";
tr += "<td>" + nodeList[i].getAttribute("Minutes")/60 + "</td>";
tr += "<td>" + nodeList[i].getAttribute("Comments") + "</td>";
tr += "<td> <input type='button' id='dButton"+i+"' value='delete'></td></tr>";
tableSource += tr;
}
tableSource += "</table>";
this._control = $(tableSource).appendTo(this._container);
for (var i = 0; i < nodeList.length; i++) {
$('#dButton'+i).on("click", {indexParam:i, o:this}, this.deleteButtonClick);
}
}
catch(err) {
document.getElementById("messages").innerHTML = "No entry :"+err.message;
}
},
getRemainingWork: function(){
if(this._workItem.getField("Remaining Work")!=null && this._workItem.getFieldValue("Remaining Work")!=""){
return this._workItem.getFieldValue("Remaining Work");
}
else return 0;
},
getCompletedWork: function(){
if(this._workItem.getField("Completed Work")!=null && this._workItem.getFieldValue("Completed Work")!=""){
return this._workItem.getFieldValue("Completed Work");
}
else return 0;
},
setRemainingWork: function(remainingWork){
this._workItem.setFieldValue("Remaining Work", remainingWork);
},
setCompletedWork: function(completedWork){
this._workItem.setFieldValue("Completed Work", completedWork);
},
});
// Register this module as a work item custom control called "WorkItemTimeSheetControl"
WITCONTROLS.registerWorkItemControl("WorkItemTimeSheetControl", WorkItemTimeSheetControl);
return {
WorkItemTimeSheetControl: WorkItemTimeSheetControl
};
})}












