Rally Cumulative Flow Diagram with Points - rally

I'm looking to try and do a cumulative flow diagram by story points in rally with their newer API/SDK and found some sample code on their GitHub page RallyAnalytics GitHub
So after some work I have it working to some degree but don't understand or can find any documentation for how to configure this more. It looks like the report being generated is doing count and not the PlanEstimate which I tried to add in fieldsToSum. How can I get it to sum the PlanEstimate field by c_KanbanState and not just give me a count of stories that matched the c_KanbanState for that week? Sample code below minus the minified code from GitHub.
var userConfig = {
title: 'Cumulative Flow Diagram',
debug: false,
trace: false,
// asOf: "2012-11-01", // Optional. Only supply if want a specific time frame. Do not send in new Date().toISOString().
granularity: 'week',
fieldsToSum: ['PlanEstimate'],
scopeField: "Project", // Supports Iteration, Release, Tags, Project, _ProjectHierarchy, _ItemHierarchy
scopeValue: 'scope',
scopeData: {
StartDate: new Date("2012-12-01T07:00:00.000Z"),
EndDate: new Date(new Date()),
Name: ""
},
//fieldNames: ['count', 'PlanEstimate']
kanbanStateField: 'c_KanbanState',
chartSeries: [
{name: 'To Do'},
{name: 'Dev Ready'},
{name: 'In Dev'},
{name: 'Peer Review'},
{name: 'QA Ready'},
{name: 'QA Done'},
{name: 'Accepted'}
]
}
(function() {
var charts = {};
var visualizer;
var nameToDisplayNameMap;
createVisualization = function(visualizationData) {
if (typeof visualizationData !== "undefined" && visualizationData !== null) {
categories = visualizationData.categories;
series = visualizationData.series;
charts.lowestValueInLastState = visualizationData.lowestValueInLastState;
charts.chart = new Highcharts.Chart({
chart: {
renderTo: 'chart-container',
defaultSeriesType: 'column',
zoomType: 'x'
},
legend: {
enabled: true
},
credits: {
enabled: false
},
title: {
text: userConfig.title
},
subtitle: {
text: userConfig.scopeData.Name
},
xAxis: {
categories: categories,
tickmarkPlacement: 'on',
tickInterval: Math.floor(categories.length / 12) + 1,
title: {
text: userConfig.granularity.slice(0, 1).toUpperCase() + userConfig.granularity.slice(1) + 's'
}
},
yAxis: [
{
title: {
text: 'Total Points',
},
min: charts.lowestValueInLastState
}
],
tooltip: {
formatter: function() {
point = this.point
s = point.series.name + ': <b>' + point.y + '</b><br \>';
if (point.x == point.series.data.length - 1) {
s += point.category.slice(0, point.category.length - 1) + ' to-date';
} else {
s += point.category;
}
return s;
}
},
plotOptions: {
series: {
events: {
legendItemClick: function(event) {
if (this.chart.series.length == this.index + 1) {
if (!this.visible) {
this.chart.yAxis[0].setExtremes(charts.lowestValueInLastState);
} else {
this.chart.yAxis[0].setExtremes(0);
};
};
return true;
}
}
}
},
series: series
}); // end of chart
} else {
// Put a spinner in the chart containers until first fetch returns
$('#chart-container')
.html('<img height="20px" src="https://rally1.rallydev.com/slm/js-lib/ext/2.2/resources/images/default/grid/loading.gif"></img>')
.attr("style", "text-align:center");
};
};
$(document).ready(function() {
visualizer = new CFDVisualizer(charts, userConfig, createVisualization);
});
})();

You may be using a slightly older version because the latest doesn't have the fieldsToSum parameter in the config, but you can upgrade the chart to sum PlanEstimate by chaging a few lines in the CFDVisualizer.coffee to this:
#config.lumenizeCalculatorConfig.metrics = [
{f: 'groupBySum', field: 'PlanEstimate', groupByField: #config.kanbanStateField, allowedValues: allowedValues}
]
from:
#config.lumenizeCalculatorConfig.metrics = [
{f: 'groupByCount', groupByField: #config.kanbanStateField, allowedValues: allowedValues}
]
You should probably also change the axis label in the cfd.html.
If this proves too difficult to accomplish (CoffeeScript may be unfamiliar), let me know and I'll post a new version to GitHub.

Related

Vue computed property functions are never called

I trying to do my own Google Science Journal, but web version with MQTT protocol, but my code have so many bugs.
Some clarification about my code:
google.charts.load is calling in the parent component, then callback make a call for the child component
time props is an interval, change between true and false every second for collect data.
I need to watch changes of a data with multiple dependencies.
How my code works?
When a new instance is created, appear an empty google chart
The chart start to show data every second.
The tittle for the chart change when a new tab is selected and the chart data is erased.
This code has a problem, is the order in which the functions are called (generate some problems with google chart), but I fixed it, moving functions from computed to methods and calling in order.
I just want to know why this computed functions don't work, I mean, they aren't never call.
<template>
<v-card>
<v-tabs
v-model="active_tab"
background-color="red lighten-2"
dark
show-arrows
>
<v-tab
v-for="(n) in tabs"
:key="n.id"
>
{{n.text}}
<v-icon>{{n.icon}}</v-icon>
</v-tab>
</v-tabs>
<div ref="char_div"></div>
</v-card>
</template>
<script>
import debounce from 'debounce'
export default {
name: 'charts',
props:{
time: {
type: Boolean,
default: false
}
},
data(){
return {
chart: null,
options: null,
value: 0,
previus: null,
data: null,
tabs: [
{id: 0, text: "Aceleración lineal", unit: "(m/s²)", icon: ""},
{id: 1, text: "Aceleración en x", unit: "(m/s²)", icon: ""},
{id: 2, text: "Aceleración en y", unit: "(m/s²)", icon: ""},
{id: 3, text: "Aceleración en z", unit: "(m/s²)", icon: ""},
{id: 4, text: "Velocidad lineal", unit: "(m/s)", icon: ""},
{id: 5, text: "Luz ambiental", unit: "(lux)", icon: ""},
{id: 6, text: "Intensidad sonora", unit: "(dB)", icon: ""},
{id: 7, text: "Tono", unit: "(Hz)", icon: ""},
{id: 8, text: "Barómetro", unit: "(hPa)", icon: ""},
{id: 9, text: "Brujula", unit: "grados", icon: ""},
{id: 10, text: "Magnetómetro", unit: "µT", icon: ""},
{id: 11, text: "Humedad", unit: "%", icon: ""},
{id: 12, text: "Temperatura ambiente", unit: "°C", icon: ""}
],
active_tab: 0
}
},
computed: {
newData: function(){
switch (this.active_tab) {
case 0:
this.value = Math.sqrt(this.$state.lin_acel.x^2 + this.$state.lin_acel.y^2 + this.$state.lin_acel.z^2)
break
case 1:
this.value = this.$state.lin_acel.x
break
case 2:
this.value = this.$state.lin_acel.y
break
case 3:
this.value = this.$state.lin_acel.z
break
case 4:
if (this.previus != null){
//var cons = Math.sqrt(this.$state.lin_acel.x^2 + this.$state.lin_acel.y^2 + this.$state.lin_acel.z^2)
var ax = this.$state.lin_acel.x,
ay = this.$state.lin_acel.y,
az = this.$state.lin_acel.z
var nuevo = Date.now()
var vx = ax * ((nuevo - this.previus)/1000),
vy = ay * ((nuevo - this.previus)/1000),
vz = az * ((nuevo - this.previus)/1000)
//this.value += (cons)*((nuevo - this.previus)/1000)
this.value += Math.sqrt(vx^2 + vy^2 + vz^2)
this.previus = nuevo
}else{
this.value = Math.sqrt(this.$state.lin_acel.x^2 + this.$state.lin_acel.y^2 + this.$state.lin_acel.z^2)
this.previus = Date.now()
}
case 5:
this.value = this.$state.lux
break
case 6:
this.value = this.$state.noise
break
case 7:
this.value = this.$state.noise
break
case 8:
this.value = this.$state.presion
break
case 9:
var vector = Math.sqrt(this.$state.magneto.x^2 + this.$state.magneto.y^2 + this.$state.magneto.z^2)
break
case 10:
this.value = Math.sqrt(this.$state.magneto.x^2 + this.$state.magneto.y^2 + this.$state.magneto.z^2)
break
default:
this.value = 0
break
}
},
newOptions(){
console.log("new options")
this.options = {
tittle: this.tabs[this.active_tab].text,
crosshair: {orientation: 'vertical', trigger: 'both'},
legend: 'none',
hAxis: {
format:'mm:ss'
}
}
},
drawchart(){
console.log("chart is drawing")
this.chart.draw(this.data, google.charts.Line.convertOptions(this.options));
},
},
watch: {
time: {
immediate: false,
handler(){
this.addData()
}
},
active_tab: {
inmediate: false,
handler(){
this.updatetable()
}
}
},
methods: {
addData(){
this.data.addRows([[new Date(Date.now()),0]])
},
updatetable(){
this.data = null
this.data = new google.visualization.DataTable(
{cols:
[{label: 'tiempo', id: 'x', type: 'date'},
{label: String(this.tabs[this.active_tab].text), id: 'y', type: 'number'}]})
}
},
mounted() {
this.chart = new google.charts.Line(this.$refs.char_div)
this.newOptions
this.updatetable()
this.drawchart
}
}
</script>
<style>
</style>
As Phil says, "Computed property functions are not meant to alter any data properties and are supposed to return a value". Is because computed watchs changes only in return, for example:
//Computed watch this
return this.a + this.b
//{...}
//Not this
this.c = this.a + this.b
I found here and in Vue forums ways to improve this code:
If you need to watch a data with multiple dependencies, you can do the next:
computed: {
multi(){
return [this.a, this.b].join()
}
},
watch: {
multi: {
handler(): {
this.c = this.a + this.b
}
}
}
I thing the best I can find solution was:
created(){
this.$watch(
(this) => (vm.x, vm.y, vm.z, Date.now()),
function () {
// Executes if `x`, `y`, or `z` have changed.
}
)
}
This last also return the function unwatch(), it stop the watcher property, if I do this.watcher = this.$watch(/*data and callback here*/), then I can do this.watcher() stop watcher and make new one, perfect for improve performance of this code.

In Rally, when copying a test set, how do you copy the test case results with the test set?

I'm fairly new to Rally and so far have only used the web interface (I haven't used the Rally APIs from a programming languages yet). Occasionally we have a test set that we don't finish in an iteration, so we'd like to be able to copy the test set to the next iteration but retain the test case results entered so far in the new iteration so that we don't have to look in 2 different places for the complete test set results. Perhaps one solution is better iteration planning, but I'm still curious if there's a way to copy test case results along with a test set when copying a test set.
Test Case Result cannot be copied. It can be created in UI or Web Services API with the identical data, but it does not support a copy functionality.
For a general example of how to create a TCR object using a browser REST client see this SO post here.
Here is a poof of concept app that creates a copy of an existing TCR. The app filters TestSets by Iteration, and loads those TestSets into a combobox. Based on the TestSet selection in the combobox another combobox is created, populated with TestCases. When a Test Case is selected from that combobox a grid is built with TestCaseResults. Doubleclicking on a TCR in the grid will invoke a copy function. See AppSDK2 topic on how to copy records here. You may extend the code per your specifications. The source is in this github repo.
Minimally you need to change ObjectIDs of destination test case and destination test set in _copyRecordOnDoubleClick method below:
Ext.define('CustomApp', {
extend: 'Rally.app.TimeboxScopedApp',
componentCls: 'app',
scopeType: 'iteration',
comboboxConfig: {
fieldLabel: 'Select an Iteration:',
labelWidth: 100,
width: 300
},
onScopeChange: function() {
if (this.down('#testSetComboxBox')) {
this.down('#testSetComboxBox').destroy();
}
if (this.down('#testCaseComboxBox')) {
this.down('#testCaseComboxBox').destroy();
}
if (this.down('#resultsGrid')) {
this.down('#resultsGrid').destroy();
}
var testSetComboxBox = Ext.create('Rally.ui.combobox.ComboBox',{
id: 'testSetComboxBox',
storeConfig: {
model: 'TestSet',
pageSize: 100,
autoLoad: true,
filters: [this.getContext().getTimeboxScope().getQueryFilter()]
},
fieldLabel: 'select TestSet',
listeners:{
ready: function(combobox){
if (combobox.getRecord()) {
this._onTestSetSelected(combobox.getRecord());
}
else{
console.log('selected iteration has no testsets');
}
},
select: function(combobox){
if (combobox.getRecord()) {
this._onTestSetSelected(combobox.getRecord());
}
},
scope: this
}
});
this.add(testSetComboxBox);
},
_onTestSetSelected:function(selectedTestset){
var testCases = selectedTestset.getCollection('TestCases', {fetch: ['FormattedID','ObjectID', 'Results']});
var ts = {
FormattedID: selectedTestset.get('FormattedID'),
TestCaseCount: selectedTestset.get('TestCases').Count,
TestCases: [],
ResultCount: 0
};
testCases.load({
callback: function(records, operation, success){
Ext.Array.each(records, function(testcase){
console.log("testcase.get('FormattedID')", testcase.get('FormattedID'));
console.log("testcase.get('Results').Count", testcase.get('Results').Count);
ts.ResultCount = testcase.get('Results').Count;
ts.TestCases.push({_ref: testcase.get('_ref'),
FormattedID: testcase.get('FormattedID'),
ObjectID: testcase.get('ObjectID')
});
}, this);
this._makeTestCaseCombobox(ts.TestCases);
},
scope: this
});
},
_makeTestCaseCombobox:function(testcases){
if (this.down('#testCaseComboxBox')) {
this.down('#testCaseComboxBox').destroy();
}
if (this.down('#resultsGrid')) {
this.down('#resultsGrid').destroy();
}
if (testcases.length>0) {
var idArray = [];
_.each(testcases, function(testcase){
console.log(testcase);
console.log('OID', testcase['ObjectID']);
idArray.push(testcase['ObjectID']);
});
console.log('idArray',idArray);
var filterArray = [];
_.each(idArray, function(id){
filterArray.push(
{
property: 'ObjectID',
value:id
}
)
});
var filters = Ext.create('Rally.data.QueryFilter', filterArray[0]);
filterArray = _.rest(filterArray,1);
_.each(filterArray, function(filter){
filters = filters.or(filter)
},1);
var testCaseComboxBox = Ext.create('Rally.ui.combobox.ComboBox',{
id: 'testCaseComboxBox',
storeConfig: {
model: 'TestCase',
pageSize: 100,
autoLoad: true,
filters:filters,
fetch: true
},
fieldLabel: 'select TestCase',
listeners:{
ready: function(combobox){
if (combobox.getRecord()) {
this._onTestCaseSelected(combobox.getRecord());
}
else{
console.log('selected testset has no testcases');
}
},
select: function(combobox){
if (combobox.getRecord()) {
this._onTestCaseSelected(combobox.getRecord());
}
},
scope: this
}
});
this.add(testCaseComboxBox);
}
else{
console.log('selected testset has no testcases');
}
},
_onTestCaseSelected:function(selectedTestcase){
var results = selectedTestcase.getCollection('Results', {fetch: ['ObjectID','Date', 'TestSet', 'TestCase', 'Build', 'Verdict']});
var tc = {
ObjectID: selectedTestcase.get('ObjectID'),
FormattedID: selectedTestcase.get('FormattedID'),
Results: []
};
results.load({
callback: function(records, operation, success){
Ext.Array.each(records, function(result){
console.log("result.get('ObjectID')", result.get('ObjectID'));
console.log("result.get('Verdict')", result.get('Verdict'));
tc.Results.push({_ref: result.get('_ref'),
ObjectID: result.get('ObjectID'),
Date: result.get('Date'),
Build: result.get('Build'),
Verdict: result.get('Verdict')
});
}, this);
this._updateGrid(tc.Results);
},
scope: this
});
},
_updateGrid: function(results){
var store = Ext.create('Rally.data.custom.Store', {
data: results,
pageSize: 100
});
if (!this.down('#resultsGrid')) {
this._createGrid(store);
}
else{
this.down('#resultsGrid').reconfigure(store);
}
},
_createGrid: function(store){
var that = this;
var that = this;
var resultsGrid = Ext.create('Rally.ui.grid.Grid', {
id: 'resultsGrid',
store: store,
columnCfgs: [
{
text: 'ObjectID ID', dataIndex: 'ObjectID',
},
{
text: 'Date', dataIndex: 'Date',
},
{
text: 'Build', dataIndex: 'Build',
},
{
text: 'Verdict', dataIndex: 'Verdict',
},
],
listeners: {
celldblclick: function( grid, td, cellIndex, record, tr, rowIndex){
that._copyRecordOnDoubleClick(record);
}
}
});
this.add(resultsGrid);
},
_copyRecordOnDoubleClick: function(record){
var that = this;
console.log('record', record);
Rally.data.ModelFactory.getModel({
type: 'TestCaseResult',
success: function(model) {
that._model = model;
var copy = Ext.create(model, {
Date: record.get('Date'),
Build: record.get('Build'),
Verdict: record.get('Verdict'),
TestCase: '/testcase/17237838118',
TestSet: '/testset/17234968911'
});
copy.save({
callback: function(result, operation) {
if(operation.wasSuccessful()) {
console.log('result',result);
}
else{
console.log("problem");
}
}
});
}
});
}
});

ExtJs 4: How do I create a dynamic menu?

I have a menu system set up in a panel which needs to be dynamically created. I have created a mock static menu which the client likes but the menu categories and items will need to be loaded via JSON from a store.
Here is what I have for the first few menu items set statically:
Ext.define('SimpleSearch.view.FacetSDL' ,{
extend: 'Ext.panel.Panel',
alias : 'widget.facetsdl', //alias is referenced in MasterList.js
requires: ['SimpleSearch.store.SDLResults', 'FacetData' ],
title: 'Facet Search',
html: null,
frame: true,
layouts: 'fit',
items: [
{
id: 'group-menu',
title: 'Browse',
xtype: 'menu',
plain: true,
floating: false,
layouts: 'fit',
items: [
{
text: 'Security',
listeners:
{
click: function() {
var groupmenu = Ext.ComponentQuery.query('#group-menu')[0];
groupmenu.hide()
var securitymenu = Ext.ComponentQuery.query('#security-menu')[0];
securitymenu.setPosition(0,-groupmenu.getHeight(),false);
securitymenu.show()
}
},
menu: { // <-- submenu by nested config object
items: [
{
text: 'Classification',
listeners:
{
click: function() {
var groupmenu = Ext.ComponentQuery.query('#group-menu')[0];
groupmenu.hide()
var securitymenu = Ext.ComponentQuery.query('#security-menu')[0];
var classificationmenu = Ext.ComponentQuery.query('#classification-menu')[0];
classificationmenu.setPosition(0,-groupmenu.getHeight() - securitymenu.getHeight(),false);
classificationmenu.show()
}
I was thinking that maybe creating a class that loads all of the necessary data and then iterating through that class for the "items" field may be the way to go, but I am not sure if that will work.
You should look at using a Tree and TreeStore. Then make use of the ui:'menu' or viewConfig { ui: 'menu' } config properties to differentiate it from a regular tree. Then style it however your client wants.
This way you have all the mechanisms in place for free to handle the data dynamically and all your submenus, you'll just have to get a little creative on the CSS side of things.
I got it working like this:
var scrollMenu = Ext.create('Ext.menu.Menu');
for (var i = 0; i < store.getCount(); ++i){
var rec = store.getAt(i);
var item = new Ext.menu.Item({
text: rec.data.DISPLAY_FIELD,
value:rec.data.VALUE_FIELD,
icon: 'js/images/add.png',
handler: function(item){
myFunction(item.value); //Handle the item click
}
});
scrollMenu.add(item);
}
Then just add scrollMenu to your form or container. Hope this helps!
This menu is created dynamically with ExtJs, the data is loaded from Json.
See my demo with the code.
Demo Online:
https://fiddle.sencha.com/#view/editor&fiddle/2vcq
Json loaded:
https://api.myjson.com/bins/1d9tdd
Code ExtJs:
//Description: ExtJs - Create a dynamical menu from JSON
//Autor: Ronny Morán <ronney41#gmail.com>
Ext.application({
name : 'Fiddle',
launch : function() {
var formPanelFMBtn = Ext.create('Ext.form.Panel', {
bodyPadding: 2,
waitMsgTarget: true,
fieldDefaults: {
labelAlign: 'left',
labelWidth: 85,
msgTarget: 'side'
},
items: [
{
xtype: 'container',
layout: 'hbox',
items: [
]
}
]
});
var win = Ext.create('Ext.window.Window', {
title: 'EXTJS DYNAMICAL MENU FROM JSON',
modal: true,
width: 680,
closable: true,
layout: 'fit',
items: [formPanelFMBtn]
}).show();
//Consuming JSON from URL using method GET
Ext.Ajax.request({
url: 'https://api.myjson.com/bins/1d9tdd',
method: 'get',
timeout: 400000,
headers: { 'Content-Type': 'application/json' },
//params : Ext.JSON.encode(dataJsonRequest),
success: function(conn, response, options, eOpts) {
var result = Ext.JSON.decode(conn.responseText);
//passing JSON data in 'result'
viewMenuDinamical(formPanelFMBtn,result);
},
failure: function(conn, response, options, eOpts) {
//Ext.Msg.alert(titleAlerta,msgErrorGetFin);
}
});
}
});
//Generate dynamical menu with data from JSON
//Params: formPanelFMBtn - > Panel
// result - > Json data
function viewMenuDinamical(formPanelFMBtn,result){
var resultFinTarea = result;
var arrayCategoriaTareas = resultFinTarea.categoriaTareas;
var containerFinTarea = Ext.create('Ext.form.FieldSet', {
xtype: 'fieldset',
title: 'Menu:',
margins:'0 0 5 0',
flex:1,
layout: 'anchor',
//autoHeight: true,
autoScroll: true,
height: 200,
align: 'stretch',
items: [
]
});
var arrayMenu1 = [];
//LEVEL 1
for(var i = 0; i < arrayCategoriaTareas.length; i++)
{
var categoriaPadre = arrayCategoriaTareas[i];
var nombrePadre = categoriaPadre.nombreCategoria;
var hijosPadre = categoriaPadre.hijosCategoria;
var arrayMenu2 = [];
//LEVEL 2
for(var j = 0; j<hijosPadre.length; j++)
{
var categoriaHijo = hijosPadre[j];
var nombreHijo = categoriaHijo.nombreHijo;
var listaTareas = categoriaHijo.listaTareas;
var arrayMenu3 = [];
//LEVEL 3
for(var k = 0; k < listaTareas.length; k++)
{
var tarea = listaTareas[k];
var nombreTarea = tarea.nombreTarea;
var objFinLTres =
{
text: nombreTarea,
handler: function () {
alert("CLICK XD");
}
};
arrayMenu3.push(objFinLTres);
}
var menuLevel3 = Ext.create('Ext.menu.Menu', {
items: arrayMenu3
});
var objFinLDos;
if(arrayMenu3.length > 0)
{
objFinLDos = {
text: nombreHijo,
menu:menuLevel3
};
}
else
{
//without menu parameter If don't have children
objFinLDos = {
text: nombreHijo
};
}
arrayMenu2.push(objFinLDos);
}
var menuLevel2 = Ext.create('Ext.menu.Menu', {
items: arrayMenu2
});
var objFinLUno;
if(arrayMenu2.length > 0)
{
objFinLUno = {
text: nombrePadre,
menu:menuLevel2
};
}
else
{
//without menu parameter If don't have children
objFinLUno = {
text: nombrePadre
};
}
arrayMenu1.push(objFinLUno);
}
var mymenu = new Ext.menu.Menu({
items: arrayMenu1
});
containerFinTarea.add({
xtype: 'splitbutton',
text: 'Example xD',
menu: mymenu
});
formPanelFMBtn.add(containerFinTarea);
}

ExtJs3.4.0 to ExtJs4.1.1 upgrade issues

ExtJS4: I am having problems while upgrading my application ExtJs version from 3.4.0 to 4.1.1a.
My 3.4.0 version code:
this.jsonStore = new Ext.data.JsonStore({
proxy : new Ext.data.HttpProxy({
url: 'rs/environments',
disableCaching: true
}),
restful : true,
storeId : 'Environments',
idProperty: 'env',
fields : [
'ConnectionName', 'Type'
]
});
this.colmodel = new Ext.grid.ColumnModel({
defaults: {
align: 'center'
},
columns: [{
header: Accero.Locale.text.adminlogin.connectionsHeading,
width : 140,
dataIndex: 'ConnectionName'
},
{
header: Accero.Locale.text.adminlogin.connectionTypeHeader,
width : 120,
dataIndex: 'Type'
}]
});
config = Ext.apply({
enableHdMenu: false,
border : true,
stripeRows : true,
store : this.jsonStore,
view : new Ext.grid.GridView(),
header : false,
colModel : this.colmodel,
sm : new Ext.grid.RowSelectionModel({singleSelect: true}),
loadMask: {
msg: Accero.Locale.text.adminlogin.loadingmask
}
}, config);
I made below changes to make application work with ExtJs4.1.1:
var sm = new Ext.selection.CheckboxModel( {
listeners:{
selectionchange: function(selectionModel, selected, options){
// Must refresh the view after every selection
myGrid.getView().refresh();
// other code for this listener
}
}
});
var getSelectedSumFn = function(column){
return function(){
var records = myGrid.getSelectionModel().getSelection(),
result = 0;
Ext.each(records, function(record){
result += record.get(column) * 1;
});
return result;
};
}
var config = Ext.create('Ext.grid.Panel', {
autoScroll:true,
features: [{
ftype: 'summary'
}],
store: this.jsonStore,
defaults: { // defaults are applied to items, not the container
sortable:true
},
selModel: sm,
columns: [
{header: Accero.Locale.text.adminlogin.connectionsHeading, width: 140, dataIndex: 'ConnectionName'},
{header: Accero.Locale.text.adminlogin.connectionTypeHeader, width: 120, dataIndex: 'Type'}
],
loadMask: {
msg: Accero.Locale.text.adminlogin.loadingmask
},
viewConfig: {
stripeRows: true
}
}, config);
With these changes, I am getting the error at my local file 'ext-override.js' saying 'this.el is not defined'.
I debug the code and found that, in the current object this, there is no el object.
ext-override.js code:
(function() {
var originalInitValue = Ext.form.TextField.prototype.initValue;
Ext.override(Ext.form.TextField, {
initValue: function() {
originalInitValue.apply( this, arguments );
if (!isNaN(this.maxLength) && (this.maxLength *1) > 0 && (this.maxLength != Number.MAX_VALUE)) {
this.el.dom.maxLength = this.maxLength *1;
}
}
}
);
})();
Kindly suggest where am I going wrong?
Thanks in advance...
Seriously, use more lazy initialization! Your code is a hell of objects, all unstructured.
First of all, you can override and use the overridden method more easily with something like that (since 4.1)
Ext.override('My.Override.for.TextField', {
override : 'Ext.form.TextField',
initValue: function() {
this.callOverridden(arguments);
if (!isNaN(this.maxLength) && (this.maxLength *1) > 0 && (this.maxLength != Number.MAX_VALUE)) {
this.el.dom.maxLength = this.maxLength *1;
}
}
});
But: The method initValue is called in initField (and this in initComponent) so that you cannot have a reference to this.me because the component is actually not (fully) rendered.
So, this should help (not tested):
Ext.override('My.Override.for.TextField', {
override : 'Ext.form.TextField',
afterRender: function() {
this.callOverridden(arguments);
if (!isNaN(this.maxLength) && (this.maxLength *1) > 0 && (this.maxLength != Number.MAX_VALUE)) {
this.el.dom.maxLength = this.maxLength *1;
}
}
});
But I'm strongly recommend not to use such things within overrides. Make dedicated components which will improve code readibility.

how to set variable value from the server response extjs 4

forum member I am having one problem in setting the value of my view from the server response I am receiving
I am using the MVC architechture of the extjs 4. My store is loaded perfectly and my taskstore is defined as below
Ext.define('gantt.store.taskStore', {
extend: 'Gnt.data.TaskStore',
model: 'gantt.model.ResourceTask',
storeId: 'taskStore',
autoLoad : true,
autoSync : true,
proxy : {
type : 'ajax',
api: {
read: 'task/GetTask.action',
create: 'task/CreateTask.action',
destroy: 'task/DeleteTask.action',
update: 'task/UpdateTask.action'
},
writer : new Ext.data.JsonWriter({
//type : 'json',
root : 'taskdata',
encode : true,
writeAllFields : true
}),
reader : new Ext.data.JsonReader({
totalPropery: 'total',
successProperty : 'success',
idProperty : 'id',
type : 'json',
root: function (o) {
if (o.taskdata) {
return o.taskdata;
} else {
return o.children;
}
}
})
}
});
but what I want to do is that as soon as the store loaded I want to assign the server response data to one of the variable in my javascript.
I tried to add the value from the beforeload function of view, but not able to do so.
my view code is given as below
var result = Ext.JSON.decode('{"calendardata": [{"startdate": 1330281000000,"enddate": 1330284600000,"id": 3,"title": "mon"}],"total": 1,"success": true}');
//var start = new Date(2012, 2, 26),
//end = Sch.util.Date.add(start, Sch.util.Date.MONTH, 30);
var start_d = new Date(result.calendardata[0].startdate);
var end_d = new Date(result.calendardata[0].enddate);
var start = new Date(start_d.getFullYear(), start_d.getMonth(), start_d.getDate());
end = Sch.util.Date.add(start, Sch.util.Date.MONTH, 30);
console.log("YEAR ::"+start.getFullYear()+"MONTH ::"+start.getMonth()+"DAY ::"+start.getDate());
console.log("YEAR ::"+end.getFullYear()+"MONTH ::"+end.getMonth()+"DAY ::"+end.getDate());
//create the downloadframe at the init of your app
this.downloadFrame = Ext.getBody().createChild({
tag: 'iframe'
, cls: 'x-hidden'
, id: 'iframe'
, name: 'iframe'
});
//create the downloadform at the init of your app
this.downloadForm = Ext.getBody().createChild({
tag: 'form'
, cls: 'x-hidden'
, id: 'form'
, target: 'iframe'
});
var printableMilestoneTpl = new Gnt.template.Milestone({
prefix : 'foo',
printable : true,
imgSrc : 'resources/images/milestone.png'
});
var params = new Object();
Ext.define('gantt.view.projectmgt.projectGanttpanel', {
extend: "Gnt.panel.Gantt",
id: 'projectganttpanel',
alias: 'widget.projectganttpanel',
requires: [
'Gnt.plugin.TaskContextMenu',
'Gnt.column.StartDate',
'Gnt.column.EndDate',
'Gnt.column.Duration',
'Gnt.column.PercentDone',
'Gnt.column.ResourceAssignment',
'Sch.plugin.TreeCellEditing',
'Sch.plugin.Pan',
'gantt.store.taskStore',
'gantt.store.dependencyStore'
],
leftLabelField: 'Name',
loadMask: true,
//width: '100%',
// height: '98%',
startDate: start,
endDate: end,
multiSelect: true,
cascadeChanges: true,
viewPreset: 'weekAndDayLetter',
recalculateParents: false,
showTodayLine : true,
showBaseline : true,
initComponent: function() {
var me = this;
me.on({
scope: me,
beforeload: function(store,records,options) {
console.log('BEFORE LOAD YAAR panel'+records.params);
if(records.params['id'] != null)
{
return true;
}
else
{
return false;
}
}
});
TaskPriority = {
Low : 0,
Normal : 1,
High : 2
};
var taskStore = Ext.create('gantt.store.taskStore');
var dependencyStore = Ext.create('gantt.store.dependencyStore');
Ext.apply(me, {
taskStore: taskStore,
dependencyStore: dependencyStore,
// Add some extra functionality
plugins : [
Ext.create("Gnt.plugin.TaskContextMenu"),
Ext.create('Sch.plugin.TreeCellEditing', {
clicksToEdit: 1
}),
Ext.create('Gnt.plugin.Printable', {
printRenderer : function(task, tplData) {
if (task.isMilestone()) {
return;
} else if (task.isLeaf()) {
var availableWidth = tplData.width - 4,
progressWidth = Math.floor(availableWidth*task.get('PercentDone')/100);
return {
// Style borders to act as background/progressbar
progressBarStyle : Ext.String.format('width:{2}px;border-left:{0}px solid #7971E2;border-right:{1}px solid #E5ECF5;', progressWidth, availableWidth - progressWidth, availableWidth)
};
} else {
var availableWidth = tplData.width - 2,
progressWidth = Math.floor(availableWidth*task.get('PercentDone')/100);
return {
// Style borders to act as background/progressbar
progressBarStyle : Ext.String.format('width:{2}px;border-left:{0}px solid #FFF3A5;border-right:{1}px solid #FFBC00;', progressWidth, availableWidth - progressWidth, availableWidth)
};
}
},
beforePrint : function(sched) {
var v = sched.getSchedulingView();
this.oldRenderer = v.eventRenderer;
this.oldMilestoneTemplate = v.milestoneTemplate;
v.milestoneTemplate = printableMilestoneTpl;
v.eventRenderer = this.printRenderer;
},
afterPrint : function(sched) {
var v = sched.getSchedulingView();
v.eventRenderer = this.oldRenderer;
v.milestoneTemplate = this.oldMilestoneTemplate;
}
})
],
eventRenderer: function (task) {
var prioCls;
switch (task.get('Priority')) {
case TaskPriority.Low:
prioCls = 'sch-gantt-prio-low';
break;
case TaskPriority.Normal:
prioCls = 'sch-gantt-prio-normal';
break;
case TaskPriority.High:
prioCls = 'sch-gantt-prio-high';
break;
}
return {
cls: prioCls
};
},
// Setup your static columns
columns: [
{
xtype : 'treecolumn',
header: 'Tasks',
dataIndex: 'Name',
width: 150,
field: new Ext.form.TextField()
},
new Gnt.column.StartDate(),
new Gnt.column.Duration(),
new Gnt.column.PercentDone(),
{
header: 'Priority',
width: 50,
dataIndex: 'Priority',
renderer: function (v, m, r) {
switch (v) {
case TaskPriority.Low:
return 'Low';
case TaskPriority.Normal:
return 'Normal';
case TaskPriority.High:
return 'High';
}
}
},
{
xtype : 'booleancolumn',
width : 50,
header : 'Manual',
dataIndex : 'ManuallyScheduled',
field : {
xtype : 'combo',
store : [ 'true', 'false' ]
}
}
],
tooltipTpl: new Ext.XTemplate(
'<h4 class="tipHeader">{Name}</h4>',
'<table class="taskTip">',
'<tr><td>Start:</td> <td align="right">{[Ext.Date.format(values.StartDate, "y-m-d")]}</td></tr>',
'<tr><td>End:</td> <td align="right">{[Ext.Date.format(Ext.Date.add(values.EndDate, Ext.Date.MILLI, -1), "y-m-d")]}</td></tr>',
'<tr><td>Progress:</td><td align="right">{PercentDone}%</td></tr>',
'</table>'
).compile()
});
me.callParent(arguments);
}
});
the reason I am not able to set the value of variable I used to set it using static data. To set the static data I am using the below code
var result = Ext.JSON.decode('{"calendardata": [{"startdate": 1330281000000,"enddate": 1330284600000,"id": 3,"title": "mon"}],"total": 1,"success": true}');
var start_d = new Date(result.calendardata[0].startdate);
var end_d = new Date(result.calendardata[0].enddate);
var start = new Date(start_d.getFullYear(), start_d.getMonth(), start_d.getDate());
end = Sch.util.Date.add(start, Sch.util.Date.MONTH, 30);
but instead of this static data I want to set the start and end value as soon as the store loads and server response is received.
please suggest me some solution I can apply here.
I am receiving the jsondata as
{
"taskdata": [{
"startdate": 1330281000000,
"enddate": 1330284600000,
"id": 3,
"title": "mon"
}],
"total": 1,
"success": true
}
I am using extjs 4 with MVC architecture and JAVA as my server side technology.
First of all your question is kind of badly formulated. You have too much code and not really clear what are you trying to ask. In a future try to isolate a particular problem you're dealing with if you want to get quick and proper answer.
Second, load operation is asynchronous. You just specified store as 'autoLoad', but I don't see anywhere where you subscribe to its load event. Most likely your problem is trying to get something of the store while it's not yet loaded. Try to set autoLoad: false, load store manually and subscribe to its 'load' event to populate your view.