In the 1.x version of the Rally SDK I was able to query and assign to an HTML DIV with a query like the following:
var querySI48 = {
type : 'portfolioitem',
query:'(Name = "Q3 2015 Release (2.8.0)")',
key : 'SI48Key',
fetch: 'PercentDoneByStoryCount'
};
And assign it to a DIV like this:
var WS215 = document.getElementById("WS215");
WS215.innerHTML = "<h2>" + pisInfo + "%</h2>";
How can I assign the PercentDoneByStoryPoint to a DIV with the 2.X SDK? I'm creating a dashboard in Confluence that contains Rally data.
Something similar to the following should do the trick:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script type="text/javascript" src="/apps/2.0/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
Ext.define('Rally.example.App', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var me = this;
var divTemplateString = "<h2>{0}: Percent Done by Story Count = {1}</h2>";
Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem/Feature',
fetch: true,
autoLoad: true,
filters: [
{
property: 'FormattedID',
value: 'F15'
}
],
listeners: {
load: function(store, data, success) {
var formattedID = data[0].get('FormattedID');
var pctDoneByStoryCount = data[0].get('PercentDoneByStoryCount');
var divHTML = Ext.String.format(divTemplateString, formattedID, pctDoneByStoryCount);
var div = Ext.get('F15');
me.add({
xtype: 'container',
html: divHTML,
renderTo: div
});
}
},
});
}
});
Rally.launchApp('Rally.example.App', {
name: 'Example'
});
});
</script>
<style type="text/css">
</style>
</head>
<body>
<div id="F15"</div>
</body>
</html>
Related
I am working on a vuejs repeatable component that will allow a user to due several things---enter a question and select the answer type from the drop down. Issue is based on the type, I need to display a select number of boxes if its multiple choices so it can update an array. I cannot figure out how or where to add this. I also need to make these variable (f1 and f2 dynamic) so that it can be reused at other times. So if its a single line choose f1 if it is multiple choice select f2. Someone please provide some direction
Vue.component('my-input', {
template: '<input v-attr="name: name" v-model="value" type="text">' + '<select>' + '<option value="type1">Multiple Choice</option>' + '<option value="type2">single line</option>' + '<option value="type3">multi-line</option>' + '</select><br>'+'<br>'+'</br>',
data() {
return {
value: '',
brand: 'multiple-choice',
options: ['option a, option b'] };
},
props: ['name'] });
new Vue({
el: '#app',
data: {
message:'',
inputs: [{ type: 'my-input' }]
},
mounted: function () {
this.getAllPages();
},
methods: {
addInput() {
this.inputs.push({ type: 'my-input' });
},
getAllPages: function () {
var vm = this;
$.ajax({
url: vm.config.domainRoot + "/_api/web/lists/getbytitle('" + vm.config.listName + "')/items",
type: 'Get',
headers: {
"Accept": "application/json; odata=verbose"
},
success: function (data) {
vm.pages = data.d.results;
console.log(vm.pages);
}
})
},
createCustomL:function(){
// Get filed collection
var fldCollection = oList.get_fields();
var f1 = clientContext.castTo(
fldCollection.addFieldAsXml('<Field Type="Text" DisplayName="NewField" Name="NewField" Required="True"/>', true, SP.AddFieldOptions.addToDefaultContentType),
SP.FieldText);
f1.set_title("q1");
f1.set_description(mydescription);
f1.update();
//Get filed collection
var fldCollection = oList.get_fields();
var f2 = clientContext.castTo(
oList.get_fields().addFieldAsXml('<Field Type="Choice" DisplayName="state" Name="fldchoice" />', true, SP.AddFieldOptions.addToDefaultContentType),
SP.FieldChoice);
var choices = Array("None", "California", "Colorado", "Connecticut", "Georgia", "Indiana");
f2.set_choices(choices);
f2.update();
}
}
});
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Vue.js repeater</title>
</head>
<body>
<!-- partial:index.partial.html -->
<div id="app">
<p>Enter your ques</p>
<component v-repeat="inputs" is="{{ type }}" name="inputs[]">
</component>
<button v-on="click: addInput">Add Question</button>
</div>
<br>
<button v-on:click="createCustom">Generate</button>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.8/vue.js'></script>
<script src="./script.js"></script>
</body>
</html>
I don't know if i understand correctly but if you want to pass different data to your component dynamically you can use props.
Take a look here https://v2.vuejs.org/v2/guide/components-props.html
I want to add expand all and collapse all option to the rallytreegrid.
I used the code at https://help.rallydev.com/apps/2.1/doc/#!/example/simple-tree-grid and added expandAllInColumnHeaderEnabled property with value as true. Still expand all and collapse all options are not working.
Following is the updated code:
<!DOCTYPE html>
<html>
<head>
<title>Simple Tree Grid Example</title>
<script type="text/javascript" src="/apps/2.1/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
Ext.define('Rally.example.SimpleTreeGrid', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['userstory'],
autoLoad: true,
enableHierarchy: true
}).then({
success: this._onStoreBuilt,
scope: this
});
},
_onStoreBuilt: function(store) {
this.add({
xtype: 'rallytreegrid',
store: store,
context: this.getContext(),
enableEditing: false,
enableBulkEdit: false,
shouldShowRowActionsColumn: false,
expandAllInColumnHeaderEnabled: true,
enableRanking: false,
columnCfgs: [
'Name',
'ScheduleState',
'Owner'
]
});
}
});
Rally.launchApp('Rally.example.SimpleTreeGrid', {
name: 'Simple Tree Grid Example'
});
});
</script>
<style type="text/css">
</style>
</head>
<body></body>
</html>
Please help. Thanks in advance.
This was a bit of a weird one. In order to get this to work you need to both enable the config flag you already found and also add a plugin to the treegrid:
plugins: [{ ptype: 'rallytreegridexpandedrowpersistence'}],
expandAllInColumnHeaderEnabled: true
I have defined dgrid and a button for removing row:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://cdn.rawgit.com/SitePen/dgrid/v1.1.0/css/dgrid.css" media="screen" />
</head>
<body class="claro">
<div id="container"></div>
<button id="remove">Remove</button>
<script type="text/javascript">
var dojoConfig = {
async: true,
packages: [
{ name: 'dgrid', location: '//cdn.rawgit.com/SitePen/dgrid/v1.1.0' },
{ name: 'dstore', location: '//cdn.rawgit.com/SitePen/dstore/v1.1.1' }
]
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script type="text/javascript">
require([
'dojo/_base/declare',
'dojo/on',
"dojo/dom",
"dstore/Memory",
"dstore/Trackable",
'dstore/SimpleQuery',
'dgrid/Grid',
'dgrid/extensions/Pagination',
'dgrid/extensions/DijitRegistry',
'dojo/domReady!'
],
function(declare, on, dom, Memory, Trackable, SimpleQuery, Grid, Pagination, DijitRegistry) {
var data = [];
for (var i = 1; i <= 500; i++) {
data.push({id:i,name: 'Name '+i, value: i});
}
var Store = declare([Memory, SimpleQuery, Trackable]);
var myStore = new Store({data:data});
var MyGrid = declare([Grid, Pagination]);
var grid = new MyGrid({
collection: myStore,
columns: {
'id' : 'Id',
'name' : 'Name',
'value' : 'Value'
},
className: "dgrid-autoheight",
showLoadingMessage: false,
noDataMessage: 'No data found.'
}, 'container');
grid.startup();
on(dom.byId('remove'),'click',function() {
myStore.remove(10);
});
});
</script>
</body>
</html>
The dgrid shows up, you can sort it, edit name or value.
The problem is, that when you click on the "remove" button, row is deleted, but then, at the end of the gird is 9x written: "No data found" and the dgrid stops to work (you cant delete any other row).
If you set showLoadingMessage: to true, then everything works without a problem.
Edit: I have simplified the example. Problem persists.
The grid may have been encountering error while updating the row data after the row has been removed. As the editor tries to update the row after the button loses focus. Try using the grid.removeRow method to remove the row. It might still encounter some other issues, but worth a try.
Editor might not be the best solution to achieve what your are trying to do.
User renderCell to add button to the grid, to remove the row/record. This might be a better solution.
Update: Just refresh the grid that should solve the problem.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://cdn.rawgit.com/SitePen/dgrid/v1.1.0/css/dgrid.css" media="screen" />
</head>
<body class="claro">
<div id="container"></div>
<button id="remove">Remove</button>
<script type="text/javascript">
var dojoConfig = {
async: true,
packages: [
{ name: 'dgrid', location: '//cdn.rawgit.com/SitePen/dgrid/v1.1.0' },
{ name: 'dstore', location: '//cdn.rawgit.com/SitePen/dstore/v1.1.1' }
]
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script type="text/javascript">
require([
'dojo/_base/declare',
'dojo/on',
"dojo/dom",
"dstore/Memory",
"dstore/Trackable",
'dstore/SimpleQuery',
'dgrid/Grid',
'dgrid/extensions/Pagination',
'dgrid/extensions/DijitRegistry',
'dojo/domReady!'
],
function(declare, on, dom, Memory, Trackable, SimpleQuery, Grid, Pagination, DijitRegistry) {
var data = [];
for (var i = 1; i <= 500; i++) {
data.push({id:i,name: 'Name '+i, value: i});
}
var Store = declare([Memory, SimpleQuery, Trackable]);
var myStore = new Store({data:data});
var MyGrid = declare([Grid, Pagination]);
var grid = new MyGrid({
collection: myStore,
columns: {
'id' : 'Id',
'name' : 'Name',
'value' : 'Value'
},
className: "dgrid-autoheight",
showLoadingMessage: false,
noDataMessage: 'No data found.'
}, 'container');
grid.startup();
on(dom.byId('remove'),'click',function() {
myStore.remove(10);
grid.refresh();
});
});
</script>
</body>
</html>
I have two dojo select dropdowns. First dropdown is populated on page load and on selecting a value from first drop down, second select box should be populated.
I create the second select box programatically and i destroy it for every on change event of the first dropdown box.( this is to avoid widget already registered error).
But when i select any of the option from second drop down select, it does not fire onchange event.
Pls help on this.
My code is
require(["dojo/parser","dijit/form/RadioButton","dojo/ready","dojo/data/ItemFileReadStore","dijit/registry","dijit/form/Select","dojo/ready","dojo/dom-form", "dojo/dom", "dojo/on", "dojo/request","dojo/domReady"],
function(parser,RadioButton,ready,ItemFileReadStore,registry,Select,ready,Form,dom,on,request){
parser.parse();
var manuData;
var modelData;
var shaftType;
var modelId;
var clubMfr;
var clubType;
var manufacturerList;
dojo.connect(dijit.byId("clubtype"),"onChange",function(event){
clubType=registry.byId("clubtype").get('value');
console.log(clubType);
var id= registry.byId("clubtype");
var option1= registry.byId("manufacturer");
request("/tradeIn/"+clubType).then(function(list){
manuData=list;
var data1 = dojo.fromJson(manuData);
var readstore=new ItemFileReadStore({ data:{
identifier : "manufacturer",
label: "manufacturer",
items : data1,
}});
if(typeof registry.byId("manufacturerId") != "undefined"){
registry.byId("manufacturerId").destroyRecursive();
}
manufacturerList=new Select({
name:"manufacturerId",
id:"manufacturerId",
store:readstore,
onSetStore: function() {
this.options.unshift({selected:'true',label:'Choose One', value:'NULL'});
this._loadChildren();
}
}).placeAt("manuList");
manufacturerList.startup();
});
}
);
dojo.connect(
dijit.byId("manufacturerId"),"onChange",function(event){
var manufacturerId=registry.byId("manufacturerId").get('value');
clubMfr=manufacturerId;
var model= registry.byId("model");
model.removeOption(dijit.byId("model").getOptions());
request("/tradeIn/"+manufacturerId+"/"+clubType).then(function(list){
modelData=list;
var data1 = dojo.fromJson(modelData);
var readstore=new ItemFileReadStore({ data:{
identifier : "model",
label: "model",
items : data1
}});
if(typeof registry.byId("modelId") != "undefined"){
registry.byId("modelId").destroyRecursive();
}
var modelList=new Select({
name:"modelId",
id:"modelId",
store:readstore,
onSetStore: function() {
this.options.unshift({selected:'true',label:'Choose One', value:'NULL'});
this._loadChildren();
}
}).placeAt("modelList");
modelList.startup();
});
}
);
dojo.connect(
dijit.byId("model"),"onChange",function(event){
modelId=registry.byId("model").get('value');
console.log("model "+modelId);
}
);
});
You need to disconnect the onChange event before destroying the select and to reconnect it after creating the select. To achieve the disconnection, you can use own() method.
Here is how it should look like:
if(typeof registry.byId("manufacturerId") != "undefined"){
registry.byId("manufacturerId").destroyRecursive();
}
manufacturerList=new Select({/* ... */});
manufacturerList.own(dojo.connect(
dijit.byId("manufacturerId"),"onChange",function(event){ /* ... */ }
));
Note: This is extremely dirty. The proper approach would be to NOT destroy the second select and instead to update its data.
See the snippets for updating it:
require(['dijit/form/Select', 'dojo/data/ItemFileReadStore', 'dojo/domReady!'], function(Select, ItemFileReadStore) {
var initialStoreData = [
{value: "AL", label: "Alabama"},
{value: "AK", label: "Alaska"},
{value: "AZ", label: "Arizona"}
];
var changedStoreData = [
{value: "CA", label: "California"},
{value: "CO", label: "Colorado"},
{value: "CT", label: "Connecticut"}
];
var prepareData = function(storeData) {
//because the store return sorted data, I have added a space before the word 'Choose'. So it comes first
return [{value: '', label: ' Choose one'}].concat(storeData);
}
var readStore=new ItemFileReadStore({
data:{
identifier: "value",
label: "label",
items: prepareData(initialStoreData)
}
});
var selectWidget = new Select({
store: readStore
});
selectWidget.placeAt(document.getElementById('test'));
selectWidget.startup();
btn.onclick = function() {
var newReadStore=new ItemFileReadStore({
data:{
identifier: "value",
label: "label",
items: prepareData(changedStoreData)
}
});
selectWidget.set('store', newReadStore);
}
});
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css">
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/tundra/tundra.css">
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/form/resources/CheckedMultiSelect.css">
<div id="test" class="tundra">
<button id="btn">change data in select</button>
</div>
I'm trying to figure out a way to pull up a link to an attachment that a user story may have but I havent been able to figure out how. As I have it, the only thing I get in that column is "[object Object]" when a user story has an attachment.
There doesnt appear to be much out there on grabbing attachments, if anyone can shed any light or point me in the right direction, I'd surely appreciate it!
<html>
<head>
<title>Table</title>
<meta name="Name" content="App Example: Table" />
<meta name="Version" content="2010.4" />
<meta name="Vendor" content="Rally Software" />
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.24/sdk.js?loginKey=bignumber"></script>
<script type="text/javascript">
function tableExample() {
var rallyDataSource = new rally.sdk.data.RallyDataSource('12345', '12345', 'True', 'True');
function itemQuery() {
var queryObject = {
key: 'stories',
type: 'HierarchicalRequirement',
fetch: 'FormattedID,Name,ScheduleState,Description,Attachments',
query: '(Name contains "release")'
};
rallyDataSource.findAll(queryObject, populateTable);
}
function populateTable(results) {
var tableDiv = document.getElementById('aDiv');
var config = { columns:
[{key: 'FormattedID', header: 'Formatted ID', width: 100},
{key: 'Name', width: 400},
{key: 'ScheduleState', header: 'Schedule State', width: 200},
{key: 'Description', width: 800},
{key: 'Attachments', header: 'Attachment Link', width: 200}]};
var table = new rally.sdk.ui.Table(config);
table.addRows(results.stories);
table.display(tableDiv);
};
itemQuery();
}
rally.addOnLoad(tableExample);
</script>
</head>
<body>
<div id="aDiv"></div>
</body>
</html>
I'm including a slightly modified version of your App sample that does some post-processing to pull the Object ID of each attachment and drops it into some HTML links that are updated into the relevant table column.
<html>
<head>
<title>Table</title>
<meta name="Name" content="App Example: Stories with Attachments" />
<meta name="Version" content="2010.4" />
<meta name="Vendor" content="Rally Software" />
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.29/sdk.js"></script>
<script type="text/javascript">
var table = null;
function tableExample() {
var rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__',
'__PROJECT_OID__',
'__PROJECT_SCOPING_UP__',
'__PROJECT_SCOPING_DOWN__');
function itemQuery() {
var queryObject = {
key: 'stories',
type: 'HierarchicalRequirement',
fetch: 'FormattedID,Name,ScheduleState,Description,Attachments,ObjectID'
// query: '(Name contains "release")'
};
rallyDataSource.findAll(queryObject, populateTable);
}
function populateTable(results) {
if (table) {
table.destroy();
}
var tableDiv = document.getElementById('aDiv');
var config = { 'columnKeys' : ['FormattedID', 'Name', 'ScheduleState', 'Attachments'],
'columnHeaders' : ['FormattedID', 'Name', 'ScheduleState', 'Attachments'],
'columnWidths' : ['100px', '400px', '85px', '300px']
};
table = new rally.sdk.ui.Table(config);
table.addRows(results.stories);
for (i=0;i<results.stories.length;i++) {
myStory = results.stories[i];
myAttachments = results.stories[i].Attachments;
myAttachmentHTML = "";
for (j=0;j<myAttachments.length;j++) {
myAttachmentOID = myAttachments[j].ObjectID;
myAttachmentName = myAttachments[j].Name;
myAttachmentURL = "https://rally1.rallydev.com/slm/attachment/"+
myAttachmentOID + "/" + myAttachmentName;
myAttachmentHTML += "<div><a href='" + myAttachmentURL + "'>" +
myAttachmentName + "</a></div>";
}
table.setCell(i, 3, myAttachmentHTML);
}
table.display(tableDiv);
};
itemQuery();
}
rally.addOnLoad(tableExample);
</script>
</head>
<body>
<div id="aDiv"></div>
</body>
</html>