Resize column in SlickGrid - backbone.js

I have the following SlickGrid:
var eligibleProductsGrid = new recline.View.SlickGrid({
model:dataset,
el:'#selectorModal #selectorModalContainer #selectorModalGrid',
state:{
fitColumns:true,
hiddenColumns: ['id', 'mrid', 'distributedQuantity' ,'qMeasureUnit'],
gridOptions:{
enableColumnReorder:false,
gridIdCSS: arguments[0].gridIdCSS ? arguments[0].gridIdCSS: "eligpprodGs9999",
}
}
});
and i want to rezise the width of the third column.
I've tried doing this:
var cols = this.eligibleProductsGrid.getColumns();
cols[2].width = 520;
this.eligibleProductsGrid.setColumns(cols);
but i have an error saying that getColumns() is not a function.
Any ideas? Thanks!

Related

Angularjs applying $watch to cellTemplate function

I am showing data to user using angular ui-grid. In the following code for field 'plan', i add a set of entities by calling the getPlan() function and show it using a cellTemplate in ui-grid columnDefs.
$scope.getPlan = function(rowEntity) {
var plan1Temp = rowEntity.plan1;
var plan2Temp = rowEntity.plan2;
var plan3Temp = rowEntity.plan3;
var plan4Temp = rowEntity.plan4;
var plan5Temp = rowEntity.plan5;
var plan6Temp = rowEntity.plan6;
var plan7Temp = rowEntity.plan7;
var plan8Temp = rowEntity.plan8;
plan = plan1Temp+plan2Temp+plan3Temp+plan4Temp+plan5Temp+plan6Temp+plan7Temp+plan8Temp;
console.log("plan=", plan);
return plan;
};
columnDefs: [{ field : 'plan',
cellTemplate : '<div id="grid-cell-template">
{{grid.appScope.getPlan(row.entity)}}</div>',
displayName : "Plan",
footerCellTemplate : '<div class="ui-grid-cell-contents">
\Total:\ {{grid.appScope.getTotalPlan() }}</div>',
width : "*"
}]
Then to show the total of all the plans i use footerCellTemplate with getTotalPlan(). While using it i got $digest() iterations reached error. I noticed the getPlan() function is called many times. So i added $watch like shown below.
var totalPlan = [];
$scope.$watch(function() {
return plan;
}, function() {
totalPlan.push(plan);
console.log("totalPlan =", totalPlan);
});
$scope.getTotalPlan = function() {
var sum = 0;
angular.forEach(totalPlan ,function(item){
sum = sum + item;
});
return sum;
console.log("getTotalPlan=", sum);
};
After adding $watch also the getPlan() function is called many times. Also in totalPlan[] it holds only 2 values, first null and second one last record value(in total there are 3 records) and prints this value in the ui-grid footercelltemplate. How should i use $watch to make it work right?
So basically the problem is i am not able to insert 'plan' values into totalPlan[ ] and show the total in the grid footer template.
Also i tried using :: inside the expression, the number of getPlan() calling times reduced to half but no luck.

google.visualization.DataTable(JSON.parse(datastring)) is not working

I am using google charts to display some data on the screen and on some button click. The data is loading from webapi call.
To simplyfy the issue, I made the data hardcoded in function itself.
The issue is when I call
google.visualization.DataTable(JSON.parse(datastring))
Message: Table has no columns.
it is returning empty datatable. I also tried with arrayToDatable but no use.
I got error with arrayToDataTable. here is it.
Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys
I have create a plunker for it.
http://plnkr.co/edit/pctIqoCWi3LhqxlgdnqM?p=preview
Can anyone have a look and let me know whats wrong with this.
when creating google.visualization.DataTable directly from json,
the json must be in a specific format
see --> Format of the Constructor's JavaScript Literal data Parameter
google.visualization.arrayToDataTable accepts an array of values, not objects...
[["ReportName","ReportTime"],["ABC",48],["XYZ",50]]
if you don't want to change the format of the results from the webapi call,
you'll need to transform the data for the chart
see following working snippet for an example...
google.charts.load('current', {
callback: function () {
var datastring = '{"PerformanceData" : [{"ReportName":"ABC","ReportTime":"48"},{"ReportName":"XYZ","ReportTime":"50"}]}';
var jsonData = JSON.parse(datastring);
var chartData = [];
// load chart data
jsonData.PerformanceData.forEach(function (row, rowIndex) {
// column headings
var columns = Object.keys(row);
if (rowIndex === 0) {
chartData.push(columns);
}
// row values
var chartRow = [];
columns.forEach(function (column, colIndex) {
var chartCell = row[column];
if (colIndex > 0) {
chartCell = parseFloat(chartCell);
}
chartRow.push(chartCell);
});
chartData.push(chartRow);
});
var data = google.visualization.arrayToDataTable(chartData);
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, { width: 400, height: 240 });
},
packages:['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
once the data table is built, use the group() method to aggregate the data
you can use one of the provided aggregation functions, or provide your own
google.visualization.data.avg
google.visualization.data.count
google.visualization.data.max
google.visualization.data.min
google.visualization.data.sum
see following working snippet...
google.charts.load('current', {
callback: function () {
var datastring = '{"PerformanceData" : [{"ReportName":"ABC","ReportTime":"48"},{"ReportName":"XYZ","ReportTime":"50"},{"ReportName":"ABC","ReportTime":"48"},{"ReportName":"XYZ","ReportTime":"50"},{"ReportName":"ABC","ReportTime":"48"},{"ReportName":"XYZ","ReportTime":"50"},{"ReportName":"ABC","ReportTime":"48"},{"ReportName":"XYZ","ReportTime":"50"}]}';
var jsonData = JSON.parse(datastring);
var chartData = [];
// load chart data
jsonData.PerformanceData.forEach(function (row, rowIndex) {
// column headings
var columns = Object.keys(row);
if (rowIndex === 0) {
chartData.push(columns);
}
// row values
var chartRow = [];
columns.forEach(function (column, colIndex) {
var chartCell = row[column];
if (colIndex > 0) {
chartCell = parseFloat(chartCell);
}
chartRow.push(chartCell);
});
chartData.push(chartRow);
});
var data = google.visualization.arrayToDataTable(chartData);
// group data
var dataGroup = google.visualization.data.group(
data, // data table
[0], // group by column
[{ // aggregation column
column: 1,
type: 'number',
aggregation: google.visualization.data.sum
}]
);
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
// use group data to draw chart
chart.draw(dataGroup, {
pieSliceText: 'value',
width: 400,
height: 240
});
},
packages:['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Why does my angular directed work on one table cell but none others?

I am using a ContextMenu directive within a kendo grid. I have made one change to it so I can include icons in the text (changed $a.text(text) to $a.html(text).
I have one in the first cell (I highjacked the hierarchical cell) that has row operations (add, clone& delete) and one on a span within each cell that changes the cell values operation (addition, subtraction, equals, etc...)
Both of these were working. I am unsure what I changed that stopped it from working because I last checked it several changes ago (I'm still locked out of TFS so I can't revert).
One change I made was to include a disabled/enabled check to the working contextMenu. I tried adding the same to the broken one and no dice.
I do perform a $compile on the working menu and the broken one is only included in the kendo field template.
If I must compile the field template (and I didn't need to before), how can this be done?
So here is some code.
working menu:
$scope.getRowContextMenu = function (event) {
var options =
[[
"<span class='fa fa-files-o'></span>Clone Rule", function (scope, cmEvent) {/*omitted for brevity*/}),rowContextDisableFunction]]
}
var setHierarchyCell = function (grid) {
var element = grid.element;
var hCells = element.find("td.k-hierarchy-cell");
hCells.empty();
var spanStr = "<span context-menu='getRowContextMenu()' class='fa fa-bars'></span>";
hCells.append($compile(spanStr)($scope));
var span = hCells.find("span.fa");
span.on('click', function (event) {
$(this).trigger('contextmenu', event);
});
}
kendo template:
var mutliFormTemplate = function (fieldName, type) {
var result = "";
result += "<span context-menu='getOperationContextMenuItems()' class='fa #= " + fieldName + "_Obj.OperationSymbol # type-" + type + "'> </span>\n";
/*The rest pertains to the cell value. excluded for brevity*/
return result;
}
$scope.getOperationContextMenuItems = function () {
//I trimmed this all the way down to see if I could get it working. Still no joy
return [
["test", function () { }, true]
];
}
Creating the kendo columns dynamically:
$scope.model = {
id: "RuleId",
fields: {}
};
$scope.fieldsLoaded = function (data, fields) {
var column = {}
$.each(fields, function () {
var field = this;
$scope.columns.push({
field: field.Name,
title: field.Name,
template: mutliFormTemplate(field.Name, "selector")
});
column[field.Name ] = { type: getFieldType(field.Type.BaseTypeId) }
});
$scope.model.fields = column;
}
Thanks for any and all help ^_^

ExtJS CheckboxGroup label wrap

I have a problem with checkboxes. So these checkboxes are in columns, and the longer labels wrap under their checkboxes. Is there any sollution to setting the column width to the longest label? It must be dynamic width. Can you help me?
Here's something you can use to measure all the labels and apply the width of the widest one to all of them http://jsfiddle.net/Wr7Wr/1/
Ext.define('DynamicLabelFormPanel', {
extend: 'Ext.form.Panel',
initComponent: function() {
// Need to create a hidden field to measure the text
var field = new Ext.form.field.Text({fieldLabel: 'Testing', value: 'whateves', renderTo: Ext.getBody(), hidden: true});
var metrics = new Ext.util.TextMetrics(field.labelEl);
var widths = Ext.Array.map(this.items, function(item) {
// Need to acount for the :
return metrics.getWidth(item.fieldLabel + ":");
});
var maxWidth = Math.max.apply(Math, widths);
for (var i = 0; i < this.items.length; i++) {
this.items[i].labelWidth = maxWidth;
}
this.callParent();
}
}
This would probably be better as a plugin, but it shows you what needs to be done

ExtJS 4 > Row Editor Grid > How to Change "Update" Button Text

Is there any way to change the text of "Update" button in ExtJS-4 Row Editor Grid ?
Good question, I had a look through the source code and whilst there is nothing inside the RowEditing plugin, in the class it extends 'RowEditor.js' there is the following:
Ext.define('Ext.grid.RowEditor', {
extend: 'Ext.form.Panel',
requires: [
'Ext.tip.ToolTip',
'Ext.util.HashMap',
'Ext.util.KeyNav'
],
saveBtnText : 'Update',
cancelBtnText: 'Cancel',
...
});
So I'd assume you'd just need to override the 'saveBtnText' in your instance of 'Ext.grid.plugin.RowEditing' as it calls the parent constructor with callParent(arguments) in the RowEditing class
Not that easy and not without hacking in undocumented areas. The problem is, that the Ext.grid.plugin.RowEditing directly instantiates the Ext.grid.RowEditor without allowing you to pass in configuration options. So in general you have to override the initEditor() method in the plugin and instantiate your own row editor:
// ...
plugins: [{
ptype: 'rowediting',
clicksToEdit: 2,
initEditor: function() {
var me = this,
grid = me.grid,
view = me.view,
headerCt = grid.headerCt;
return Ext.create('Ext.grid.RowEditor', {
autoCancel: me.autoCancel,
errorSummary: me.errorSummary,
fields: headerCt.getGridColumns(),
hidden: true,
// keep a reference..
editingPlugin: me,
renderTo: view.el,
saveBtnText: 'This is my save button text', // <<---
cancelBtnText: 'This is my cancel button text' // <<---
});
},
}],
// ...
For ExtJS 4
Ext.grid.RowEditor.prototype.cancelBtnText = "This is cancel";
Ext.grid.RowEditor.prototype.saveBtnText = "This is update";
This solution is to define the prototype of rowEditors. that means that this config is than general.
If you want to change it just for one editor, or if you want to get different configs , the prototype is definitely not the solution.
look at source code :
initEditorConfig: function(){
var me = this,
grid = me.grid,
view = me.view,
headerCt = grid.headerCt,
btns = ['saveBtnText', 'cancelBtnText', 'errorsText', 'dirtyText'],
b,
bLen = btns.length,
cfg = {
autoCancel: me.autoCancel,
errorSummary: me.errorSummary,
fields: headerCt.getGridColumns(),
hidden: true,
view: view,
// keep a reference..
editingPlugin: me
},
item;
for (b = 0; b < bLen; b++) {
item = btns[b];
if (Ext.isDefined(me[item])) {
cfg[item] = me[item];
}
}
return cfg;
}`
this method inits the rowEditor, and there's a loop on btns Array:
btns Array :
btns = ['saveBtnText', 'cancelBtnText', 'errorsText', 'dirtyText']
for (b = 0; b < bLen; b++) {
item = btns[b];
if (Ext.isDefined(me[item])) {
cfg[item] = me[item];
}
}
In this loop foreach string in btnArray it's searched if exists in cfg the same string property, if it's found it's added to config. You just have to manage that this loop finds what you want to modify:
Example: we want to change the text of save button:
the property saveBtnText which is the first item of btns Array must exists in cfg:
if (Ext.isDefined(me[item])) {
cfg[item] = me[item];
}
this search if property exists : if (Ext.isDefined(me[item]))
if saveBtnText already exists in rowEditor properties then:
cfg[item] = me[item];
and the additional config property will be set!!

Resources