I have a grid of the which has actual time as one of its columns. How can I add the rows up to get the total actual time similar to the way it is done on the track team status page.
Edit:
I am currently trying to find the sum using this var sum = grid.getStore().sum('Actuals');, however when I run it, I get this error on the console:
Uncaught ReferenceError: grid is not defined
I have also tried using this piece of code that I found online:
var tasks = [];
var users = [];
that = this
if (data.length ===0) {
this._createGrid(); //to refresh grid when no items in iteration
}
Ext.Array.each(this.tasks, function(task) {
var owner = task.get('Owner');
var total;
Ext.Array.each(data, function(actual){
//some tasks have no owner. If this condition is not checked Uncaught TypeError: Cannot read property '_refObjectName' of null
if (owner && actual.get('User')._refObjectName === owner._refObjectName) {
total = actual.get('Actuals');
}
});
var t = {
FormattedID: task.get('FormattedID'),
_ref: task.get("_ref"),
Name: task.get('Name'),
Estimate: task.get('Actuals'),
Owner: (owner && owner._refObjectName) || 'None',
TaskEstimates: total
};
tasks.push(t);
});
},
but when I try to print total or taskestimate or attempt to find a specific part of tasks (tasks[i][j]) I either get no data or an error
See a not-treegrid code in this post for an example of how to create a row in a grid that sums up values in a specific column (e.g. Estimate)
columnCfgs: [
{
xtype: 'templatecolumn',text: 'ID',dataIndex: 'FormattedID',width: 100,
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'),
summaryRenderer: function() {
return "Estimate Total";
}
},
{
text: 'Estimate',dataIndex: 'Estimate',
summaryType: 'sum',
}
Related
I developed a SAPUI5 table on frontend having 4 columns, now I need to show the total sum of 1 column. If anyone knows the code related to this please help me
Controller code
onInit: function () {
var oTable = this.byId("producttable");
oTable.addStyleClass("myCustomTable");
//column list item creation
var oTemplate = new sap.m.ColumnListItem({
cells: [
new sap.m.Text({
text: "{Plant}"
}),
new sap.m.Text({
text: "{PlantDesc}"
}),
new sap.m.Text({
text: "{parts: [ {path: 'NetAmount'}, {path: 'currency'}],type: 'sap.ui.model.type.Currency',formatOptions: {showMeasure: false, maxFractionDigits: 0,roundingMode: 'away_from_zero'}}"
})
]
});
var sServiceUrl = "/sap/opu/odata/sap/ZSALES_PLANT001_SRV/";
//Adding service to the odata model
var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, false);
//Setting model to the table
oTable.setModel(oModel);
oTable.bindAggregation("items", {
path: "/ZSalesheaderSet",
template: oTemplate
});
I am getting the following errors in console
sap-ui-core.js:187 Assertion failed: could not find any translatable
text for key 'Total Sales-Yesterday' in bundle
'./i18n/i18n.properties' Failed to load resource: the server
responded with a status of 503 ()
getSum: function() {
var sum = 0, items = this.getView().byId("tableId").getItems();
for (var i = 0; i < items.length; i++) {
sum = sum + items[i].getBindingContext("urBoundModel").getObject().urColumn
}
return sum;
}
If you have bound the table to a Odata or JSON model. Just Iterate over your items and sum the bound property of the column.
I am using Extjs 4.2.1 and I ask myself a while how to put an edited and saved record on top of the grid after the save process has taken place. So the user can see the effect of the saved change.
I tried to put some code between the success callback method of the save method of the store. It looks like this:
store.save({
success : function(rec, op, success) {
var selectionModel = Ext.getCmp('grid').getSelectionModel();
var selection = selectionModel.getSelection();
selectionModel.select(selection);
billRecordStore.insert(0, selection);
billRecordStore.reload();
Ext.getCmp('grid').getView().refresh();
}
But i have no idea how to get the changed record on top of the table....
Any ideas and helpful posts are very welcome!
Thanks for your help in advance!
when I edit a record, I do not use the load() or reload() method.
I use only the sync () method.
This way the edited register remain highlighted in the grid.
Something like this:
var values = form.getValues();
var record = form.getRecord();
record.set(values);
var store = grid.getStore();
store.sync({
success: function(){...},
failure: function(){...}
});
When I create a new record, I have the grid records sorted so that the last inserted record is displayed on the first line.
So when it does the load (), or loadPage(1), is always selected the first row of the grid that corresponds to the last inserted record.
Edited 26/06/2015
var form = Ext.ComponentQuery.query('#formitemId')[0];
var grid = Ext.ComponentQuery.query('#griditemId')[0];
var values = form.getValues();
var record = form.getRecord();
record.set(values);
var store = grid.getStore();
store.sync({
callback: function(){
var record1 = grid.getSelectionModel().getLastSelected(record);
form.loadRecord(record1);
},
scope: this,
success: function(){
var windowInfoCNrecord = Ext.MessageBox.show({
title:'INFO',
msg: 'Success...',
closable: true,
modal: false,
iconCls: 'msg_success',
icon: Ext.MessageBox.INFO
});
},
failure: function(){
var windowInfoErrorEdit = Ext.Msg.alert({
title: 'Error',
message:'Error...!',
icon: Ext.Msg.ERROR,
button: Ext.Msg.CANCEL,
buttonText:{
cancel: 'Close'
},
});
}
}); //sync
I'm using Dojo GridX with many modules, including filter:
grid = new Grid({
cacheClass : Cache,
structure: structure,
store: store,
modules : [ Sort, ColumnResizer, Pagination, PaginationBar, CellWidget, GridEdit,
Filter, FilterBar, QuickFilter, HiddenColumns, HScroller ],
autoHeight : true, autoWidth: false,
paginationBarSizes: [25, 50, 100],
paginationBarPosition: 'top,bottom',
}, gridNode);
grid.filterBar.applyFilter({type: 'all', conditions: [
{colId: 'type', condition: 'equal', type: 'Text', value: 'car'}
]})
I've wanted to access the items, that are matching the filter that was set. I've travelled through grid property in DOM explorer, I've found many store references in many modules, but all of them contained all items.
Is it possible to find out what items are visible in grid because they are matching filter, or at least those that are visible on current page? If so, how to do that?
My solution is:
try {
var filterData = [];
var ids = grid.model._exts.clientFilter._ids;
for ( var i = 0; i < ids.length; ++i) {
var id = ids[i];
var item = grid.model.store.get(id);
filterData.push(item);
}
var store = new MemoryStore({
data : filterData
});
} catch (error) {
console.log("Filter is not set.");
}
I was able to obtain filtered gridX data rows using gridX Exporter. Add this Exporter module to your grid. This module does exports the filtered data. Then, convert CSV to Json. There are many CSV to Json conversion javasripts out there.
this.navResult.grid.exporter.toCSV(args).then(this.showResult, this.onError, null)
Based on AirG answer I have designed the following solution. Take into account that there are two cases, with or without filter and that you must be aware of the order of rows if you have applied some sort. At least this works for me.
var store = new Store({
idProperty: "idPeople", data: [
{ idPeople: 1, name: 'John', score: 130, city: 'New York', birthday: '31/02/1980' },
{ idPeople: 2, name: 'Alice', score: 123, city: 'WÃĄshington', birthday: '07/12/1984' },
{ idPeople: 3, name: 'Lee', score: 149, city: 'Shanghai', birthday: '8/10/1986' },
...
]
});
gridx = new GridX({
id: 'mygridx',
cacheClass: Cache,
store: store,
...
modules: [
...
{
moduleClass: Dod,
defaultShow: false,
useAnimation: true,
showExpando: true,
detailProvider: gridXDetailProvider
},
...
],
...
}, 'gridNode');
function gridXDetailProvider (grid, rowId, detailNode, rendered) {
gridXGetDetailContent(grid, rowId, detailNode);
rendered.callback();
return rendered;
}
function gridXGetDetailContent(grid, rowId, detailNode) {
if (grid.model._exts.clientFilter._ids === undefined || grid.model._exts.clientFilter._ids === 0) {
// No filter, with or without sort
detailNode.innerHTML = 'Hello ' + grid.row(grid.model._cache._priority.indexOf(rowId)).item().name + " with id " +
grid.row(grid.model._cache._priority.indexOf(rowId)).item().idPeople;
} else {
// With filter, with or without sort
detailNode.innerHTML = 'Hello ' + grid.row(grid.model._exts.clientFilter._ids.indexOf(rowId)).item().name + " with id " +
grid.row(grid.model._exts.clientFilter._ids.indexOf(rowId)).item().idPeople;
}
}
Hope that helps,
Santiago Horcajo
function getFilteredData() {
var filteredIds = grid.model._exts.clientFilter._ids;
return grid.store.data.filter(function(item) {
return filteredIds.indexOf(item.id) > -1;
});
}
On the front-end I have a Calls grid. Each Call may have one or more Notes associated with it, so I want to add the ability to drill down into each Calls grid row and display related Notes.
On the back-end I am using Ruby on Rails, and the Calls controller returns a Calls json recordset, with nested Notes in each row. This is done using to_json(:include => blah), in case you're wondering.
So the question is: how do I add a sub-grid (or just a div) that gets displayed when a user double-clicks or expands a row in the parent grid? How do I bind nested Notes data to it?
I found some answers out there that got me part of the way where I needed to go. Thanks to those who helped me take it from there.
I'll jump straight into posting code, without much explanation. Just keep in mind that my json recordset has nested Notes records. On the client it means that each Calls record has a nested notesStore, which contains the related Notes. Also, I'm only displaying one Notes column - content - for simplicity.
Ext.define('MyApp.view.calls.Grid', {
alias: 'widget.callsgrid',
extend: 'Ext.grid.Panel',
...
initComponent: function(){
var me = this;
...
var config = {
...
listeners: {
afterrender: function (grid) {
me.getView().on('expandbody',
function (rowNode, record, expandbody) {
var targetId = 'CallsGridRow-' + record.get('id');
if (Ext.getCmp(targetId + "_grid") == null) {
var notesGrid = Ext.create('Ext.grid.Panel', {
forceFit: true,
renderTo: targetId,
id: targetId + "_grid",
store: record.notesStore,
columns: [
{ text: 'Note', dataIndex: 'content', flex: 0 }
]
});
rowNode.grid = notesGrid;
notesGrid.getEl().swallowEvent(['mouseover', 'mousedown', 'click', 'dblclick', 'onRowFocus']);
notesGrid.fireEvent("bind", notesGrid, { id: record.get('id') });
}
});
}
},
...
};
Ext.apply(me, Ext.apply(me.initialConfig, config));
me.callParent(arguments);
},
plugins: [{
ptype: 'rowexpander',
pluginId: 'abc',
rowBodyTpl: [
'<div id="CallsGridRow-{id}" ></div>'
]
}]
});
I would like to start by saying I have read Rally Kanban - hiding Epic Stories but I'm still having trouble on implementing my filter based on the filter process from the Estimation Board app. Currently I'm trying to add an items filter to my query object for my cardboard. The query object calls this._getItems to return an array of items to filter from. As far as I can tell the query calls the function, loads for a second or two, and then displays no results. Any input, suggestions, or alternative solutions are welcomed.
Here's my code
$that._redisplayBoard = function() {
that._getAndStorePrefData(displayBoard);
this._getItems = function(callback) {
//Build types based on checkbox selections
var queries = [];
queries.push({key:"HierarchicalRequirement",
type: "HierarchicalRequirement",
fetch: "Name,FormattedID,Owner,ObjectID,Rank,PlanEstimate,Children,Ready,Blocked",
order: "Rank"
});
function bucketItems(results) {
var items = [];
rally.forEach(queries, function(query) {
if (results[query.key]) {
rally.forEach(results[query.key], function(item) {
//exclude epic stories since estimates cannot be altered
if ((item._type !== 'HierarchicalRequirement') ||
(item._type === 'HierarchicalRequirement' && item.Children.length === 0)) {
items = items.concat(item);
}
});
}
});
callback(items);
}
rallyDataSource.findAll(queries, bucketItems);
};
function displayBoard() {
artifactTypes = [];
var cardboardConfig = {
types: [],
items: that._getItems,
attribute: kanbanField,
sortAscending: true,
maxCardsPerColumn: 200,
order: "Rank",
cardRenderer: KanbanCardRenderer,
cardOptions: {
showTaskCompletion: showTaskCompletion,
showAgeAfter: showAgeAfter
},
columnRenderer: KanbanColumnRenderer,
columns: columns,
fetch: "Name,FormattedID,Owner,ObjectID,Rank,Ready,Blocked,LastUpdateDate,Tags,State,Priority,StoryType,Children"
};
if (showTaskCompletion) {
cardboardConfig.fetch += ",Tasks";
}
if (hideLastColumnIfReleased) {
cardboardConfig.query = new rally.sdk.util.Query("Release = null").or(kanbanField + " != " + '"' + lastState + '"');
}
if (filterByTagsDropdown && filterByTagsDropdown.getDisplayedValue()) {
cardboardConfig.cardOptions.filterBy = { field: FILTER_FIELD, value: filterByTagsDropdown.getDisplayedValue() };
}
cardboardConfig.types.push("HierarchicalRequirement");
if (cardboard) {
cardboard.destroy();
}
artifactTypes = cardboardConfig.types;
cardboard = new rally.sdk.ui.CardBoard(cardboardConfig, rallyDataSource);
cardboard.addEventListener("preUpdate", that._onBeforeItemUpdated);
cardboard.addEventListener("onDataRetrieved", function(cardboard,args){ console.log(args.items); });
cardboard.display("kanbanBoard");
}
};
that.display = function(element) {
//Build app layout
this._createLayout(element);
//Redisplay the board
this._redisplayBoard();
};
};
Per Charles' hint in Rally Kanban - hiding Epic Stories
Here's how I approached this following Charles' hint for the Rally Catalog Kanban. First, modify the fetch statement inside the cardboardConfig so that it includes the Children collection, thusly:
fetch: "Name,FormattedID,Children,Owner,ObjectID,Rank,Ready,Blocked,LastUpdateDate,Tags,State"
Next, in between this statement:
cardboard.addEventListener("preUpdate", that._onBeforeItemUpdated);
And this statement:
cardboard.display("kanbanBoard");
Add the following event listener and callback:
cardboard.addEventListener("onDataRetrieved",
function(cardboard, args){
// Grab items hash
filteredItems = args.items;
// loop through hash keys (states)
for (var key in filteredItems) {
// Grab the workproducts objects (Stories, defects)
workproducts = filteredItems[key];
// Array to hold filtered results, childless work products
childlessWorkProducts = new Array();
// loop through 'em and filter for the childless
for (i=0;i<workproducts.length;i++) {
thisWorkProduct = workproducts[i];
// Check first if it's a User Story, since Defects don't have children
if (thisWorkProduct._type == "HierarchicalRequirement") {
if (thisWorkProduct.Children.length === 0 ) {
childlessWorkProducts.push(thisWorkProduct);
}
} else {
// If it's a Defect, it has no children so push it
childlessWorkProducts.push(thisWorkProduct);
}
}
filteredItems[key] = childlessWorkProducts;
}
// un-necessary call to cardboard.setItems() was here - removed
}
);
This callback should filter for only leaf-node items.
Mark's answer caused an obscure crash when cardboard.setItems(filteredItems) was called. However, since the filtering code is actually manipulating the actual references, it turns out that setItems() method is actually not needed. I pulled it out, and it now filters properly.
Not sure this is your problem but your cardboard config does not set the 'query' field. The fetch is the type of all data to retrieve if you want to filter it you add a "query:" value to the config object.
Something like :
var cardboardConfig = {
types: ["PortfolioItem", "HierarchicalRequirement", "Feature"],
attribute: dropdownAttribute,
fetch:"Name,FormattedID,Owner,ObjectID,ClassofService",
query : fullQuery,
cardRenderer: PriorityCardRenderer
};
Where fullQuery can be constructed using the the Rally query object. You find it by searching in the SDK. Hope that maybe helps.