Changing constraints on the fly - dojo

I have a dijit.form.NumberTextBox input field that starts out with these parms:
new dijit.form.NumberTextBox({
id: din1,
style: "width:60px",
constraints: {
places: 0,
pattern: '######'
}
},
din1);
Everything works great..My question is I would like to change 'places' and 'pattern' parms on the fly. So I wrote this to change 'places' and 'patterns' parms:
var myFldObj = dijit.byId(din1);
if (myFldObj) {
var myConstObj = myFldObj.attr('constraints');
if (myConstObj) {
myConstObj.places = 2;
myConstObj.pattern = '#####.0';
}
}
So, after I show the form again, I'd expect the entry field to allow 2 decimal places but the form still acts like places=0 and pattern='######'. When I check the values of 'places' and 'pattern' I get what I'd expect (2 and #####.0). My question:
Can you change these values on the fly??
OR
Do you have to destroy the original dijit object and recreate with new parms??
Thx!!

So, here is what worked for me:
First, I think this is a bug because an input field that starts out like
new dijit.form.NumberTextBox({
id: "fieldID",
style: "width:60px",
constraints: {
places: 0
}
},
"fieldID");
that is then changed on the fly with code like:
NOTE: ntbArry - Array of dijit.form.NumberTextBox objs tied to a html
input tag id.
for (var x=0;x < ntbArry.length;x++) {
var handle = ntbArry[x];
if (handle) {
handle.attr('constraints').places = 2;
handle.attr('constraints').pattern = '#####.0#';
}
}
Does not exhibit the same behavior as a field created this way (no constraints mods on the fly):
new dijit.form.NumberTextBox({
id: "fieldID",
style: "width: 60px",
constraints: {
places: 2,
pattern: '#####.0#'
}
},
"fieldID");
It's close in behavior but every time you type a decimal point, the error message pops up stating invalid entry. This message doesn't pop up when typing the decimal point on a field that was originally created with the constraints places=2 and pattern '#####.0#'.
So, to get original behavior I wanted:
fieldIDEvents is an array of dojo events tied to NumberTextBox fields.
Before continuing disconnect dojo events
for (var x=0;x < fieldIDEvents.length;x++) {
var handle = fieldIDEvents[x];
if (handle) {
dojo.disconnect(handle);
}
}
then destroy the NumberTextBox dojo objects
for (var x=0;x < ntbArry.length;x++) {
var handle = ntbArry[x];
if (handle) {
handle.destroy();
ntbArry[x] = null;
}
}
Next, place the input tag back into the html because it gets destroyed:
NOTE: tdtag and an id on a html td tag which should contain the input tag.
var fld1 = this.document.getElementById("tdtag");
if (fld1) {
//alert("\""+fld1.innerHTML+"\"");
fld1.innerHTML = "<input id=\"fieldID\">";
}
Now, create the NumberTextBox object again:
ntbArry[0] = new dijit.form.NumberTextBox({
id: "fieldID",
style: "width: 60px",
constraints: {
places: 2,
pattern: '#####.0#'
}
},
"fieldID");
It's a few extra steps but, at least I know this is what works for me..If I'm missing something basic, let me know, it's easy to miss the small details with this stuff.

I use Dojo 1.3 and I can see that dijit.form.NumberTextBox has no pattern and places properties, but has editOptions property. So I would try to change the constraints like this:
myConstObj.editOption.places = 2;

Related

Testing that an array of objects contains a certain key using Mocha/Chai

I am trying to write some tests using Mocha and Chai on an array of objects. I want to go through this array and return any objects that contain the error key. I figured this sort of thing would be easy, but I am having a difficult time of it.
[
{ fileName: 'font1.ttc', error: 'font_type_not_supported' },
{ fileName: 'font2.ttf', error: 'parse_failed' },
{ fileName: 'font3.tff' }
]
I've tried things like.
expect(testResult).to.have.nested.property('error');
I'm probably missing something simple, does anyone have any suggestions?
I think you can use node function filter to do your work.
Something like this works:
var array = [
{ fileName: 'font1.ttc', error: 'font_type_not_supported' },
{ fileName: 'font2.ttf', error: 'parse_failed' },
{ fileName: 'font3.tff' }
]
var filter = array.filter(item => item.error != undefined)
With this way you get the elements where exists the attribute.
But if you want to compare how many elements has the property, you can use length attribute.
var count = array.filter(item => item.error != undefined).length
expect(count).gt(0)
If count variable is greater than 0, implies that at least one object has the attribute.

columnSummary is not added

I am trying to add columnSummary to my table using Handsontable. But it seems that the function does not fire. The stretchH value gets set and is set properly. But it does not react to the columnSummary option:
this.$refs.hot.hotInstance.updateSettings({stretchH: 'all',columnSummary: [
{
destinationRow: 0,
destinationColumn: 2,
reversedRowCoords: true,
type: 'custom',
customFunction: function(endpoint) {
console.log("TEST");
}
}]
}, false);
I have also tried with type:'sum' without any luck.
Thanks for all help and guidance!
columnSummary cannot be changed with updateSettings: GH #3597
You can set columnSummary settings at the initialization of Handsontable.
One workaround would be to somehow manage your own column summary, since Handsontable one could give you some headeache. So you may try to add one additional row to put your arithmetic in, but it is messy (it needs fixed rows number and does not work with filtering and sorting operations. Still, it could work well under some circumstances.
In my humble opinion though, a summary column has to be fully functionnal. We then need to set our summary row out of the table data. What comes to mind is to take the above mentioned additional row and take it away from the table data "area" but it would force us to make that out of the table row always looks like it still was in the table.
So I thought that instead of having a new line we could just have to add our column summary within column header:
Here is a working JSFiddle example.
Once the Handsontable table is rendered, we need to iterate through the columns and set our column summary right in the table cell HTML content:
for(var i=0;i<tableConfig.columns.length;i++) {
var columnHeader = document.querySelectorAll('.ht_clone_top th')[i];
if(columnHeader) { // Just to be sure column header exists
var summaryColumnHeader = document.createElement('div');
summaryColumnHeader.className = 'custom-column-summary';
columnHeader.appendChild( summaryColumnHeader );
}
}
Now that our placeholders are set, we have to update them with some arithmetic results:
var printedData = hotInstance.getData();
for(var i=0;i<tableConfig.columns.length;i++) {
var summaryColumnHeader = document.querySelectorAll('.ht_clone_top th')[i].querySelector('.custom-column-summary'); // Get back our column summary for each column
if(summaryColumnHeader) {
var res = 0;
printedData.forEach(function(row) { res += row[i] }); // Count all data that are stored under that column
summaryColumnHeader.innerText = '= '+ res;
}
}
This piece of code function may be called anytime it should be:
var hotInstance = new Handsontable(/* ... */);
setMySummaryHeaderCalc(); // When Handsontable table is printed
Handsontable.hooks.add('afterFilter', function(conditionsStack) { // When Handsontable table is filtered
setMySummaryHeaderCalc();
}, hotInstance);
Feel free to comment, I could improve my answer.

Rally API 2 query historical velocity

I am doing some processing across iterations in a release and I want to find out what the teams velocity was at that point in time, is there any way to use the lookback API or otherwise get the information for that period?
i.e. the Rally generated velocity at that time or manually calculate the last 10 or all time velocity measures?
So, based on the responses below I have ended up with this code:
_getVelocity: function() {
this.logger.log("_getVelocity");
var me = this;
var deferred = Ext.create('Deft.Deferred');
Ext.Array.each(this.iterations,function(iteration){
iteration.PlanEstimate = 1;
me.logger.log("Fetching velocity for iteration", iteration.Name);
var start_date_iso = Rally.util.DateTime.toIsoString(iteration.StartDate);
var end_date_iso = Rally.util.DateTime.toIsoString(iteration.EndDate);
var type_filter = Ext.create('Rally.data.lookback.QueryFilter', {
property: '_TypeHierarchy',
operator: 'in',
value: this.show_types
});
var date_filter = Ext.create('Rally.data.lookback.QueryFilter', {
property: '_ValidFrom',
operator: '>=',
value:start_date_iso
}).and(Ext.create('Rally.data.lookback.QueryFilter', {
property: '_ValidFrom',
operator: '<=',
value:end_date_iso
}));
var filters = type_filter.and(date_filter);
me.logger.log("Filter ", filters.toObject());
Ext.create('Rally.data.lookback.SnapshotStore',{
autoLoad: true,
filters: filters,
fetch: ['FormattedID','PlanEstimate','ScheduleState'],
hydrate: ['ScheduleState'],
listeners: {
scope: this,
load: function(store,it_snaps,successful) {
if ( !successful ) {
deferred.reject("There was a problem retrieving changes");
} else {
me.logger.log(" Back for ", it_snaps.length, it_snaps);
deferred.resolve(it_snaps);
}
}
}
});
});
deferred.resolve([]);
return deferred;
},
The shape of this code and the filters etc is lifted from another function in the same app that IS working, however this one is NOT working, I get the following errors:
Uncaught TypeError: Cannot read property 'Errors' of null
GET https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/99052282…ScheduleState%22%5D&pagesize=20000&start=0&jsonp=Ext.data.JsonP.callback49 400 (Bad Request)
Since LookbackAPI gives historic data, you may query stories at the specific point of time and get number of points completed at that time. There is no Rally generated velocity, so this has to be accessed and summed up manually. For example, I have iteration that started on August 7 and ended on August 14, but if I want data from August 10 I use:
https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/1234/artifact/snapshot/query.js?find={"Iteration":5678,"_TypeHierarchy":"HierarchicalRequirement",_ValidFrom:{$gte:"014-08-10",$lte:"2014-08-14"}}&fields=['FormattedID','ScheduleState','PlanEstimate']&hydrate=['ScheduleState']
UPDATE: As far as the code you posted, change
var start_date_iso = Rally.util.DateTime.toIsoString(iteration.StartDate)
var end_date_iso = Rally.util.DateTime.toIsoString(iteration.EndDate);
to
var start_date_iso = Rally.util.DateTime.toIsoString(iteration.get('StartDate'),true);
var end_date_iso = Rally.util.DateTime.toIsoString(iteration.get('EndDate'),true);
I replicated the bad request error with your syntax, and after changing it to this format it worked: iteration.get('StartDate'),true
App source code is in this repo.

Dijit form select

I have a question about the dgrid-master/editor_more_widgets.html test file on this path:
https://github.com/SitePen/dgrid/blob/master/test/editor_more_widgets.html
maybe you should download the whole package to see the file. anyway, is there a way to fix the "Select Store" column so it would show the label not the value, like the "FilteringSelect Store" column does?
I created a custom plugin for this purpose. The key part is the renderCell function:
define([
"dojo",
"sb",
"put-selector/put",
"dgrid/editor",
"dijit/form/Select"
], function(dojo, sb, put, editor, Select){
dojo.global.starbug.grid.columns = dojo.global.starbug.grid.columns || {};
dojo.global.starbug.grid.columns.select = function(column){
//populate the cell with the label or value
column.renderCell = function(object, value, cell, options, header){
items = column.editorInstance.getOptions();
for (var i in items) {
if (value == items[i].value) value = items[i].label;
}
put(cell, 'span.'+value.replace(/ /g, '-').toLowerCase(), value);
};
column.editorArgs = {
style:'width:100%',
labelAttr:'label',
store:sb.get(column.from, 'select')
};
column = editor(column, Select, "dblclick");
return column;
};
});
Note that sb is a custom module I used to provide the store. You can modify it accordingly.

Conditionally adjust visible columns in Rally Cardboard UI

So I want to allow the user to conditionally turn columns on/off in a Cardboard app I built. I have two problems.
I tried using the 'columns' attribute in the config but I can't seem to find a default value for it that would allow ALL columns to display(All check boxes checked) based on the attribute, ie. the default behavior if I don't include 'columns' in the config object at all (tried null, [] but that displays NO columns).
So that gets to my second problem, if there is no default value is there a simple way to only change that value in the config object or do I have to encapsulate the entire variable in 'if-else' statements?
Finally if I have to manually build the string I need to parse the values of an existing custom attribute (a drop list) we have on the portfolio object. I can't seem to get the rally.forEach loop syntax right. Does someone have a simple example?
Thanks
Dax - Autodesk
I found a example in the online SDK from Rally that I could modify to answer the second part (This assumes a custom attribute on Portfolio item called "ADSK Kanban State" and will output values to console) :
var showAttributeValues = function(results) {
for (var property in results) {
for (var i=0 ; i < results[property].length ; i++) {
console.log("Attribute Value : " + results[property][i]);
}
}
};
var queryConfig = [];
queryConfig[0] = {
type: 'Portfolio Item',
key : 'eKanbanState',
attribute: 'ADSK Kanban State'
};
rallyDataSource.findAll(queryConfig, showAttributeValues);
rally.forEach loops over each key in the first argument and will execute the function passed as the second argument each time.
It will work with either objects or arrays.
For an array:
var array = [1];
rally.forEach(array, function(value, i) {
//value = 1
//i = 0
});
For an object:
var obj = {
foo: 'bar'
};
rally.forEach(obj, function(value, key) {
//value = 'bar'
//key = 'foo'
});
I think that the code to dynamically build a config using the "results" collection created by your query above and passed to your sample showAttributeValues callback, is going to look a lot like the example of dynamically building a set of Table columns as shown in:
Rally App SDK: Is there a way to have variable columns for table?
I'm envisioning something like the following:
// Dynamically build column config array for cardboard config
var columnsArray = new Array();
for (var property in results) {
for (var i=0 ; i < results[property].length ; i++) {
columnsArray.push("'" + results[property][i] + "'");
}
}
var cardboardConfig = {
{
attribute: 'eKanbanState',
columns: columnsArray,
// .. rest of config here
}
// .. (re)-construct cardboard...
Sounds like you're building a neat board. You'll have to provide the board with the list of columns to show each time (destroying the old board and creating a new one).
Example config:
{
attribute: 'ScheduleState'
columns: [
'In-Progress',
'Completed'
]
}