How to do a "row header" in Angular ui-grid - angular-ui-grid

What I'm trying to do in Angular ui-grid seems pretty common, but I'm having trouble finding anything that describes a solution.
I have a table. Like many tables the first row is really a "row header".
Now what specifically do I mean by that:
Like column headers, the values are always the same. They are not "data"
Like column headers, they are styled differently than non-header data cells to indicate that they are not "data".
You should not be able to "sort" nor "remove" the header row
Ideally, the column for the row headers is "frozen" in that it doesn't scroll
It perhaps is worth mentioning that the row header labels COME from the data as in:
{
rowHeader : "Fixed Rate",
TenYear: .02,
TwentyYear: .03
},
{
rowHeader : "Variable Rate",
TenYear: .04,
TwentyYear: .05
}
So what I'm looking for in the above example, is a table where the first column has row headers of "Fixed Rate" and "Variable Rate". The styling of that column should "look like" a header cell rather than a data cell.
Now I know that some of these things like "frezeing" and turning off sorting are available via columnDefs in gridOptions. But what I'm unclear of is if there's a way to just declare that the first column is a header, and I just get all of these things.
This seems to be a common table paradigm.

This is pretty easy with row header template. You can define your own template like below
var app = angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid']);
app.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.columns = [{ field: 'TenYear' }, { field: 'TwentyYear' }];
var data = [{
rowHeader : "Fixed Rate",
TenYear: .02,
TwentyYear: .03
},
{
rowHeader : "Variable Rate",
TenYear: .04,
TwentyYear: .05
}]
$scope.gridOptions = {
data : data,
enableSorting: true,
columnDefs: $scope.columns,
onRegisterApi: function( gridApi ) {
$scope.gridApi = gridApi;
var cellTemplate = 'ui-grid/selectionRowHeader'; // you could use your own template here
$scope.gridApi.core.addRowHeaderColumn( { name: 'rowHeaderCol', displayName: '', width: 200, cellTemplate: "<div class=\"ui-grid-row-header-cell ui-grid-disable-selection\"><div class=\"ui-grid-cell-contents\">{{row.entity['rowHeader']}}</div></div>"} );
}
};
}]);
Working plnkr http://plnkr.co/edit/9jZYgS3Ygaj2vhOnd2vh?p=preview

Related

Highcharts data module: filtering specific columns in referenced HTML table

Full example:
https://jsfiddle.net/gbeatty/4byg0p2t/
data: {
table: 'datatable',
startRow: 0,
endRow: 6,
startColumn: 0,
endColumn: 3,
parsed: function (columns) {
columns.forEach(column => {
column.splice(1, 2);
});
}
},
What I'd like the chart to reference is only column 0 "Year" and column 3 "Group C" while keeping the entire table displayed below. Challenge is disregarding the 2 columns in the middle.
I am trying the parsed option but it seems the rows and columns are mixed up. I even tried setting the switchRowsAndColumns value to true. (https://api.highcharts.com/highcharts/data.seriesMapping)
You can also use complete function to modify your data.
Example code based on your config:
complete: function(options) {
let series = [];
series.push(options.series[2]);
options.series = series;
}
Demo:
https://jsfiddle.net/BlackLabel/tfs4ubcL/
API Reference:
https://api.highcharts.com/highcharts/data.complete

Updating Highcharts column chart based on drop down-menu

I'm trying to have Highcharts do the following: I want to show a column chart with three columns. The two first are to remain constant, the third is to be updated multiple times based on what the user chooses from a drop down-menu.
Choosing from the drop down-menu, I am able to have the third column update. If it's showing "Name 3" initially, choosing "Name 4" from the drop down menu will correctly replace the column. Choosing "Name 5" causes another correct replacement. However, if I then choose "Name 3" again, only the label will update, while the column and the y-value in the tooltip will not. Thus, it will say "Name 3", but use the y-value for "Name 5". How do I fix this behaviour?
The important thing here is user control of column 3. It would be okay to only show 2 column initially, if it's easier.
Code:
var data = {
"10 - Name 1": [700000],
"1001 - Name 2": [750000],
"1000 - Name 3": [800000],
"1002 - Name 4": [900000],
"1003 - Name 5": [950000]
};
var chart = Highcharts.chart('fig8', {
chart: {
type: 'column',
animation: true
},
series: [{
name: "10 - Name 1",
data: data["10 - Name 1"]
}, {
name: "1001 - Name 2",
data: data["1001 - Name 2"]
}, {
name: "1000 - Name 3",
data: data["1000 - Name 3"]
}],
title: {
text: 'Some metric'
},
subtitle: {
text: 'Choose unit from drop down to alter third column'
},
xAxis: {
labels: {
enabled: false
}
}
});
$("#sel").change(function() {
chart.series[2].update({
name: this.value,
data: data[this.value]
});
});
Here's a stripped down example: https://jsfiddle.net/RuneS/soh8vw79/10/
#jlbriggs is correct. Although the docs for update() don't say anything about it, it is mentioned in the docs for setData(): When updating series data, the default behavior is to update the values in the original data array instead of replacing the whole array.
In your case, that means that "Name 3"'s value is overwritten by the others' values when you select from the dropdown. There are at least two ways to fix this:
Force Highcharts to replace the data array by calling setData() with the updatePoints parameter instead of sending the data with update():
$("#sel").change(function() {
var unit = this.value,
val = data[unit],
ser = chart.series[2];
ser.update({ name: unit }, false);
//... false): Replace the series' data array instead of updating its values,
//(which would alter the original array in the global `data` object).
//https://api.highcharts.com/class-reference/Highcharts.Series#setData
ser.setData(val, true, true, false);
});
https://jsfiddle.net/soh8vw79/22
Don't give Highcharts the original array, but a copy of it. That way, updating the values won't affect the original data (similar to #jlbriggs solution). Added bonus: Smooth animation:
...
series: [{
name: "10 - Name 1",
data: data["10 - Name 1"]
}, {
name: "1001 - Name 2",
data: data["1001 - Name 2"]
}, {
name: "1000 - Name 3",
//Here, we use `.slice()` to make a copy of the original array,
//so that future updates don't change the original values in the global `data` object:
data: data["1000 - Name 3"].slice()
}],
...
https://jsfiddle.net/soh8vw79/23

dynamic jqgrid with dynamic data loading

The dwr call returns a set of data which will have any number of specific columns. For example name, id, address. The address could be 1,2 or 3 like address1, address2 for first record and address1, address2, address3 for second data. My question is how to make the column name for jqgrid dynamic.
DataHandler.fetch(function(data){
resultSet = data;
jQuery("#table1").jqGrid({
datatype : "local",
data : resultSet,
height : 250,
width : 978,
sortable : false,
ignoreCase : true,
sortorder : "desc",
colNames : ['Email Date/Time','User Name', 'Department'] //want to make this dynamic
colModel : [ {
name : 'mailedOn',
index : 'mailedOn',
width : '18%',
align : 'center',
}, {
name : 'userName',
index : 'userName',
width : '18%',
align : 'left',
sorttype : 'text',
}],
rowList:[10,20,30],
pager : '#pager',
rowNum : 10,
altRows : true,
altclass: "myclass",
viewrecords : true
});
});
Any help ??
If you have some fix (known) number of columns and need to change column headers dynamically (change colNames) then I would recommend you to read solution from the answer and try the demo. The question is marked as "duplicate" and my answer have currently no voting so you can not find the answer during searching.
The main idea of my suggestion is usage some generic column names like c1, c2 and so on and modify column headers dynamically inside of beforeProcessing. In the same way one can even make modifications of properties of items of colModel (set formatter, formatoptions, editoptions and so on), but it seems that you don't need currently to do this.

Avoid client-side sorting of rows in JQGrid with Multi Grouping

I've noticed that multi grouping in JQGrid elicits rows sorting to be rearranged inline once the list of values is retrieved through ajax getJSon().
Sometimes the reordering splits groups of the same elements in more than one group, as it should be.
I guess the solution is to avoid client side re-sorting of JQGrid rows, with the aim to definitively reuse the same order given inside the JSON without changes --- as returned by the server.
I'm using the following configuration :
jq("#myGrid").jqGrid({
datatype: 'local',
data: myvar.detail, // a well formatted json locally stored
colNames: [ ....],
colModel: [
{name:'nome_attr',index:'nome_attr', sorttype: function () {return 1;}, editable:true, editrules:{required:true}, editoptions:{size:27}, align:'center'},
{name:'desc_attr', index:'desc_attr', sorttype: function () {return 1;}, editable:true, editrules:{required:false}, edittype: "textarea",editoptions:{rows:5, cols:25}, hidden:true},
{name:'valore',index:'valore', sorttype: function () {return 1;},editable:true, editrules:{required:false}, editoptions:{size:30}, width:120},
....
],
loadonce: false, // to dis-able sorting on client side
sortable: false,
grouping:true,
groupingView : {
groupField : ['nome_attr', 'valore'],
groupColumnShow: [false,false],
groupText : ['{0}'],
groupCollapse: true,
groupDataSorted: false,
groupSorted: false,
groupOrder: false
}
});
Notice (1) I'm already using the workaround to disable the sort type
sorttype: function () {return 1;}
as described here, and that in "#myGrid" is a sub-grid, where the datatype: local, means the rows have been previously retrieved in the container grid.
Does anybody knows which is the configuration of the colModel attribute and the groupingView parameters to be set in order to avoid in-line re-sorting in case of Multi Grouping ?
thanks in advance,
Michele
One workaround to fix the automatic sort is to allow the client to work in order to re-produce the same list of values (recreating the same order).
First, prepare a JScript function forcing the right order value for each grouped column:
/**
* Sort type in subgrid's gropued rows
*/
function sortGroup(cellValus, rowData, ty) {
if(ty==='attribute_1')
return rowData.attr1_order;
else if(ty==='attribute_2')
return rowData.attr2_order;
}
Second, inject the desired order values in the colModel.
Third, trigger the previous function inside the sorttype in each grouped column, using the column type to know which group the order belongs:
colModel: [
{name:'nome_attr',index:'nome_attr', sorttype: function (cellValus, rowData) {return sortGroup(cellValus, rowData, 'attribute_1')}, editable:true, editrules:{required:true}, editoptions:{size:27}, align:'center'},
{name:'desc_attr', index:'desc_attr', editable:true, editrules:{required:false}, edittype: "textarea",editoptions:{rows:5, cols:25}, hidden:true},
{name:'valore',index:'valore', sorttype: function (cellValus, rowData) {return sortGroup(cellValus, rowData, 'attribute_2')},editable:true, editrules:{required:false}, editoptions:{size:30}, width:120},
.....
{name:'attr1_order',index:'attr1_order', editable:false, hidden:true},
{name:'attr2_order',index:'attr2_order', editable:false, hidden:true}
]

extjs4 grid - changing column editor per row basis

ExtJS4 grid anticipates appropriate editor (cellEditor or rowEditor) per column.
If a column's header field is dateField - date selector will be applied on every row in that column.
What I need is an editor with different field editors per row, not per column.
The Extjs3 solution is provided here - unfortunately doesn't fit in Extjs4 case.
(please check that link to see explanatory images, cause I can't post images yet)
There's also a single column solution called property grid, but again - it supports only one column and is very deviated from the standard Ext.grid component
I have tried manually changing grid editor by customizing column.field and reloading grid.editingPlugin.editor, but always get a blank rowEditor panel with no fields.
//by default rowEditor applies textField to all cells - I'm trying to force custom numberFiled on apropriate row
var numberField=Ext.form.field.Number();
grid.columns[0].field=numberField;
//destroy current rowEditor's instance
delete grid.editingPlugin.editor;
//now, upon doubleClick on apropriate cell it should reinitialize itself (initEditor()) - and it does, but is an empty panel
what am I missing here? once I delete editingPlugin.editor everything should start from the beginning like during the first time rowEditor is called, but it looses all the fields
Solution for Ext4:
I was looking for a solution for this and this guy said the property grid has this behavior.
I have adapted it to work in a clean way for me
on initComponent I declared:
this.editors = {
'date' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Date', {selectOnFocus: true})}),
'string' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Text', {selectOnFocus: true})}),
'number' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Number', {selectOnFocus: true})}),
'int' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Number', {selectOnFocus: true})}),
'boolean' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.ComboBox', {
editable: false,
store: [[ true, 'Sim' ], [false, 'Não' ]]
})})
};
I used these functions to help me (copied):
this.renderCell = function(val, meta, rec) {
var result = val;
if (Ext.isDate(val)) {
result = me.renderDate(val);
} else if (Ext.isBoolean(val)) {
result = me.renderBool(val);
}
return Ext.util.Format.htmlEncode(result);
};
this.getCellEditor = function(record, column) {
return this.editors[record.get('type')];
};
And finally, associate these functions to the column:
{text: "Valor", name : 'colunaValor', width: 75, sortable: true, dataIndex: 'valor', width:200,
renderer: Ext.Function.bind(this.renderCell, this),
getEditor: Ext.Function.bind(this.getCellEditor, this)
}

Resources