AngularJS ui-grid data value and display value - angularjs

I am looking at using the AngularUI team's new table / grid implementation ui-grid. It looks really great, promising and easy to use.
Tho I have a question / problem I can't find the answer to in the documentation.
I want a column to sort on a different value then the one displayed, how can I achieve that?
I have a rank property ranging from 1 to 10 which I want to sort on but I have a rank_name property I want to be displayed.
The rank property would be the data value and the rank_name would be the display value for the column.
var members = [
{
name: 'Member 1',
rank: 1,
rank_name: 'Grand Admiral'
},
{
name: 'Member 2',
rank: 2,
rank_name: 'Aspirant'
}
]
Take the following list of members as an example, the rank property should not be its own column but be hidden, the rank_name should be visible as its own column.
But if you try and sort members from highest rank to lowest rank it would sort it alphabetically and not by the rank number which is the real rank indicator. Thus placing the Aspirant at the top and not the Grand Admiral.
$scope.gridOptions = {
enableSorting: true,
enableFiltering: true,
columnDefs: [
{field: 'name'},
{field: 'coords'},
{field: 'rank_name', name: 'rank'},
{field: 'score'},
{field: 'strength'},
{field: 'level'},
{field: 'outposts'},
{field: 'public_note'}
],
data: members
};
Here is the grid options i currently use, but would like to add a sort value for the column definition for rank.
{display_field: 'rank_name', name: 'rank', value_field: 'rank'},

write rankToString filter in your angular module
module.filter('rankToString', function () {
return function(input) {
switch(input) {
case 1:
return 'Grand Admiral';
case 2:
return 'Aspirant';
}
};
}
columnDef for rank, you still sort on rank number but show the string value in viewport. so you can dump rank_name filed.
{
field: 'rank',
sort: {
direction: uiGridConstants.ASC
},
cellFilter: 'rankToString'
}

add below to rank_name columnDef
sort: {
direction: uiGridConstants.ASC
},
sortingAlgorithm: function(a, b) {
var rank = {
'Grand Admiral': 1,
'Aspirant': 2
};
if (rank[a] > rank[b]) {
return 1;
}
if (rank[a] < rank[b]) {
return -1;
}
return 0;
}

Related

Creating dynamic columns in an Ext JS Grid

I am looking to create some logic for JSON data retrieved from a server request. As you can see from the raw data below, it is received in a particular format.
There is a "balances" entry which, in this case, has 5 different sub-values, of which names can vary dependent upon a given user.
For example:
Barry has 5 bank accounts, each with different balances.
Melissa has 2 bank accounts, each with different balances.
Melissa's bank accounts are different to Barry's bank accounts, and vise versa.
The Balance ID numbers that are assigned, may not necessarily match both Barry and Melissa.
In the Ext JS grid, the column headings which need to be displayed, must adjust to both Barry and Melissa's individual bank account balances.
Barry's JSON Data:
{
"firstName": "Foo",
"lastName": "Bar",
"balances":
{
Natwest: 9,
BankofScotland: 2,
Lloyds: 40,
Halifax: 89,
Lords: 12
},
}
Melissa's JSON Data:
{
"firstName": "Melissa",
"lastName": "Bar",
"balances":
{
DifferentNatwest: 10,
DiffferentBankofScotland: 45
},
}
At the moment, I only have one mapping in my store/model, called "balances" which only takes one value:
Store/Model definitions:
fields: ['firstName', 'lastName', 'balances']
So, obviously the following issue occurs when the grid is generated, as more than one value is being passed:
Results:
The Question:
Does anyone know what I can do to get the columns to dynamically generate in this Ext JS grid, dependant upon the JSON data being received for this balances information?
What you need is to create the grid columns and store for it dynamically.
I don't know if there is some more "ExtJS" way (simpler, automatic creation) but I would do a straightforward solution.
1# Solution - with multiple columns
Get the data, get the JSON object
Based on the JSON object create the new grid columns
Based on the JSON object create the new store with correct records (I
don't think there is model which can have object in it - you need to transofrm it)
Create the grid and add the new store and columns to it.
Here is the code snippet with the most important part:
for (var key in d.balances) {
bankAcountsColumns.push({
xtype: 'gridcolumn',
dataIndex: key,
text: key
});
transformData[key] = d.balances[key];
fields.push(key);
}
var myCustomColumns = [{
xtype: 'gridcolumn',
dataIndex: 'firstName',
text: 'Name'
}, {
xtype: 'gridcolumn',
dataIndex: 'lastName',
text: 'LastName '
}, {
xtype: 'gridcolumn',
text: 'Bank accounts',
columns: bankAcountsColumns
}]
Ext.create('MyApp.view.MyGridPanel', {
renderTo: Ext.getBody(),
columns: myCustomColumns,
store: {
fields: fields,
data: transformData
}
});
Here is working fiddle example:
https://fiddle.sencha.com/#view/editor&fiddle/1l5j
2# Solution - one column
If you want to have only one column with all the balances, you would need templatecolumn
In there I would create template for 5 items (or it can be again created dynamically):
tpl:'{bank1name} {bank1value} {bank2name} {bank2value} ...'
And than you would have to dynamically create the data for the new store.
data:[
{ firstName: "Foo", lastName:"Scott", bank1name: "Natwest", bank1value: "9" ... },
{ firstname: "Dwight", lastName: "Bar", ... bank5name: "" ... }
]

how to add drop down on header using grid (not input field)?

I am trying to use Ui-grid from this link
http://ui-grid.info/docs/#/tutorial/101_intro.
I make a simple example of ui-grid in plunker..I need to add select box on "Gender" as filter .If I select "male" it show only data who is "m or If I select "female" it show filter data only "f" value here is my code
Plunker https://plnkr.co/edit/DqBgHFnwLpYM5pvg0f56?p=preview
I try like that but not work
type: uiGridConstants.filter.SELECT,
selectOptions: [
{ value: 'm', label: 'male' },
{ value: 'F', label: 'female' }
];
I don't need input field on gender .I need select box or dropdown on gender column
First you need to add uiGridConstants as parameter in your controller declaration, so you can use it. Then, you will be able to do what you want.
angular.module('app',['ngTouch', 'ui.grid'])
.controller('MainCtrl',function( $scope, uiGridConstants ){
// ...
$scope.gridOptions = {
enableFiltering: true,
columnDefs: [
{
field: 'gender',
displayName:'Gender',
filter: {
type: uiGridConstants.filter.SELECT,
selectOptions: [
{ value: 'm', label: 'male' },
{ value: 'F', label: 'female' }
];
}
},
{field: 'name', displayName:'First'},
{field: 'lastname', displayName:'Second',enableSorting: false}
]
};
// ...
}
I'll give you an advice : to debug angular code, or any javascript code, use a tool like Firebug (for Mozilla Firefox). It will show you the javascript errors encountered when you change your code and plunker try to apply it. In this case, you would have seen this :
Error: uiGridConstants is not defined
#https://run.plnkr.co/8CvvTtAR4QY8O2Ln/app.js:30:11

Angularjs ui grid with grouping column sequence is getting jumbled up

I am using AngularJs ui grid with grouping. The table is displaying fine but the problem I am facing is that the months sequence in the table is getting jumbled up. Please find my Plunker. In the table the Months are appearing in the jumbled up sequence 11-14, 05-15, 04-15, ... 02-15. But I need it in the sequence of 11-14, 12-14, 01-15, 02-15, 03-15, 04-15, 05-15. Can any one help me to fix it?
I am using the following for to get colDefs:
$scope.getColumnDefsForUiGrid = function(columns) {
var colDef = [];
colDef.push({
name: 'mode',
grouping: {
groupPriority: 0
},
displayName: 'Type',
enableCellEdit: false,
width: '5%'
});
colDef.push({
name: 'service',
displayName: 'Catg',
enableCellEdit: false,
width: '5%'
});
angular.forEach(columns, function(value, key) {
colDef.push({
name: key,
displayName: value,
enableCellEdit: true,
aggregationType: uiGridConstants.aggregationTypes.sum,
width: '5%'
})
});
return colDef;
};
Here is a workaround for your problem
you can see it working on this plunker
$scope.getColumnDefsForUiGrid = function( columns ){
var colDef = [];
colDef.push({name: 'mode', grouping: { groupPriority: 0 }, displayName: 'Type', enableCellEdit: false, width: '5%'});
colDef.push({name: 'service', displayName: 'Catg', enableCellEdit: false, width: '5%'});
//I split the monthColumns into an other array
var monthCol = [];
angular.forEach(columns, function( value, key ) {
monthCol.push({name: key, displayName: value, enableCellEdit: true, aggregationType : uiGridConstants.aggregationTypes.sum, width: '5%' })
});
//I sort this array using a custom function
monthCol.sort(function(a,b){
a = a.displayName.split("-");
b = b.displayName.split("-");
if(a[1] < b[1]){
return -1;
}else if (a[1] > b[1]){
return 1;
}else {
if(a[0] < b[0]){
return -1;
}else{
return 1;
}
}
});
//I concat the two array
return colDef.concat(monthCol);
};

Why is ng-grid not sorting by both columns?

I have 2 grids showing the same data with 2 different sorts:
$scope.aGridOptions = {
data: 'aData',
columnDefs: [
{ displayName: 'Column 1', field: 'col1',},
{ displayName: 'Column2', field: 'col2',}],
sortInfo: {
fields: ['col1'], directions: ['asc']
},
};
$scope.bGridOptions = {
data: 'aData',
columnDefs: [
{ displayName: 'Column 1', field: 'col1',},
{ displayName: 'Column2', field: 'col2',}],
sortInfo: {
fields: ['col1', 'col2'],
directions: ['asc', 'asc']
},
};
As the plunker shows, both sort the same way, only by column 1. Not only that, but ng-grid 2.0.7, trashes by sortInfo object on bGridOptions to shorten the sort to only one column.
http://plnkr.co/edit/riDzDcS3YSJrQrULwL2j?p=preview
I can't seem to find where it is destroying my sort options. How do I get it to sort by 2 columns and not have it trash my sortInfo?
Below is the initial answer I typed, which seemed to work as I played around in your Plunk; however, when I went to make a clean copy of the Plunk it stopped working. It sounds like this issue may be resolved in 2.0.8 though, see Issue #748 and Issue #732.
My initial response, but not working for me now...
Try changing the sortInfo for each grid to look like this:
$scope.aGridOptions.sortInfo = {
fields: ['col1'],
directions: ['asc'],
columns: [0]
};
$scope.bGridOptions.sortInfo = {
fields: ['col1', 'col2'],
directions: ['asc', 'asc'],
columns: [0, 1]
};

How do to filter an Ext.data.Store returning any match on the record instance?

I am trying to filter a store based on a set of mapped Ext.util.Filters. For example:
comboBox.store.filter(_.map(this.displayFields, function (displayField) {
return {
property: displayField.name,
value: queryString,
anyMatch: true
};
}));
this.displayFields is a list of display fields in my combobox template. In my combobox template I have something like:
'{codeValue} {displayValue} {descriptionValue}'
displayValue is the displayField property on my combobox. When I search for 'co' in my combobox, all displayFields must have 'co' in the value when I apply the filters to the store. My filters look like this:
[
{property: 'codeValue', value: 'co'},
{property: 'displayValue', value: 'co'},
{property: 'desciptionValue', value: 'co'}
]
I would like a set of records that have the value 'co' in any of the displayFields' property.
Each filter is applied after the previous one, resulting in a logical "and". You've probably got that, or you wouldn't be asking. So, how do you get an "or" with Ext? If that were an "or" on values, you could use a regex for value, but you want it on property. As far as I know there isn't a built-in config option for that, but you can do anything you want in filterFn.
Here's, for example, a combo that displays all records with an 'a', either in their code or name, and only them:
Ext.widget('combo', {
renderTo: Ext.getBody()
,store: {
fields: ['id', 'code', 'name']
,data: [
{id: 1, code: 'a', name: 'Foo'}
,{id: 2, code: 'b', name: 'Bar'}
,{id: 3, code: 'ba', name: 'Baz'}
,{id: 4, code: 'z', name: 'Zoo'}
]
,filters: [{
filterFn: function(record) {
var match = false;
Ext.each(fields, function(field) {
if (re.test(record.get(field))) {
match = true;
return false; // break the loop
}
});
return match;
}
}]
}
,displayField: 'name'
,valueField: 'id'
});

Resources