How do you call a function in a react-table accessor? (reactjs) - reactjs

I am modifying a ReactJS component. I have added a react-table to get the pagination, which works beautifully. But one of the columns in the table needs to call a function that is also in this component, so it can render a link depending on the content of that record. (Some results will render a link, some will not.) When I list the function in the accessor property of the column, it returns some of the values from the function, but not all of them. So, the link comes back as:
localhost:3000/view/c/IDnumber/undefined.
Both the IDnumber and query should be returned, but the query parameter is "undefined".
I've tried listing the function in the accessor like:
getSerialNo(hit,query)
But then I get "hit is not defined".
I've searched on this site and others to find a solution.
The column looks like:
{id:'serialno',
Header: "Serial #",
accessor: getSerialNo
}
The function, in part, looks like:
const getSerialNo = (hit, query) => {
const linkAs = '/view/c/${hit._id}/${query}'
return <Link href={link} as={linkAs}><a target="_blank">{serialNo}
</a></Link>
I would like to get back a link that actually includes the query, like:
localhost:3000/view/c/IDnumber/query

according to documentation
accessor: String | Function
Required This string/function is used to
build the data model for your column. The data returned by an accessor
should be primitive and sortable. If a string is passed, the column's
value will be looked up on the original row via that key, eg. If your
column's accessor is firstName then its value would be read from
row['firstName']. You can also specify deeply nested values with
accessors like info.hobbies or even address[0].street If a function is
passed, the column's value will be looked up on the original row using
this accessor function, eg. If your column's accessor is row =>
row.firstName, then its value would be determined by passing the row
to this function and using the resulting value.
Its accept both string or function but make sure you set the id, you can do any operation on the row like row.attrbuiteName === null ? "no thing" : row.attrbuiteName
{
id:'serialno',
Header: "Serial #",
accessor: row => row.attrbuiteName
}
Reference:
https://github.com/tannerlinsley/react-table/blob/master/docs/api.md
Note in case using the function you must provide id in row

Yes, as mentioned above, you can call a function inside an accessor like so:
{
Header: 'Column header',
accessor: (row) => {
// some function that returns a primitive value you want to display in the cell
},
},
I'm adding an updated link to documentation as the one above does not seem to work anymore.

Related

React Table toggleRowExpanded not working

We are using react-table and we would like to collapse/expand the next available row in the react-table. For this, we are using react-table toggleRowExpanded passing row-id as the first param. This function isn't working as expected.
toggleRowExpanded([id], true);
Any help is appreciated.
As from react-table documentation, toggleRowExpanded is a function to toggle whether 'a' row is expanded or not. toggleRowExpanded expects a single rowId rather than an array of ids and an optional isExpanded boolean value which is the status of that single row.
In the example codesandbox shared, 2 changes to note :
rowId is not the id from the data - but the id of the row in the table - which will be the index in this case
toggleRowExpanded function is to be called separately for each row.
For the example to work,
data.forEach((val, index) => {
toggleRowExpanded(index, isEven ? index%2 === 0 : false);
})

React Table: Filtering specific columns within a Global Filter

I'm currently attempting to build an Airtable-esque filter component. I'm wondering if it is possible to use the useGlobalFilter hook to choose what columns to filter a table by programmatically. For example, Airtable implements table filtering using a component that lives outside of a given table's boundaries. Inside of this component, there is a dropdown menu to choose which column to apply a filterValue and a dropdown to choose the filterType for a given column. Based on react-table's documentation, it appears that useGlobalFilter is used to build filtering components that exist outside of the table. However, based on the documentation's code sandbox example, for filtering, it also appears that useGlobalFilter applies the filter value to all columns rather than to specific columns.
My question would be if it's possible to use useGlobalFilter's ability to create filtering UI outside of a table and have a way to select what columns to apply a filterValue & filterType, all from within the global filter?
If this is possible, would anyone be willing to provide tips or advice on the implementation? Please let me know if this task would be more suited for useFilter or another part of react-table's API.
I've provided a screenshot of Airtable's filter component as an example of what I'd like to build. Any feedback or advice would be much appreciated!
`const columns = React.useMemo(
() => [
{
Header: 'Group Name',
accessor: 'name',
// disableGlobalFilter: true
},
{
Header: 'Created',
accessor: 'sector',
disableGlobalFilter: true,
},
],
[]
)`
Add this in the column array inside the column where you want to disable global filter

How to access a cell value when the column has been defined with ag-grid value getters?

If the ag-grid column definition has been defined with a value getter , the value gets displayed fine on the grid. However I was not able to find a way to access a value in a given cell if the cell is using cell value getters. Was trying to access the data through api.forEachNode, but it doesnt show the data. The only way I found was to export the data as CSV and then parse it using getDataAsCsv(params).
Is exporting the data the only way to access value of a column in a grid with a value getter?
Thanks in advance:)
You can always add a new property to your data.
Let's say I have a derived column to show the row index, where I am just returning row index.
Before returning from value getter, I can add this index to a new property called 'special'
{
headerName: 'Special',
maxWidth: 100,
valueGetter: function(params) {
params.node.data.special = params.node.rowIndex; // added property called special
return params.node.rowIndex;
}
},
You can now access this in api.forEachNode by doing -
this.gridApi.forEachNode(function(rowNode, index) {
console.log(rowNode.data.special);
}

Filter input render bug in React-Table with expanded

I have some troube to understand the behavior I observe.
I use pivot and filter function with React-Table (v6), and I want to expand my row when the filter match with a subrow value.
I achieved the expand of the row but when I entered a value (in a input filter) present in subrow the input filter is not changed (like rerender to empty) ...
It's look like the setState reset the input field.
The state.expended is an object which contains index with a boolean to specify if the row is expanded or not.
I upload a sample of my problem of codesanbox here, I reproduce the problem:codesandbox.io
I encountered a problem when, after using the filter, the extensions began to work incorrectly. Perhaps a subrow will help you:
getSubRows: (row) => row.subRows
useTable(
{
columns: columns,
data: data,
defaultColumn: {
Filter: ''
},
initialState: {},
getSubRows: (row) => row.subRows
},
useExpanded,
useFilters
);

Select Grouping Row in ag-Grid

I'm wondering if there's a way to select the "Grouping" row in ag-grid.
For example, in the example shown on the website:
http://www.ag-grid.com/angular-grid-grouping/index.php
You can set the "rowSelection" parameter to "single" in order to highlight an entire row at the lowest node. However, that does not allow you to highlight the "Country" row.
In the example, the only way to do this is to "select all" the elements below that row.
Thanks!
According to the documentation, setting the grid option groupSelectsChildren to false will make the grouping row selectable, independently from its children.
groupSelectsChildren: When true, selecting a group will have the
impact of selecting all it's children. The group will then display
'selected' when all children are selected, 'unselected' when none are
selected and 'intermediate' when children have a mix of selected and
unselected. When the node is selecting children, it will never appear
in the selected set when calling api.getSelectedNodes(). When false,
then the group is selectable independently of the child nodes. When
selecting the group node independently of the children, it will appear
in the set when calling api.getSelectedNodes().
I had the same problem so I worked around it by emulating the look-and-feel of selecting rows.
In your columnDefs object, add the cellClassRules attribute to EVERY column definition (so every cell will be highlighted, making it appear that the row itself is highlighted when you click on it):
var columnDefs = [
{ headerName: "#1", cellClassRules: { rowSelected: CustomRowStyle }, field: "Col1" },
{ headerName: "#2", cellClassRules: { rowSelected: CustomRowStyle }, field: "Col2" },
{ headerName: "#3", cellClassRules: { rowSelected: CustomRowStyle }, field: "Col3" }
]
Then add an event listener for onCellClicked in your gridOptions object:
onCellClicked: function(cell) {
SelectedRowIndex = cell.rowIndex;
$scope.gridOptions.api.refreshView();
}
In your controller, define a variable called SelectedRowIndex:
var SelectedRowIndex; // this will contain the currently selected row number
Now create a function called CustomRowStyle which is called by ag-grid each time it is about to render a cell on-screen. This function will check if the cell is in the same row as the SelectedRowIndex (based on which row the user last clicked on) to determine if the cell should appear with the rowSelected class.
function CustomRowStyle(params) {
return params.rowIndex === SelectedRowIndex
}
Finally, define a rowSelected class with your selected row CSS:
.rowSelected {
background-color: silver !important;
}
Whichever row you click on (whether it's a group item or a child item) will appear with the rowSelected CSS. Your controller can always know which row is currently selected by checking the SelectedRowIndex variable.
This probably won't work for all cases but I found that as of version 20.2.0 RowNode's have a 'parent' property (Note: I'm not saying that feature was added in 20.2.0, just that I haven't gone and checked previous versions). So I do this:
api.getRowNode('child-row-id').parent.setSelected(true)
Obviously depending on how many levels of grouping you have and how dynamic that is (i.e. can the user change the grouping configuration, can you have n levels of grouping, etc.) you'll need to detect and adjust, but this works well for my particular use case of remembering what was selected and reselecting it on page refresh because my grid always starts out in the same grouping state on page load.
set groupSelectsChildren={false} and use this code onRowClicked={this.onRowClicked}
use any unique data identifier for selecting the node.
onRowClicked = (row) =>{
let that = this;
this.gridApi.forEachNode(node =>{
if(node.data.id === row.data.id) { that.gridApi.selectNode(node,true);}
});
}

Resources