I have a modal dialog that should get filled automatically with values.
It looks like this:
As you can see in the console, listCategory has the value Social (Comment), but it doesn't appear in the modal dialog and I don't know why.
It only has a value if I write this:
return {
commentData: {
comment: "",
customDate: ""
},
selectedCategory: "Social (Comment)",
lang: {
default: "en"
}
};
I'm not too familiar with Vue.js which is why I want to know how one can assign listCategory to selectedCategory.
This doesn't work:
selectedCategory: listCategory,
Nor does this:
selectedCategory: this.listCategory,
Here is the code:
export default {
props: ["text"],
components: { DatePicker },
data: function() {
var listCategory;
var listComment;
var listDate;
let siteUrl = 'https://thesite.sharepoint.com/sites/Playercard/';
let clientContext = new SP.ClientContext(siteUrl);
let oList = clientContext.get_web().get_lists().getByTitle('Comment');
let camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View><Query><Where><Eq><FieldRef Name=\'ID\'/>' +
'<Value Type=\'Number\'>100</Value></Eq></Where></Query></View>');
var collListItem = oList.getItems(camlQuery);
clientContext.load(collListItem);
console.log("clientContext loaded!");
// First we much execute the query to retrieve the items
clientContext.executeQueryAsync(()=> {
// Now colListItem is a collection, we must iterate through it
var listItemEnumerator = collListItem.getEnumerator();
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
listDate = oListItem.get_item('Date');
listCategory = oListItem.get_item('Category');
listComment = oListItem.get_item('Comment');
}
console.log("listDate: " + listDate);
console.log("listCategory " + listCategory);
console.log("listComment: " + listComment);
this.commentData.customDate = listDate;
this.commentData.selectedCategory = listCategory;
this.commentData.comment = listComment;
clientContext.executeQueryAsync(
() => console.log('Item(s) edited')),
() => console.log('Failed to edit item(s)');
},
()=>console.log('Failed to retrieve items'));
return {
commentData: {
comment: "",
customDate: ""
},
selectedCategory: "",
lang: {
default: "en"
}
};
},
Here's the relevant part of the template:
<div class="row">
<div class="d-inline col-lg-4 col-md-4 col-sm-4" padding="0px">
Category
<font color="red">*</font>
</div>
<div class="d-inline col-lg-8 col-md-8 col-sm-8" padding="0px">
<select v-model="selectedCategory">
<option>Social (Comment)</option>
<option>Sport (Comment)</option>
<option>School (Comment)</option>
<option>Others (Comment)</option>
</select>
</div>
</div>
error is in line
this.commentData.selectedCategory = listCategory;
replace it with
this.selectedCategory = listCategory;
You have an issue here :
console.log("listCategory " + listCategory);
console.log("listComment: " + listComment);
this.commentData.customDate = listDate;
this.commentData.selectedCategory = listCategory; -----------> Your commentData dict does not have selectCategory as a key
this.commentData.comment = listComment;
Change it to this :
console.log("listCategory " + listCategory);
console.log("listComment: " + listComment);
this.commentData.customDate = listDate;
this.selectedCategory = listCategory;
this.commentData.comment = listComment;
Related
Finally found an anchor code that puts a clickable URL where I want it, however the onclick of the radio buttons writes the URL for each click.
I need the URL to replace / reset the previous selection on each radio click so only 1 URL is ever showing - i will eventually have about 30 radio buttons - each will produce a different URL.
var roomNo = ""
var phoneNo = ""
var guestPin = ""
var roomLink = ""
var createLinkNode1 = ""
var createLinkNode2 = ""
var link369 = 'https://join.meet.video.justice.gov.uk/';
var link453 = 'https://join.meet.video.justice.gov.uk/';
function H369() {
document.getElementById("roomNo").innerHTML = "CVP Room: " + "HMCTS369";
document.getElementById("phoneNo").innerHTML = "Telephone Number: " + "02920 ";
document.getElementById("guestPin").innerHTML = "Guest Pin Number: " + "4444";
document.getElementById("roomLink").innerHTML = "<b>" + "Full Clickable URL Link: " + "</b>";
createLinkNode1(link369, document.body);
function createLinkNode1(url, parent) {
const linkTextNode = document.createTextNode(url);
const linkNode = document.createElement('a');
linkNode.href = url;
linkNode.appendChild(linkTextNode);
parent.appendChild(linkNode);
}
}
function H453() {
document.getElementById("roomNo").innerHTML = "CVP Room: " + "HMCTS453";
document.getElementById("phoneNo").innerHTML = "Telephone Number: " + "02920";
document.getElementById("guestPin").innerHTML = "Guest Pin Number: " + "5555";
document.getElementById("roomLink").innerHTML = "<b>" + "Full Clickable URL Link: " + "</b>";
createLinkNode2(link453, document.body);
function createLinkNode2(url, parent) {
const linkTextNode = document.createTextNode(url);
const linkNode = document.createElement('a');
linkNode.href = url;
linkNode.appendChild(linkTextNode);
parent.appendChild(linkNode);
}
}
<html>
<body>
<input type="radio" name="CVPRoom" onclick = "H369()">HMCTS369</br>
<input type="radio" name="CVPRoom" onclick = "H453()">HMCTS453</br>
<p id="demo"></p>
<p id="demo2"></p>
<p id="demo3"></p>
<div id="roomNo"></div>
<div id="phoneNo"></div>
<div id="guestPin"></div>
<div id="roomLink"></div>
<script src="CVPScripts.js">
</script>
</body>
</html>
I had it working on my previous code version, but the anchor would put the URL at the bottom of the HTML so was useless - stupidly overwrote the code so no example to demo
I suggest you delegate and create an object to hold the values
Then you are much more DRY (Don't Repeat Yourself)
I additionally use template literals
const radioContainer = document.getElementById("radioContainer");
const linkBase = 'https://join.meet.video.justice.gov.uk/HMCTS/#/';
const emailBase = '#meet.video.justice.gov.uk';
const output = document.getElementById("output");
const rooms = {
"hmcts369": {
"telephone": "02920 376411",
"guestPin": "4444"
},
"hmcts453": {
"telephone": "02920 376400",
"guestPin": "5555"
}
};
// create the room radios
radioContainer.innerHTML = Object
.keys(rooms)
.map(key => `<label><input type="radio" name="CVPRoom" />${key.toUpperCase()}</label>`).join("<br/>");
radioContainer.addEventListener("click", function(e) { // click anywhere in the label to select and show the details
const tgt = e.target.closest("label");
if (!tgt) return
const thisRoom = tgt.textContent.trim();
const thisRoomKey = thisRoom.toLowerCase();
const details = rooms[thisRoomKey];
if (!details) {
alert(`Sorry, room ${thisRoom} not found`);
return;
}
const href = `${linkBase}?conference=${thisRoomKey}${emailBase}`; //
output.innerHTML = `<div id="roomNo">CVP Room: ${thisRoom}</div>
<div id="phoneNo">Telephone Number: ${details.telephone}</div>
<div id="guestPin>Guest Pin Number: ${details.guestPin}</div>
<div id="roomLink"><b>Full Clickable URL Link</b></div>`;
})
<div id="radioContainer"></div>
<div id="output"></div>
Note the URL is not a truly valid URL with the /#/ in the middle.
If you have a better URL, you can do
const linkBase = new URL('https://join.meet.video.justice.gov.uk/HMCTS/#/'); // invalid URL - fix it and we can use the URL API
linkBase.searchParams.set("conference", `${thisRoomKey}${emailBase}`); // set the conference parameter
const href = linkBase.toString(); // get the URL
Here is a version that does not manipulate the DOM but just changes the text and attributes
const radioContainer = document.getElementById("radioContainer");
const linkBase = 'https://join.meet.video.justice.gov.uk/HMCTS/#/';
const emailBase = '#meet.video.justice.gov.uk';
const output = document.getElementById("output");
const roomNo = document.getElementById("roomNo");
const phoneNo = document.getElementById("phoneNo");
const guestPin = document.getElementById("guestPin");
const roomLink = document.getElementById("roomLink");
const rooms = {
"hmcts369": {
"telephone": "02920 376411",
"guestPin": "4444"
},
"hmcts453": {
"telephone": "02920 376400",
"guestPin": "5555"
}
};
// create the room radios
radioContainer.innerHTML = Object
.keys(rooms)
.map(key => `<label><input type="radio" name="CVPRoom" />${key.toUpperCase()}</label>`).join("<br/>");
radioContainer.addEventListener("click", function(e) { // click anywhere in the label to select and show the details
const tgt = e.target.closest("label");
if (!tgt) return
output.hidden = true;
const thisRoom = tgt.textContent.trim();
const thisRoomKey = thisRoom.toLowerCase();
const details = rooms[thisRoomKey];
if (!details) {
alert(`Sorry, room ${thisRoom} not found`);
return;
}
const href = `${linkBase}?conference=${thisRoomKey}${emailBase}`; //
roomNo.textContent = thisRoom;
phoneNo.textContent = details.telephone;
guestPin.textContent = details.guestPin;
roomLink.href = href;
output.hidden = false;
})
<div id="radioContainer"></div>
<div id="output" hidden>
<div>CVP Room: <span id="roomNo"></span></div>
<div>Telephone Number: <span id="phoneNo"></span></div>
<div>Guest Pin Number: <span id="guestPin"></span></div>
<div><a id="roomLink" href=""><b>Full Clickable URL Link</b></a></div>
</div>
The best way is create a object with the data, and not repeat functions that do the same thing. Create one function for each functionality and pass the data from the object to the functions.
Check this:
let conferences = [
{
id: "369",
input: {
name : "CVPRoom",
value: "HMCTS369"
},
info: {
room: "HMCTS369",
phone: "02920 376411",
pin: "4444",
link: "https://join.meet.video.justice.gov.uk/HMCTS/#/?conference=hmcts369#meet.video.justice.gov.uk"
}
},
{
id: "453",
input: {
name : "CVPRoom",
value: "HMCTS453"
},
info: {
room: "HMCTS453",
phone: "02920 376400",
pin: "5555"
}
}
]
let divInputs = document.querySelector('#inputs')
let divData = document.querySelector('#data')
conferences.forEach( c => {
let label = document.createElement('label')
let radio = document.createElement('input')
radio.setAttribute('type', 'radio')
radio.value = c.input.value
radio.name = c.input.name
radio.id = c.id
radio.addEventListener( 'change', e=>{
changeData( c )
} )
label.appendChild(radio)
label.appendChild( document.createTextNode( c.input.value ) )
divInputs.appendChild( label )
} )
function changeData( conferenceData ){
while( divData.hasChildNodes() ){
divData.removeChild( divData.firstChild )
}
let divRoom = document.createElement('div')
divRoom.appendChild(document.createTextNode(`CVP Room: ${conferenceData.info.room}`))
divData.appendChild( divRoom )
let divPhone = document.createElement('div')
divPhone.appendChild(document.createTextNode(`Telephone Number: ${conferenceData.info.phone}`))
divData.appendChild( divPhone )
let divPin = document.createElement('div')
divPin.appendChild(document.createTextNode(`Guest Pin Number: ${conferenceData.info.pin}`))
divData.appendChild( divPin )
let aLink = document.createElement('a')
aLink.appendChild(document.createTextNode('Full Clickable Link'))
aLink.href = `https://join.meet.video.justice.gov.uk/HMCTS/#/?conference=${conferenceData.info.room.toLowerCase()}#meet.video.justice.gov.uk`
divData.appendChild( aLink )
}
<html>
<body>
<div id="inputs">
</div>
<div id="data">
</div>
</body>
</html>
I've already searched this up before and tried using both pop() and lastIndexOf but it doesn't work well on looped dropdown.
Is there any alternative to getting the value after a delimiter, one that does not remove it from the list?
Here's my code:
$(document).ready(function () {
$('#VehicleID').change(function () {
var vehdrv = ($('#VehicleID :selected').val());
var drvid = vehdrv.split("_").pop();
var vehid = vehdrv.split("_")[0];
$('#VehicleID :selected').val(vehid);
//alert($('#VehicleID :selected').val());
if (drvid > 0) {
$('#DriverID').find("option").show().not("option[value*='" + drvid + "']").hide();
$("#DriverID").val(drvid);
//$("#DriverID").val(
//$("#DriverID").find("option:visible:first").val())
}
else {
$("#DriverID").find("option").show();
$("#DriverID").val(
$("#DriverID").find("option:visible:first").val())
}
}).trigger("change");
})
My Dropdowns from the controller:
public ActionResult ReserveInitial()
{
ViewBag.VehicleID = db.Vehicles.Where(item => item.IsReserved == false).Select(a => new SelectListItem
{
Value = a.VehicleID.ToString() + "_" + a.DriverID.ToString(),
Text = a.VehicleMake + " - " + a.PlateNumber,
});
ViewBag.DriverID = db.Drivers.Select(a => new SelectListItem
{
Value = a.DriverID.ToString(),
Text = a.DriverLastName + ", " + a.DriverFirstName
});
return View();
}
EDIT
This is how the string would look like if the VehicleID is linked to a Driver:
"14_5"
if the VehicleID is not associated with a Driver it would look like this:
"15_0"
var parts = vehdrv.split("_");
var drvid = parts[1];
var vehid = parts[0];
You can try this
var vehdrv = $('#VehicleID').val().match(/[^_]+/g);
var drvid = vehdrv[0];
var vehid = vehdrv[1];
console.log(drvid,vehid);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="VehicleID" type="text" value="14_5" name="text">
I have the following method which correctly gets list items from a sharepoint query, however the content type needs a special treatment and its not returned.
function getListItems(listId, camlQueryString, selectProperties){
var deferred = $q.defer();
var context = SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getById(listId);
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml(camlQueryString);
var listItems = list.getItems(camlQuery);
//var includesString = "Include(ID,Title,AssignedTo, WorkflowOutcome, ApproverComments, FileRef, WorkflowItemId, Created, Modified)"; // + selectProperties.join(", ") + ")";
if(selectProperties) {
var includesString = convertSelectPropertiesToIncludesString(selectProperties);
context.load(listItems, includesString);
} else {
context.load(listItems);
}
context.executeQueryAsync(
function() {
$log.info("Successfully retrieved list item result");
deferred.resolve(listItems);
},
function(error, errorInfo) {
$log.warn("Retrieving list item result failed");
deferred.reject(errorInfo);
}
);
return deferred.promise;
}
I need the content type name to be returned in the same array of listitems as another field.
I have found a few examples, but I am not sure how to integrate that code into mine because it seems a double call is needed for eachitem.
Update 1
I try to use the above method from this:
function GetRelatedBillingDocumentsFromList(selectProperties, currentBillCyclePath, clientCode, jobCodes, engagementCode, enhanceFunctions) {
$log.info("Retrieving related billing documents for bill cycle with name [" + currentBillCyclePath + "]");
var deferred = $q.defer();
var webUrl = _spPageContextInfo.webAbsoluteUrl;
var viewFields = spService.ConvertSelectPropertiesToViewFields(selectProperties);
// query must return the documents for the same client but in other bill cycles not the current one
var camlQuery = '<View>' + viewFields +
'<Query>' +
'<Where>' +
//'<And>' +
'<Eq>' +
'<FieldRef Name="ClientCode" />' +
'<Value Type="Text">'+ clientCode + '</Value>' +
'</Eq>' +
// '<Neq>' +
// '<FieldRef Name="ContentType" />' +
// '<Value Type="Computed">Bill Cycle</Value>' +
// '</Neq>' +
//'</And>' +
'</Where>' +
//'<QueryOptions>' +
// '<ViewAttributes Scope="RecursiveAll" />' +
//'</QueryOptions>' +
'</Query>' +
'</View>';
var billCyclesListId = "{c23bbae4-34f7-494c-8f67-acece3ba60da}";
spService.GetListItems(billCyclesListId, camlQuery, selectProperties)
.then(function(listItems) {
var listItemsWithValues = [];
if(listItems) {
var enumerator = listItems.getEnumerator();
while (enumerator.moveNext()) {
var listItem = enumerator.get_current();
var listItemValues = [];
selectProperties
.forEach(function(propertyName) {
if(propertyName==='ContentType'){
var value = listItem.get_item('ows_ContentType');
}else{
var value = listItem.get_item(propertyName);
}
listItemValues[propertyName] = value;
});
listItemsWithValues.push(listItemValues);
}
}
// Create the full item url
listItemsWithValues.forEach(function(listItem) {
var fileDirRef = listItem["FileRef"];
var id = listItem["ID"];
var serverUrl = _spPageContextInfo.webAbsoluteUrl.replace(_spPageContextInfo.webServerRelativeUrl,"");
var dispFormUrl = serverUrl + fileDirRef + "/DispForm.aspx?ID=" + id;
listItem["FileRef"] = dispFormUrl;
});
var enhancedListItemValues = spService.SpSearchQuery.EnhanceSearchResults(listItemsWithValues, enhanceFunctions);
deferred.resolve(listItemsWithValues);
})
.catch (function (message) {
deferred.reject();
});
return deferred.promise;
}
as you can see I need a way to return content type name in the same array of values in a simple way
You can use the ows_ContentType property to get the content type name.
So, add ows_ContentType in your includesString variable or selectProperties parameter.
After that, in your code you can use it as below:
context.executeQueryAsync(
function() {
var listItemEnumerator = listItems.getEnumerator();
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
console.log(oListItem.get_item('ows_ContentType'));
}
},
function(error, errorInfo) {
console.log(errorInfo);
}
);
Update - Full code
var context = SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getByTitle("Test");
var includesString = "Include(ID,Title,Created, Modified, ows_ContentType)";
var camlQuery = SP.CamlQuery.createAllItemsQuery();
var listItems = list.getItems(camlQuery);
context.load(listItems, includesString);
context.executeQueryAsync(
function() {
var listItemEnumerator = listItems.getEnumerator();
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
console.log(oListItem.get_item('ows_ContentType'));
}
},
function(error, errorInfo) {
console.log(errorInfo);
}
);
I want to take a JavaScript var from database to JavaScript code.
I have a twitch community that help stream by the way I need to let the user or member add their twitch name to the list so that other members can see them when they are online.
my code is :
JAVASCRIPT
var hello = "hello";
/* This is an alternate method to creating javascript methods
function streamer(name, status, url) {
this.name = name;
this.status = status;
this.url = url;
} */
// The streamer object
// here we will store the necessary information from
// the twitch api json file
var Streamer = {
id: 0,
status: "title",
name: "strimmah",
display_name: "Strimmah",
url: "https://secure.twitch.tv/freecodecamp", // test url
previewImgs: ["large", "medium", "small", "template"],
game: "GaM3",
viewers: 0,
init: function(name, status, game, url) {
this.name = name;
this.status = status;
this.game = game;
this.url = url;
},
init: function(name, status, game, viewers, url) {
this.name = name;
this.status = status;
this.game = game;
this.viewers = viewers;
this.url = url;
},
initPreviewImgs: function(large, medium, small, template) {
this.previewImgs[0] = large;
this.previewImgs[1] = medium;
this.previewImgs[2] = small;
this.previewImgs[3] = template;
}
};
// delete test variables
var test = Object.create(Streamer);
var backUpImage = "https://static-cdn.jtvnw.net/ttv-static/404_preview-640x360.jpg";
var tempStreamers = [
"nokss68",
"snake606",
"team_itxx_cod",
"relapsegtv",
"sokkaenpyjama",
"elfepurpl3",
"lighthund",
"spacecakezed",
"nagatsu6",
"xng360",
"nazenko",
"giiskaa",
"floki_live",
"kayakox",
"jejen64",
"spivix",
"keryg4n",
"mehdii95150",
"mrgeekyfr",
"zaykerz92",
"etsalutdit",
"x_dyn_x",
"martind32",
"el_fideo11",
"xmisticoxx",
"zookervinc78",
"MrCraaftt",
"killerelite84",
"Aqu0ss",
"panteleimon42",
"veynstream",
"le_salty_gamer"
];
var streamDisplayStatus = 1; // 0-ALL, 1-Online Only, 2-Offline only
var twitchURL = "https://secure.twitch.tv/"; // to create channel urls
var streamerArray = [];
var showOffline = true;
// ENTRY POINT,
$(document).ready(function() {
/*for (var i = 0; i < tempStreamers.length; i++) {
loadStreamJsonInfo(tempStreamers[i], test);
}*/
// initial set of streamers, we start with Overview so show all
instantiateStreamers();
// navigator button setup
navigationButtons();
});
function instantiateStreamers() {
streamerArray.length = 0;
for (var i = 0; i < tempStreamers.length; i++) {
var streamer = Object.create(Streamer);
loadStreamJsonInfo(tempStreamers[i], streamer);
}
}
function loadStreamJsonInfo(name, data) {
/*$.getJSON('https://api.twitch.tv/kraken/streams/freecodecamp?callback=?', function(json) {
console.log(json);
}); */
$.getJSON('https://api.twitch.tv/kraken/streams/' + name + '?callback=?',
function(json) {
// console.log(json);
var stream = json.stream;
if (stream !== null) {
var channel = json.stream.channel;
data.init(channel.display_name, channel.status, channel.game, stream.viewers, channel.url);
data.initPreviewImgs(stream.preview.large, stream.preview.medium, stream.preview.small, stream.preview.template);
// console.log(data.name + " " + data.status + " " + data.viewers);
} else {
data.init(name, "Offline", "", 0, twitchURL + name)
data.initPreviewImgs(backUpImage, backUpImage, backUpImage, backUpImage);
}
streamerArray.push(data);
//console.log("TEST: " + streamerArray.length);
checkDisplayStatus(data);
}); // end of getJson
}
function checkDisplayStatus(data) {
switch (streamDisplayStatus) {
case 0:
createStreamerDOMItem(data);
break;
case 1:
if (data.status !== "Offline") {
createStreamerDOMItem(data);
}
break;
case 2:
if (data.status === "Offline") {
createStreamerDOMItem(data);
}
break;
default:
createStreamerDOMItem(data);
console.log("Default switch");
break;
}
}
function createStreamerDOMItem(streamData) {
var divStart = '<div class="streamer-container">';
var divEnd = '</div></div>';
var divStreamerItem = '<div class="streamer-item" align="center">' + '<a target="_blank" href="' + streamData.url +
'"><iframe src="https://player.twitch.tv/?channel='+ streamData.name +'\" frameborder="0" scrolling="no" height="350" width="100%" /></a>' +
'<p id="viewer-count"><font color="yellow">' + streamData.viewers + ' personne(s) sur ' +
'</font>' + streamData.name + '</p>'
+ '';
var final = divStart + divStreamerItem + divEnd;
$(final).appendTo(".live-channels-container");
}
function clearStreamerDOMItems() {
$("div").remove(".streamer-container");
}
HTML
<div>
<div class="navbar-container" >
</div>
<br>
<div class="live-channels-container">
</div>
<!-- END OF STREAMER BOXES-->
</div>
Now I want to get ( var tempStreamers = ) username from DATABASE.
You can get the tempStreamers by JSONP method which you need a new api to output the data.
Use setinterval to run you function every 2 seconds.Then you will get the newest data.
I have been trying to fetch some information such as username, displayname, role and capacity depending upon iteration. The query returns some of the result for the specified project but not all for the selected iteration. I am not sure what is causing this. You can find my work so far below.
function iterationSelected(dropdown, eventArgs) {
console.log("Iteration Selected Callback");
if(table != null){
table.destroy();
}
var queryByUser = {
key: "teamDataByUser", type: "User",
fetch: 'DisplayName,UserName',
query: '(ObjectID > 0)'
};
rallyDataSource.findAll(queryByUser, queryTeamInformation);
}
function queryTeamInformation(results){
console.log(results.teamDataByUser.length);
for(var i=0;i<results.teamDataByUser.length;i++){
console.log(results.teamDataByUser[i].UserName + " " + results.teamDataByUser[i].DisplayName);
}
console.log(iterationDropdown.getSelectedName());
var queryByUserName = {
key: "teamData", type: "UserIterationCapacity",
project: null,
fetch: "Capacity,User,Role,EmailAddress,DisplayName,UserName",
query: '((Iteration.Name = ' + '"' + iterationDropdown.getSelectedName() + '") AND (Project = /project/5564891653))'
};
rallyDataSource.findAll(queryByUserName, processResults);
console.log("GH");
}
function processResults(results){
rally.forEach(results.teamData,
function(teamData) {
console.log(teamData._ref);
});
console.log(results.teamData.length);
var tableDiv = document.getElementById('table');
var config = { columns:
[{key: 'emailaddress', header: 'Team Member Email', width: 200},
{key: 'displayname', header: 'Display name'},
{key: 'username', header: 'User name'},
{key: 'role', header: 'Role'},
{key: 'cap', header: 'Capacity'}] };
if(table != null){
console.log("Got here");
table.destroy();
}
table = new rally.sdk.ui.Table(config);
for(var i=0;i<results.teamData.length;i++){
var rowInfo = {'emailaddress': results.teamData[i].User.DisplayName, 'displayname': results.teamData[i].User.UserName, 'username': results.teamData[i].User.EmailAddress, 'role' : results.teamData[i].User.Role, 'cap' : results.teamData[i].Capacity};
table.addRow(rowInfo);
}
table.display(tableDiv);
}
//========================================================================================================================
/*
* Initializes all the page elements
*/
function initPage() {
rallyDataSource = new rally.sdk.data.RallyDataSource('5410787910', '5948174836', 'false', 'true');
var config = { label : "Select an iteration " };
iterationDropdown = new rally.sdk.ui.IterationDropdown(config, rallyDataSource);
iterationDropdown.display("aDiv", iterationSelected);
}
rally.addOnLoad(initPage);
Ok - I've written an example that I think illustrates what's needed to get where you want to go. It does this by doing two queries in a queryConfig array: one for Users and another for UserIterationCapacity for the Iteration of interest. Then, in the processResults function, the code constructs three hashes:
teamMembersByTeamName: string of team members for each project, hashkey: Team/project Name
myTeamList: contains User data from Users (1st) query, selected for a Team of interest, hashkey: UserName
userIterationCapacityByUser: contains UserIterationCapacity data from 2nd query, hashkey: UserName
Finally, the code does a cross-walk by UserName to re-construct Capacity data for all TeamMembers, even if they have no capacity defined for the Sprint of interest. If this is the case, the Capacity is shown as "N/A".
You would need to customize the workspaceOID, projectOID, and myTeamSlashProjectName variables to get this to work in your environment. You will probably want to customize and tweak - it's just a rough code sample. But hopefully enough to illustrate the concept.
<!-- Copyright (c) 2012 Rally Software Development Corp. All rights reserved -->
<html>
<head>
<title>Team Capacity Summary Example</title>
<meta name="Name" content="App Example: Team Capacity Summary" />
<meta name="Version" content="1.31" />
<meta name="Vendor" content="Rally Labs" />
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.31/sdk.js"></script>
<script type="text/javascript">
var rallyDataSource = null;
var iterationDropdown = null;
var selectedIteration = "Iteration 1";
var workspaceOID = "12345678910";
var projectOID = "12345678911";
var myTeamSlashProjectName = "My Project";
var table;
function iterationSelected(dropdown, eventArgs) {
var selectedItem = eventArgs.item;
selectedIteration = eventArgs.value;
runMainQuery();
}
function runMainQuery() {
var queryConfig = [];
var capacityQueryString = '((Iteration.Name = ' + '"' +
selectedIteration +
'") AND (Project.ObjectID = "' +
projectOID +
'"))';
console.log(capacityQueryString);
queryConfig[0] = {
key: "usercapacities",
type: "UserIterationCapacity",
fetch: "Capacity,User,Role,EmailAddress,DisplayName,UserName",
query: capacityQueryString
};
queryConfig[1] = {
type: "users",
key: "userdata",
fetch: "UserName,EmailAddress,DisplayName,UserName,UserPermissions,Project,Role,Name,TeamMemberships,Project,Name"
};
rallyDataSource.findAll(queryConfig, processResults);
}
function processResults(results) {
// Populate a hash of team members by team name
var teamMembersByTeamName= new Array();
for (i=0;i<results.userdata.length;i++){
myUser = results.userdata[i];
myUserName = myUser.UserName;
myEmailAddress = myUser.EmailAddress;
myDisplayName = myUser.DisplayName;
myRole = "N/A";
if (myUser.TeamMemberships) {
myTeamMemberships = myUser.TeamMemberships;
for (j=0;j<myTeamMemberships.length;j++) {
thisTeam = myTeamMemberships[j];
thisTeamName = thisTeam.Name;
if (!(thisTeamName in teamMembersByTeamName)) {
teamMembersByTeamName[thisTeamName] = [];
}
var dataToPush = new Array();
dataToPush["UserName"] = myUserName;
dataToPush["EmailAddress"] = myEmailAddress;
dataToPush["DisplayName"] = myDisplayName;
dataToPush["Role"] = myRole;
dataToPush["Capacity"] = "N/A";
teamMembersByTeamName[thisTeamName].push(dataToPush);
}
}
}
// Now populate a hash of User Capacities
var userIterationCapacityByUser = new Array();
for (i=0;i<results.usercapacities.length;i++) {
thisCapacityObject = results.usercapacities[i];
thisUserName = thisCapacityObject.User.UserName;
if (!(thisUserName in userIterationCapacityByUser)) {
thisUser = thisCapacityObject.User;
thisCapacity = thisCapacityObject.Capacity;
userIterationCapacityByUser[thisUserName] = [];
var dataToPush = new Array();
dataToPush["UserName"] = thisUser.UserName;
dataToPush["EmailAddress"] = thisUser.EmailAddress;
dataToPush["DisplayName"] = thisUser.DisplayName;
dataToPush["Role"] = thisUser.Role;
dataToPush["Capacity"] = thisCapacity;
userIterationCapacityByUser[thisUserName].push(dataToPush);
}
}
// Setup and configure the table
var tableDiv = document.getElementById('tableDiv');
var tableConfig = { columns:
[{key: 'emailaddress', header: 'Team Member Email', width: 200},
{key: 'displayname', header: 'Display name'},
{key: 'username', header: 'User name'},
{key: 'role', header: 'Role'},
{key: 'cap', header: 'Capacity'}] };
if(table != null){
table.destroy();
}
table = new rally.sdk.ui.Table(tableConfig);
// Finally cross-walk team membership by correlating the data from the two hashes
// Grab team list of interest
myTeamList = teamMembersByTeamName[myTeamSlashProjectName];
for(i=0;i<myTeamList.length;i++) {
myTeamMemberData = myTeamList[i];
myUserNameFromTeamList = myTeamMemberData["UserName"];
// User has capacity information - populate data from that result set
if (myUserNameFromTeamList in userIterationCapacityByUser) {
myUserDataArray = userIterationCapacityByUser[myUserNameFromTeamList];
myUserData = myUserDataArray[0];
} // User doesn't have capacity information - populate data from user query
else {
myUserData = myTeamMemberData;
}
var myUserName = myUserData["UserName"];
var myEmailAddress = myUserData["EmailAddress"];
var myDisplayName = myUserData["DisplayName"];
var myRole = myUserData["Role"];
var myCapacity = myUserData["Capacity"];
if (myDisplayName) {
thisDisplayName = myDisplayName;
} else {
thisDisplayName = "N/A";
}
var rowInfo = {
'emailaddress': myEmailAddress,
'displayname': thisDisplayName,
'username': myUserName,
'role' : myRole,
'cap' : myCapacity};
table.addRow(rowInfo);
}
var tableDiv = document.getElementById("tableDiv");
table.display(tableDiv);
}
function onLoad() {
rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__',
'__PROJECT_OID__',
'__PROJECT_SCOPING_UP__',
'__PROJECT_SCOPING_DOWN__');
var config = {
label : "Select an iteration ",
defaultDisplayValue: selectedIteration
};
var iterationDropdown = new rally.sdk.ui.IterationDropdown(config, rallyDataSource);
iterationDropdown.display("aDiv", iterationSelected);
}
rally.addOnLoad(onLoad);
</script>
</head>
<body>
<div id="aDiv"></div>
<div id="tableDiv"></div>
</body>
</html>