Computed values in knockout koGrid - javascript

I need to use a grid in which one column has a computed value based on values from other columns in the grid ...
As a sample requirement I have one column which shows the age this is a editable column ... if the age is changed the next column should compute the value of 100 - the updated age ...
I have created a jsfiddle to demo my requirement here JSFiddle
{field: 'computedAge', displayName: '100 -Age',cellTemplate:self.calculatedCellTemplate}
is the computed column that i wish to populate when the age column is updated
Can anyone suggest how i could achieve this ?

You can achieve this by only two steps:
(1) Create instantiation function for every item in your datalist with computedAge computed property within it.
function Item(data) {
this.name = ko.observable(data.name);
this.age = ko.observable(data.age);
this.computedAge = ko.computed(function(){
return 100 - this.age();
}, this);
}
(2) Map source array to create instances instead of simple observableArray creation.
self.browsers = ko.observableArray(
ko.utils.arrayMap(
datastore.initialData,
function(data){ return new Item(data); }
)
);
Working example: http://jsfiddle.net/xp6xa/
Update:
To get self-updating cell do not forget to define your self.calculatedCellTemplate like this:
self.calculatedCellTemplate = '<span data-bind="text: $parent.entity.computedAge"></span>';
http://jsfiddle.net/xp6xa/3/

Related

How to display several fields in one column in tabulator.info grid

I have several columns in my tabledata structure, what I want to display in one single column
var tabledata = [
{id:1, first_name:"Bob", last_name:"Smith"},
{id:2, first_name:"Mary", last_name:"Hope"}
];
I can have access to the actual cell data by using the var val1 = cell.getValue(); command, but how can I get access from the first_name to the last_name field to display both of them at once?
The getValue() function has no parameter to specify an other field and the formatter parameter describes only the cell parameter (i.e. no row) for the formatter function.
I'm looking to get something like that:
{title:"Name", field:"first_name", width:550, formatter:function(cell, formatterParams){
var val1 = cell.getValue();
var val2 = cell.getCell("last_name");
return val1 + " " + val2;
}},
I would recommend that you dont use a formatter for this, because formatters are visual only it means that you would be unable to sort that column.
The correct approach would be to use a field property that doesn't exist, for example lets call it full_name and then use a Mutator to create this value for you. this would then have the added benifit of being filterable and sortable.
//define custom mutator
var customMutator = function(value, data, type, params, component){
return data.first_name + " " + data.last_name;
}
//column definition
{title:"Name", field:"full_name", mutator:customMutator}

Mix clickable row and unclickable row on slickgrid

For my columns definition.
var columns = [
{id: "label", name: "point", formatter:this.clickableFormatter,field: "point",width: 150},
then I add clickhander for it.
chart.addClickHandler(){
}
Also I use clickableFormatter for this.
clickableFormatter(row,cell,value,columnDef,dataContext){
return "<span style='cursor:pointer;'>" + value + "</span>";
}
From these code. my table rows are clickable and I can show the user where is clickable by changing pointer.
However now I want to make one row unclickable.
(for example total row)
Is it possible to prevent click event for one low??
And is it possible to use another formatter for one row?
I gave the data from for loop and add total seperately.
for (var k = 0 ; k < data.length ;k++){
var temp = new Array();
temp['id'] = data[k]['id'];
temp['point'] = data[k]['point'];
ret.push(temp);
}
ret.push({
'id' : "total",
"point" : pointTotal,
});
In your formatter, you have access to the value of the cell, so if value==='total', just return an empty string.
Also FYI, I don't think you need the for loop in your code (you could just leave it out entirely), unless you're using it to calculate the total, but you don't seem to be doing that.
If you think that you need it for creating the array objects, you're misunderstanding arrays in javascript, what you're actually setting is object properties, and it would be usual to initialise with var temp = { }; rather than as Array.
It may not make sense at first, but everything in javascript is an object, including arrays and functions. So you can add object properties to anything.
somevar[numericVal] = x; // set array element, somevar must be type Array
somevar['stringVal'] = x; // set object property 'stringVal'
somevar.stringVal = x; // identical to above line, different way of specifying

How to update the columnDef of an angular ui-grid column dynamically

So the issue I'm facing is I would like to update the field property of a columnDef definition to show a different value based on some configuration that's being passed into the directive. I have a dumbed down version in this plunk:
http://plnkr.co/edit/gmjUcQsnIOpqWwkoYiI8?p=preview
Clicking the button in that plunk should switch the emails from actual to pretend. It's looping over the columnDefs on scope and then altering the field to be email.pretend from email.actual. Do I need some kind of "refresh" function after changing the columnDefs? I tried gridApi.core.refresh() but that did not do anything. Thanks for any input!
http://plnkr.co/edit/ujIpJFFGRAwNUKiy0Bnm?p=preview
$scope.otherColumn = {displayName: 'Pretend', field: 'email.pretend'};
//change the field - is this possible???
$scope.changeField = function changeField() {
$scope.otherColumn = $scope.columnDefs.splice(1, 1, $scope.otherColumn)[0];
}
You just add / remove the item from the columnDefs array and it will do it.
So I thought I could update my grid similar to this but by reassigning an array to the columnsDef like this
var a = true;
//change the field - is this possible???
$scope.changeField = function changeField() {
if (a) {
$scope.columnDefs = [{ field: 'name' }, {
displayName: 'Pretend',
field: 'email.pretend'
}];
} else {
$scope.columnDefs = [{ field: 'name' }, {
displayName: 'Email',
field: 'email.actual'
}];
}
a = !a;
};
If you put that in the plnkr you'll see it doesn't have any effect.
That's because the assignment doesn't change the $scope.gridApi.
As #dave's answer suggests you need to modify the original columnsDef object from the initialization or the columns under the api won't be affected. I'm glad the code doesn't clone the object for the api or I'd have to dig into the api to make this change.

make json from table

I want to make specific json from table. I have a table, which has rows and 4 columns.
Here is my table I want to build an jsonarray from the table.
First value in the left column is key of json and last value in the right column is a valueof json.
I mean I want to get from table jsonarray, it must look as
json_from_form = [{color: 'id',
name: "mouse",
x: "table",
y: "book"}];
I have tried to build json, but have a problem with structure and setting a key in json object.
Please help me to buld right structure of json object.
var json_from_form_tmp = {};
$('#table').find('tbody tr').each(function (i) {
//var name = $(this).find('td:first').text();
json_from_form_tmp[i] = {
imd: $(this).find('td:eq(3) input').val()
};
});
console.log(json_from_form_tmp);
Here is my DEMO
You should use the jQuery map-function for this, here is an example:
$(function () {
var m = $("table tr").map(function (index, e) {
return {
color: $(e).children().eq(0).text(),
name: $(e).children().eq(1).text()
}
}).get();
});
Where m will be an array of objects as defined inside the map function.
To set a property of the object (json_from_form_tmp), use the ['propertyName'] notation.
//get the name of the property from the first column
var name = $(this).find('td:first').text();
//use that name as the name of the property. Your value fetch was right!
json_from_form_tmp[name] = $(this).find('td:eq(3) input').val();
Here is your fiddle with a tiny modification.
http://jsfiddle.net/bMzq8/32/

How to get the object which represents the selected row in a slickgrid

I have a webpage with a slickgrid which renders an array of objects on a grid. I want to do some dynamic stuff (a master-detail like setup) when the selected row changes. However to be able to do this, I would need the data of the selected row. I know that the grid.getCurrentCellNode() function will give me the dom element of the current node, but what I am looking for is a javascript object. For instance, if I use an array of objects like the one below
data = [
{id:1, name:'Khaja', dob:'26/07/1985'},
{id:2, name:'Iqbal', dob:'26/07/1935'}
......
...
];
and if my selected row is the row with id equal to 2, I want to be able to retrive the object {id:2, name:'Iqbal', dob:'26/07/1935'} Is there a way through which I can get this object?
You can use the onSelectedRowsChanged event and the getSelectedRows method.
data[i]={
ID: json[i].ID,
Name: json[i].Name,
Description: json[i].Description,
CreatedDate: myDate,
makesub: "---",
shared: json[i].IsShared
};
.....
grid.onClick = function (e, row, cell) {
if (columns[cell].id == "colname"){
// where colname is the column on which you want to trigger the click
alert("clicked:"+row+", albumID:"+data[row].ID);

Categories

Resources