React Material Data Grid: Sorting a currency field - material-ui

I am passing in rows of financial data to a React MUI Data Grid component, however, as a currency symbol exists within the cell data the default sorting function is not working. Is there anyway I can ignore the currency symbol when applying sort?
[
{id: 0, cpa: '£20', cpl: '£0', revshare: '0%', startDate: '02/03/2022'}
{id: 1, cpa: '£10', cpl: '£0', revshare: '0%', startDate: '02/02/2022'}
]
<DataGrid
disableSelectionOnClick
headerHeight={65}
rowHeight={70}
autoHeight
className={classes.root}
rows={displayRowData(rowsData)}
columns={columns}
/>

You can add a custom sortComparator in the columns of your <DataGrid/>.
Assuming your currency symbol is always the first character, your cpa column definition would look like this:
const columns = [
...
{
field: "cpa",
headerName: "cpa",
sortComparator: (a: string, b: string) =>
Number(a.slice(1)) - Number(b.slice(1)),
},
...
];
For more information regarding sorting I would recommend checking out the official documentation.

Related

Proper custom component with complex data in it

I have following interface:
export interface Product {
name: string;
provider: {
name: string;
logo: string;
};
pricePerUnit: {
quantity: number;
currency: string;
};
}
And my rowData looks like this:
rowData = [
{
name: 'Fish',
provider: {
name: 'Amazon',
logo: 'url to amazon logo',
},
pricePerUnit: {
quantity: 5,
currency: 'USD',
},
},
]
So, as you can see i have at least 2 complex object here, and by design I should display provider as img + name and price as quantity + currency symbol.
I`m using custom angular components for that with styling.
Actual problem
In order to provide these object to my custom components, I set field property in colDefs as follow (example for price):
{
headerName: 'Price',
field: 'pricePerUnit',
cellRenderer: PriceCellRendererComponent,
},
And here is the catch, because I specified in field property complex object, I no longer able to visualize data using integrated charts, because for them to work I should specify in my field propery path to number itself, like so:
{
field: 'pricePerUnit.quantity',
}
But now I`ve broke my custom component because params.value now holds just a number and not my complex object. Same goes to provider.
And it`s also broke grouping, sorting, filtering.
html template for one of my custom component (provider) looks like so:
<div class="wrapper provider">
<tui-avatar [avatarUrl]="params.value.logo" class="provider__logo"></tui-avatar>
<div class="provider__name">{{params.value.name}}</div>
</div>
So the question is:
How to properly setup custom components, so they would work in grouping, sorting, filtering and also integrated charts would use just simple primitive like number to correctly display data?

Can Autocomplete component have different value and option types?

As per docs, Autocomplete component has no distinction between option and actual value.
I have a list of options as objects with ids. When I select an option I want to get its id as a value, not the object itself. Also, when I set the value of Autocomplete I want to pass in id only.
Is it possible?
<Autocomplete
options={[{id: 1, label: 'foo'}, {id: 2, label: 'bar'}]}
value={1}
onChange={(_, value) => { /* value should be number (id) */ }}
/>
Update: option label should remain configurable
Ciao, unfortunately value on onChange event returns one of the options selected. So is not possible to return only one attribute of the element.
The only thing you can do is take the value.id:
<Autocomplete
options={[
{ id: 1, label: "foo" },
{ id: 2, label: "bar" }
]}
getOptionLabel={(option) => option.label} // this to show label on Autocomplete
getOptionSelected={(option, value) => option.id === value.id} // this to compare option on id value
onChange={(event, value) => console.log(value.id)} // here access to id property of value object
...
/>
Here a codesandbox example.

Ag-Grid Server Side Row Group Key Creator

When using Ag-Grid's server side row model, I am unable to send a custom group key to the server in order to do proper group by queries.
My row data is a simple JSON structure but with one composite object.
row = {
athlete: '',
age: '',
country: {
name: 'Ireland',
code: 'IRE'
},
...
}
I am using the server side row model. To get the grid to display the country name is simple enough as I use the following column definition.
{
headerName: "Country",
colId: "country",
valueGetter: "data.country.name",
enableRowGroup: true
}
However, when I group by the Country column ag-grid sends the groupKey as 'Ireland' from my example above. But I need the group key to be the country code, 'IRE'. I cannot figure out how to generate a groupKey when using the server-side row model.
I have seen the keyCreator method, but this only works for client-side row model. In addition, I have seen the Tree Data Mode which has a callback for getServerSideGroupKey(dataItem) but then callback only gets used when gridOptions.treeData = true and when the treeData option is set to true, a "Group" column is always displayed regardless if a grouping is happening or not. I tested this out by setting isServerSideGroup: function(dataItem) {return false;}
Any help would be appreciated.
I was able to solve this issue by using the dot notation for the column definition's field attribute and a custom cellRenderer.
{
headerName: "Country",
colId: "country",
field: "country.code",
enableRowGroup: true,
cellRenderer: function (params) {
return params.data.country.name;
}
}
This allowed me to display the correct data point from the custom object and when doing server side actions, ag-grid will send the datapoint contained within the field attribute.

AG-GRID Default Sort Model with Dynamic Column Defs

So I have a Grid setup that works with the Enterprise Row Model.
The columns are very dynamic and so the column defs are not known until the first query for rows is made to the server. This all works fine, but how can I set a default sort state when the column defs are not set until after the request has succeeded?
Once the grid has been set-up with the column defs you can just set the sort on any column
gridOptions.columnApi.getColumn(COLUMN_NAME).setSort("asc")
Adding a sort attribute to your colDef works too.
Example:
const columnDefs = [
{
headerName: 'Created Date',
field: 'CreateDate',
sort: 'desc',
sortingOrder: ['desc','asc'] //optional but for better sorting behaviour
}
]
Try this
const sort = [
{
colId: "firstName",
sort: "asc",
},
{
colId: "lastName"
},
];
this.gridApi.setSortModel(sort);

Posting limited fields with ExtJS 4.2.x REST on store update

We are trying to use ExtJS grid/forms and bind them with Store to perform REST operations.
Now as I was playing with extjs examples for restful api, I came across http://docs.sencha.com/extjs/4.2.1/#!/example/restful/restful.html and tried editing a model to add a new field 'phone' in the list like below:
Ext.define('Person', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int',
useNull: true
}, 'email', 'first', 'last','phone'],
validations: [{
type: 'length',
field: 'email',
min: 1
}, {
type: 'length',
field: 'first',
min: 1
}, {
type: 'length',
field: 'last',
min: 1
}]
});
As you can see "phone" is a new field added in fields list of a model and after adding that field while I was trying to perform any of the rest operation (PUT/POST) it was posting that field along with rest of the visible fields in grid. This is something I have not expected.
Is there anyway by which I can just post dirty fields (which are modified) and not all those exist in model with default store/rest manipulation way that ExtJS has provided?
In the proxy writer definition you would want to use the writeAllFields param which will work for updates. New model instances will send all fields.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.writer.Writer-cfg-writeAllFields