I want to use by default all the datas from rowData, I do not want use specific values. Do you know how to unify columnDefs for both examples?
1st example:
columnDefs = [
{headerName: 'make', field: 'make' },
{headerName: 'model', field: 'model' },
{headerName: 'price', field: 'price'}
];
rowData = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 }
];
2nd example:
columnDefs = [
{headerName: 'name', field: 'name' },
{headerName: 'phone', field: 'phone' },
];
rowData = [
{ name: 'Manuel', phone: 35000 },
{ name: 'Maria', phone: 32000 },
{ name: 'John', phone: 72000 }
];
I have one idea, but dont exactly know if it is more elegant.
var columnDefs = [
{ headerName: "make", field: "make" },
{ headerName: "model", field: "model" },
{ headerName: "price", field: "price" }
];
var rowData = [
{ make: "Toyota", model: "Celica", price: 35000 },
{ make: "Ford", model: "Mondeo", price: 32000 },
{ make: "Porsche", model: "Boxter", price: 72000 }
];
genColums() {
let columsDef = [];
for (var prop in rowData[0]) {
columsDef.push({
headerName: prop,
field: prop
});
}
console.log(columsDef);
}
this.genColums();
PS. this work, if all data same, in each object
Related
In eCharts, how do I modify the following option to show multiple lines in the chart? What I want is one line for product "Matcha Latte" and one line for "Cheese Cocao"? I would like to keep the dataset unchanged if possible.
option = {
legend: {},
tooltip: {},
dataset: {
dimensions: [{name:'product', type:'ordinal'}, {name:'date'},
{name:'value'}],
source: [
{product: 'Matcha Latte', 'date': 2016, 'value': 85.8},
{product: 'Matcha Latte', 'date': 2017, 'value': 73.4},
{product: 'Cheese Cocoa', 'date': 2016, 'value': 65.2},
{product: 'Cheese Cocoa', 'date': 2017, 'value': 53.9}
]
},
xAxis: {type: 'category', name: 'date'},
yAxis: {type: 'value', name: 'value'},
series: [
{type: 'line', encode: {x: 'date', y:'value'}},
]
};
you can you transform the dataset by using a filter:
option = {
legend: {},
tooltip: {},
dataset: [
{
dimensions: [
{ name: 'product', type: 'ordinal' },
{ name: 'date' },
{ name: 'value' }
],
source: [
{ product: 'Matcha Latte', date: 2016, value: 85.8 },
{ product: 'Matcha Latte', date: 2017, value: 73.4 },
{ product: 'Cheese Cocoa', date: 2016, value: 65.2 },
{ product: 'Cheese Cocoa', date: 2017, value: 53.9 }
]
},
{
fromDatasetIndex: 0,
transform: [
{
type: 'filter',
config: {
dimension: 'product',
value: 'Matcha Latte'
}
}
]
},
{
fromDatasetIndex: 0,
transform: [
{
type: 'filter',
config: {
dimension: 'product',
value: 'Cheese Cocoa'
}
}
]
}
],
xAxis: { type: 'category', name: 'date' },
yAxis: { type: 'value', name: 'value' },
series: [
{ datasetIndex: 1, type: 'line', encode: { x: 'date', y: 'value' } },
{ datasetIndex: 2, type: 'line', encode: { x: 'date', y: 'value' } }
]
};
I need to autosize the columns width based on content. All columns resize just fine except for the groupColumnDef, for some reason the actualSize value is a lot smaller than what it should be.
I did not set minWidth/width/maxWidth in the column def.
What could be the issue?
// grid.component.html
<div style="text-align:center">
ag-grid Example
</div>
<ag-grid-angular #agGrid style="width: 100%; height: 500px;" class="ag-theme-balham" [gridOptions]="gridOptions"
(gridReady)="onGridReady($event)">
</ag-grid-angular>
// employee.ts
export interface Employee {
name: string;
age: number;
country: string;
year: number;
date: number;
month: string;
ssn: number;
address: string;
zipCode: number;
occupation: string;
employer: string;
employerAddress: string;
mobNum: number;
}
// grid-component.ts
import { Component, OnInit } from '#angular/core';
import { GridOptions } from 'ag-grid-community';
import { Employee } from './models/employee';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class GridComponent implements OnInit {
gridOptions: GridOptions;
constructor() {}
ngOnInit() {
this.setGridOptions();
}
setGridOptions() {
this.gridOptions = {
suppressColumnVirtualisation: true
} as GridOptions;
}
onGridReady(params) {
this.setData();
}
setData() {
this.gridOptions.api.setColumnDefs(this.getColumnDefinitions());
this.gridOptions.api.setRowData(this.getData());
this.autoSizeAll();
this.gridOptions.api.refreshCells();
}
getColumnDefinitions(): Array<any> {
return [
{
field: 'name',
headerName: 'Name'
},
{
field: 'age',
headerName: 'Age'
},
{
field: 'country',
headerName: 'Country'
},
{
headerName: 'Birth Day',
children: [
{
headerName: 'Year',
field: 'year'
},
{
headerName: 'Month',
field: 'month'
},
{
headerName: 'Date',
field: 'date'
}
]
},
{
field: 'ssn',
headerName: 'Social Security Number'
},
{
field: 'address',
headerName: 'Address'
},
{
field: 'zipCode',
headerName: 'Zip Code'
},
{
headerName: 'Occupation Details',
children: [
{
field: 'occupation',
headerName: 'Occupation'
},
{
field: 'employer',
headerName: 'Employer'
},
{
field: 'employerAddress',
headerName: 'Employer Address'
},
]
},
{
field: 'mobNum',
headerName: 'Mobile Number'
}
];
}
getData(): Employee[] {
return [
{
name: 'Mary Smith',
age: 25,
country: 'Australia',
year: 1990,
date: 14,
month: 'March',
ssn: 1234542792102229,
address: '31 Rainbow Rd, Towers Hill, QLD 4820 31 Rainbow Rd, Towers Hill, QLD 4820',
zipCode: 11350,
occupation: 'Engineer',
employer: 'MicroSoft',
employerAddress: '245 Rainbow Rd, Microsoft, Towers Hill, QLD 4820',
mobNum: 7156662910
},
{
name: 'Jeff Martin',
age: 30,
country: 'UK',
year: 1987,
date: 24,
month: 'December',
ssn: 1234542792102229,
address: '31 Rainbow Rd, Towers Hill, QLD 4820',
zipCode: 11350,
occupation: 'UI/UX Designer',
employer: 'Facebook India',
employerAddress: '17 Rainbow Rd, Towers Hill, QLD 4820',
mobNum: 7158462910
}
];
}
autoSizeAll() {
const allColumnIds = [];
this.gridOptions.columnApi.getAllColumns().forEach((column: any) => {
allColumnIds.push(column.colId);
});
this.gridOptions.columnApi.autoSizeColumns(allColumnIds);
}
}
Here what I have done is
In html - Bind gridOptions and onGridReady event
In Component
Initialize the grid options and set suppressColumnVirtualisation = true.
When the grid is ready set data to the grid by setting the column definitions and then row data.
Get the column ids of all the columns in the grid and set them in grid api autoSizeColumns.
autoSizeColumns() looks only at the cells already rendered on the screen. Therefore the column width is set based on what it sees. This happens due to column virtualization. So the columns not visible on the screen will not auto size.
This behavior can be bypassed simply by setting suppressColumnVirtualisation = true
Note that grid use this column virtualization to improve the
performance of the grid when there are large amount of columns to be
rendered.
I want to add a new element in AG Grid. I have a following model:
export class PersonModel {
cars: CarModel[];
}
The AG Grid has as rowData the array Cars of my model. But this array is not Observable. Now I want to add a new car when I click a button:
<button type="button" (click)="onClickCreateCar()">
And in my viewmodel:
onClickCreateCar() {
var emptyCar = new CarModel();
this.person.cars.push(emptyCar);
}
I can not see the new row in the grid because the array Cars is not observable. It is ok because the property of a model should not be observable. How do you fix the problem?
My AG-Grid definition:
<ag-grid-angular class="ag-theme-fresh" *ngIf="person" style="height: 100%; width: 100%;" [gridOptions]="gridOptions" [rowData]="person.cars" [columnDefs]="columnDefs">
For insert a new row into ag-grid you shouldn't use the rowData directly it will create\override existing object and all states would be reset, and anyway, there is a method for it setRowData(rows)
But I'd recommend to use updateRowData(transaction):
updateRowData(transaction) Update row data into the grid. Pass a transaction object with lists for add, remove and update.
As example:
gridApi.updateRowData({add: newRows});
for angular:
set id for html - selector (#agGrid in this example):
<ag-grid-angular
#agGrid
style="width: 650px; height: 500px;"
class="ag-theme-balham"
[rowData]="rowData"
[columnDefs]="columnDefs"
>
</ag-grid-angular>
and then define the viewchild with this id, import AgGridAngular like shown below, then you can use the ag-grid api in Angular
import {Component, OnInit, ViewChild} from '#angular/core';
import { AgGridAngular } from 'ag-grid-angular';
#Component({
selector: 'app-angular-handsometable',
templateUrl: './angular-handsometable.component.html',
styleUrls: ['./angular-handsometable.component.scss']
})
export class AngularHandsometableComponent implements OnInit {
#ViewChild('agGrid') agGrid: AgGridAngular;
columnDefs = [
{headerName: 'Make', field: 'make', sortable: true, filter: true, editable: true },
{headerName: 'Model', field: 'model', sortable: true, filter: true, editable: true },
{headerName: 'Price', field: 'price', sortable: true, filter: true, editable: true }
];
rowData = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 },
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 },
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 },
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 }
];
constructor() { }
ngOnInit() {
}
save() {
console.log( 'Save', this.rowData );
}
addRow() {
this.agGrid.api.updateRowData({
add: [{ make: '', model: '', price: 0 }]
});
}
}
Make sure your rowData array is getting updated with the new object you added and if its getting updated and its just a question of updating the grid view, you can explicitly call the refresh API's of the grid.
https://www.ag-grid.com/javascript-grid-api/#refresh
I visited ag-grid documentation and got rowData is simple array. If ag-grid not refreshing your dom then may be they want a fresh array. You can do like this:
this.person.cars = [this.person.cars.slice(0), yourNewCarObj];
I am using the Sencha Touch 2.0 KitchenSink example to try to learn some of the basics. I am getting stuck on chained selectfields though.
I am going off the tutorial here but with the different setup I am being thrown off. The code below runs perfectly in the Forms.js file in kitchensink, but I am missing on the actual chainedselect part of it.
EDIT: What I am asking is how to make chained selectfields. I have the datastores and the selectfields in the example code, but not a working chained selectfield from first to second.
Ext.regModel('First', {
idProperty: 'FirstID',
fields: [{
name: 'FirstID',
type: 'int'
}, {
name: 'FirstName',
type: 'string'
}]
});
Ext.regModel('Second', {
idProperty: 'SecondID',
fields: [{
name: 'SecondID',
type: 'int'
},{
name: 'FirstID',
type: 'int'
}, {
name: 'SecondName',
type: 'string'
}]
});
var firstStore = new Ext.data.Store({
model: 'First',
data: [{
FirstID: 1,
FirstName: 'Kenworth'
}, {
FirstID: 2,
FirstName: 'Peterbilt'
}],
autoLoad: true
});
var secondStore = new Ext.data.Store({
model: 'First',
data: [{
SecondID: 1,
FirstID: 1,
SecondName: 'T800'
}, {
SecondID: 2,
FirstID: 1,
SecondName: 'T700'
}, {
SecondID: 3,
FirstID: 1,
SecondName: 'T660'
}, {
SecondID: 4,
FirstID: 1,
SecondName: 'T470'
}],
autoLoad: true
});
Ext.define('Kitchensink.view.Forms', {
extend: 'Ext.tab.Panel',
requires: [
'Ext.form.Panel',
'Ext.form.FieldSet',
'Ext.field.Number',
'Ext.field.Spinner',
'Ext.field.DatePicker',
'Ext.field.Select',
'Ext.field.Hidden'
],
config: {
activeItem: 0,
tabBar: {
// docked: 'bottom',
ui: 'dark',
layout: {
pack: 'center'
}
},
items: [
{
title: 'Basic',
xtype: 'formpanel',
id: 'basicform',
iconCls: 'refresh',
items: [
{
xtype: 'fieldset',
title: 'Enter Data',
instructions: 'Please enter the information above.',
defaults: {
labelWidth: '35%'
},
items: [
{
xtype: 'selectfield',
name: 'firstfield',
label: 'First',
store: firstStore,
displayField: 'FirstName',
valueField: 'FirstID'
}, {
xtype: 'selectfield',
name: 'secondfield',
label: 'Second',
store: secondStore,
displayField: 'SecondName',
valueField: 'SecondID'
}
]
}
]
}
]
},
onFirstChange: function(selectField, value){
var secondSelectField = this.items.get(1);
secondSelectField.store.clearFilter(); // remove the previous filter
// Apply the selected Country's ID as the new Filter
secondSelectField.store.filter('FirstID', value);
// Select the first City in the List if there is one, otherwise set the value to an empty string
var firstValue = secondSelectField.store.getAt(0);
if(firstValue){
secondSelectField.setValue(firstValue.data.SecondID);
} else {
secondSelectField.setValue('');
}
}
});
I have a Dojo-DataGrid which is programatically populated as below :
var jsonStore = new dojo.data.ItemFileWriteStore({ url: "json/gaskets.json" });
var layout= [
{ field: "description", width: "auto", name: "Tier/Description", editable:true },
{ field: "billingMethod", width: "auto", name: "Billing Method", editable: true,
type: dojox.grid.cells.Select, options: [ '0', '1' ] },
{ field: "offeringComponents", width: "auto", name: "Offering Component", editable: true,
type: dojox.grid.cells.Select, options: [ '0', '1' ] },
{ field: "serviceActivity", width: "auto", name: "Service Activity", editable: true,
type: dojox.grid.cells.Select, options: [ '0', '1' ] },
{ field: "hours", width: "auto", name: "Hours" },
{ field: "rate", width: "auto", name: "Rate <br/> (EUR)" },
{ field: "cost", width: "auto", name: "Cost <br/> (EUR)" },
{ field: "price", width: "auto", name: "Price <br/> (EUR)" },
{ field: "gvn", width: "auto", name: "Gvn" }
];
grid = new dojox.grid.DataGrid({
query: { description: '*' },
store: jsonStore,
structure: layout,
rowsPerPage: 20
}, 'gridNode');
The options for the field billingMethod (Currently defined as dojox.grid.cells.Select) are hard coded right now, but I would like to get those values dynamically from the backend as JSON. But dojox.grid.cells.Select currently(I am using Dojo 1.5) does not have a option to define a "store".
I am trying to use dijit.form.FilteringSelect, but this needs a id(of a Div) for its constructor and I cannot specify one as this select box has to go with in the grid, rather than a separate DIV.
Thanks
Sandeep
Your answer works fine, the issue is that in the combo the user can select A, but once the combo lose the focus, the value 1 will be shown. Some months ago I had the same problem, and I got a solution from KGF on #dojo. The idea is to have a formatter on the cell that just creates a SPAN element, and then it invokes a query over the store to get the label of the selected element and put it on the SPAN. I modified your example to get that working.
dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dojox.grid.cells.dijit");
dojo.require("dojox.grid.DataGrid");
dojo.require("dijit.form.Select");
dojo.require('dojox.grid.cells.dijit');
dojo.require('dijit.form.FilteringSelect');
var grid;
var jsonStore;
dojo.addOnLoad(function() {
jsonStore = new dojo.data.ItemFileWriteStore({
data: {
"identifier": "identify",
"label": "description",
"items": [
{
"identify": 123,
"description": "Project Manager"},
{
"identify": 234,
"description": "Developer"},
{
"identify": 536,
"description": "Developer",
"billingMethod":2}
]
}
});
var myStore = new dojo.data.ItemFileReadStore({
data: {
identifier: 'value',
label: 'name',
items: [{
value: 1,
name: 'A',
label: 'A'},
{
value: 2,
name: 'B',
label: 'B'},
{
value: 3,
name: 'C',
label: 'C'}]
}
});
//[kgf] callback referenced by formatter for FilteringSelect cell
function displayValue(nodeId, store, attr, item) {
if (item != null) { //if it's null, it wasn't found!
dojo.byId(nodeId).innerHTML = store.getValue(item, attr);
}
}
var layout = [
{
field: "identify",
width: "auto",
name: "Id 2 Hide",
hidden: true},
{
field: "description",
width: "auto",
name: "Tier/Description",
editable: true},
{
field: 'billingMethod',
name: 'Billing Method',
editable: true,
required: true,
width: '150px',
type: dojox.grid.cells._Widget,
widgetClass: dijit.form.FilteringSelect,
widgetProps: {
store: myStore
},
formatter: function(data, rowIndex) { //[kgf]
//alert("data "+data)
var genId = 'title' + rowIndex;
var store = this.widgetProps.store;
var attr = "label";
setTimeout(function() {
store.fetchItemByIdentity({
identity: data,
onItem: dojo.partial(displayValue, genId, store, attr)
});
}, 50);
//for now return a span with a predetermined id for us to populate.
return '<span id="' + genId + '"></span>';
}
}
];
grid = new dojox.grid.DataGrid({
query: {
description: '*'
},
store: jsonStore,
singleClickEdit: true,
structure: layout,
rowsPerPage: 20
}, 'gridNode');
grid.startup();
});
I was finally able to figure this out..Incase someone wants to implement same kind of stuff using DOJO Datagrid+FilteringSelect.
Sample Code
dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dojox.grid.cells.dijit");
dojo.require("dojox.grid.DataGrid");
dojo.require("dijit.form.Select");
dojo.require('dojox.grid.cells.dijit');
dojo.require('dijit.form.FilteringSelect');
var grid;
var jsonStore;
dojo.addOnLoad(function() {
jsonStore = new dojo.data.ItemFileWriteStore({
data: {
"identifier": "identify",
"label": "description",
"items": [
{
"identify": 123,
"description": "Project Manager"},
{
"identify": 234,
"description": "Developer"},
{
"identify": 536,
"description": "Developer"}
]
}
});
var myStore = new dojo.data.ItemFileReadStore({
data: {
identifier: 'value',
label: 'name',
items: [{
value: 1,
name: 'A',
label: 'A'},
{
value: 2,
name: 'B',
label: 'Y'},
{
value: 3,
name: 'C',
label: 'C'}]
}
});
var layout = [
{
field: "identify",
width: "auto",
name: "Id 2 Hide",
hidden: true},
{
field: "description",
width: "auto",
name: "Tier/Description",
editable: true},
{
field: 'billingMethod',
name: 'Billing Method',
editable: true,
required: true,
width: '150px',
type: dojox.grid.cells._Widget,
widgetClass: dijit.form.FilteringSelect,
widgetProps: {
store: myStore
}}
];
grid = new dojox.grid.DataGrid({
query: {
description: '*'
},
store: jsonStore,
singleClickEdit: true,
structure: layout,
rowsPerPage: 20
}, 'gridNode');
grid.startup();
});