I am new to react virtualized concepts and am using a RV Table decorated with Autosizer to display contents from my list. Currently, when I select a row, I dispatch an action to react-redux to update the state in store based on selected row data. This seems to work. I would also like to add a visual cue of "row selected" like a background color or text color and I have not been able to achieve that.
I tried using the rowRenderer function to set style but it does not seem to be working. Can someone share a simple example of how I can change the selected row on a RV table? When I select it once, I want the color changed and reselecting the same row should undo the color background.
Below is the working example to highlight row on selection. To deselect highlighted row, you can tweak logic in rowStyleFormat function
import React from 'react'
import { Column, Table } from "react-virtualized";
import "react-virtualized/styles.css";
class TestTable extends React.Component {
constructor(props) {
super(props);
this.state = {
index: -1,
data: [
{ 'rank': 1, 'player': 'Michael Jordan', 'points': 30 },
{ 'rank': 2, 'player': 'Wilt Chamberlain', 'points': 30 },
{ 'rank': 3, 'player': 'Bill Russell', 'points': 15 },
]
}
}
handleRowSelect(event) {
this.setState(
{
index: event.index
}
)
}
rowStyleFormat(row) {
if (row.index < 0) return;
if (this.state.index === row.index) {
return {
backgroundColor: '#b7b9bd',
color: '#333'
};
}
return {
backgroundColor: '#fff',
color: '#333'
};
}
render() {
return (
<Table width={500} height={300} headerHeight={20} rowHeight={30}
rowCount={this.state.data.length} rowGetter={({ index }) => this.state.data[index]}
onRowClick={this.handleRowSelect.bind(this)}
rowStyle={this.rowStyleFormat.bind(this)}
>
<Column width={100} label='Rank' dataKey='rank' />
<Column width={150} label='Player' dataKey='player' />
<Column width={150} label='Points' dataKey='points' />
</Table>
);
}
}
export default TestTable;
Related
Using vue v2.5 with vueCLI 3 trying to have a v-data-table that on each row have a button, when this button clicked should make it appear as loading.
v-btn has loading property by default, really I don't know why is not working...
<v-data-table
:headers="headers"
:items="records"
#dblclick:row="editRowCron_jobs">
<template v-slot:[`item.actions`]="props">
<v-btn color="blue-grey" :loading="props.item.createloading" fab dark small #click="ManuralRun(props.item)">
<v-icon dark>mdi-google-play</v-icon>
</v-btn>
</template>
</v-data-table>
On the click method, I can read but not set the item
export default {
data() {
return {
headers: [
{ text: "id", value: "id", align: " d-none" },
{ text: "actions", value: "actions" }
],
records: [] //grid rows filled by API
}
},
methods: {
ManuralRun(item){
this.records[2].createloading=true; //even I set it like that, nothing happens
item.createloading = true; //property changed here - ok
console.log(item); //here outputs the clicked item - ok
},
so, according to this
the property MUST pre-exist in the array, that means, when we get the result from the API, we have to add the property as:
this.records = data.data.map(record => {
return {
createloading: false,
...record
}
})
I wants to fetch all the coordinates of a polygon drawn on Google's Map. And here is my code
import React from "react";
import { compose, withProps } from "recompose";
import {
withScriptjs,
withGoogleMap,
GoogleMap,
Marker
} from "react-google-maps";
//import withScriptjs from "react-google-maps/lib/async/withScriptjs";
import { DrawingManager } from "react-google-maps/lib/components/drawing/DrawingManager";
const MyMapComponent = compose(
withProps({
/**
* Note: create and replace your own key in the Google console.
* https://console.developers.google.com/apis/dashboard
* The key "AIzaSyBkNaAGLEVq0YLQMi-PYEMabFeREadYe1Q" can be ONLY used in this sandbox (no forked).
*/
googleMapURL:
"https://maps.googleapis.com/maps/api/js?key=AIzaSyALpmb4KhFoR2Kcvty21gzzegprl4ilIgs&v=3.exp&libraries=geometry,drawing,places",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div style={{ height: `100%` }} />
}),
withScriptjs,
withGoogleMap
)(props => (
<GoogleMap
defaultZoom={8}
defaultCenter={new window.google.maps.LatLng(-34.397, 150.644)}
>
<DrawingManager
defaultDrawingMode={
window.google.maps.drawing.OverlayType.ControlPosition
}
defaultOptions={{
drawingControl: true,
drawingControlOptions: {
position: window.google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
window.google.maps.drawing.OverlayType.CIRCLE,
window.google.maps.drawing.OverlayType.POLYGON,
window.google.maps.drawing.OverlayType.POLYLINE,
window.google.maps.drawing.OverlayType.RECTANGLE
]
},
circleOptions: {
fillColor: `#ffff00`,
fillOpacity: 1,
strokeWeight: 5,
clickable: false,
editable: true,
zIndex: 1
}
}}
/>
{props.isMarkerShown && (
<Marker position={{ lat: -34.397, lng: 150.644 }} />
)}
</GoogleMap>
));
My focus of work is to fetch all the coordinates of that polygon that should be drawn on Google Maps.I also wants to store these coordinates in MongoDB using mongoose and NodeJs as backend.
We can use this function to get all the coordinates of a polygon or any other reactangle.
function getPaths(polygon) {
var polygonBounds = polygon.getPath();
var bounds = [];
for (var i = 0; i < polygonBounds.length; i++) {
var point = {
lat: polygonBounds.getAt(i).lat(),
lng: polygonBounds.getAt(i).lng()
};
bounds.push(point);
}
console.log(bounds);
}
And in GoogleMap component, i simplified the above code by given way.
<DrawingManager
drawingMode={"polygon"}
onPolygonComplete={value => console.log(getPaths(value))} />
I am using export all to Excel functionality to export the React table data into an Excel sheet. All the data is getting inserted as string format, but I wanted record count to be stored as integer format, however it is being stored as string format.
Export all to Excel code:
<div id="excelLayer">
<Workbook filename='DownloadedReport.xlsx' element={<a href="javascript:void(null)" className='excel_div'>Export all to Excel</a>}>
<Workbook.Sheet data={this.state.data} name="Table Data">
<Workbook.Column label="From" value="senderID"/>
<Workbook.Column label="To" value="receiverID"/>
<Workbook.Column label="Transaction File" value="fileName"/>
<Workbook.Column label="Transaction Date" value="transationDate"/>
<Workbook.Column label="Record Count" value="recordCount"/>
<Workbook.Column label="Status" value="status"/>
</Workbook.Sheet>
</Workbook>
</div>
React table Record Count column code: This code is used for record count column sorting.
{Header: 'Record Count',accessor: 'recordCount', style: {textAlign: "center"},
sortMethod: (a, b) => {
if (isNaN(a) || isNaN(b)) {
return a > b ? 1 : -1;
}
return a - b;
}
},
Exported Excel data:
How to handle this in code so that the data will automatically be stored as integer?
Can you make sure you are giving recordCount value as string?
I tried using react-excel-workbook with integer values and the downloaded excel is proper.
And if I use string, the excel has string formatted values.
NOTE: Assuming your "recordCount" is always int I have used parseInt. If it can be float please modify <Workbook.Column label="recordTotal" value={row => parseInt(row.recordTotal)} /> accordingly.
import React, { Component } from 'react';
import './App.css';
import Workbook from 'react-excel-workbook'
class App extends Component {
render() {
const data1 = [
{
recordTotal: '123',
status: 'Not started',
},
{
recordTotal: '12',
status: 'in progress',
},
{
recordTotal: '111',
status: 'Completed',
}
]
return (
<div className="App">
<Workbook filename="example.xlsx" element={<a href="javascript:void(null)" className='excel_div'>Export all to Excel</a>}>
<Workbook.Sheet data={data1} name="Sheet A">
<Workbook.Column label="recordTotal" value={row => parseInt(row.recordTotal)} />
<Workbook.Column label="status" value="status" />
</Workbook.Sheet>
</Workbook>
</div>
);
}
}
export default App;
Below is the downloaded excel.
I'd like to display the columns that are defined in Tabulator with editor: false differently than the cells where editing is enabled.
I currently have columns defined like so:
this.tabAuthorizations = new Tabulator('#myTab', {
data: data,
columns: [
// 0
{
title: 'Id',
field: 'Id',
visible: false
},
{
title: 'User',
field: 'UserId',
formatter: (c) => {
return directReports.find(x => x.EmployeeListID === c.getValue()).EmployeeName;
},
editor: false
}, {
title: 'Type',
field: 'AuthTypeId',
formatter: c => {
return authTypes.find(x => x.AuthTypeId === Number(c.getValue())).AuthType;
},
editor: 'autocomplete',
editorParams: {
showListOnEmpty: true,
values: authTypes.reduce((a, c) => Object.assign( {[c.AuthTypeId]: c.AuthType}, a), {})
}
},
// etc
]
});
currently this generates cells with the same css classes applied.
<div class="tabulator-cell" role="gridcell" style="width: 542px; height: 28px;" tabulator-field="TaskListID" title="">My readonly field<div class="tabulator-col-resize-handle"></div><div class="tabulator-col-resize-handle prev"></div></div>
I would like to apply a -readonly or -editable class to the cells depending on the setting for editor: in the column definition. There doesn't appear to be a class applied either to the editable or non-editable cells by Tabulator itself, is there a better way of doing this other than in the cell formatter? I'd rather not have to define formatters simply to change the cell style.
you can add a CSS class to any column with the cssClass property in the column definition:
{
title: 'Type',
field: 'AuthTypeId',
cssClass: 'editable', //add custom css class to cell
}
When I inherit/subclass the 'Column' component, it throws Warning: Failed prop type: Table only accepts children of type Column
This is how I subclassed Column
import React, {Component, PropTypes} from 'react';
import * as RV from 'react-virtualized';
class Column extends Component {
constructor() {
super();
}
render() {
return (
<RVC.Column {...this.props} type="Column" />
)
}
}
Column.defaultProps = RV.Column.defaultProps;
Column.propTypes = RV.Column.propTypes;
export default Column;
It works very well but how can I avoid from that warning?
I don't think there's any benefit to subclassing Column. I assume your real intent is to set default values or DRY up your project in which case, I'd suggest just using a factory-function for columns like so:
import { Column, Table } from 'react-virtualized'
export default function CustomColumn (columnProps) {
const customProps = {
// Set any default props here ...
}
return (
<Column
{...customProps}
{...columnProps}
/>
)
}
function ExampleTable (tableProps) {
return (
<Table {...tableProps}>
{CustomColumn({
dataKey: 'foo',
width: 100
})}
{CustomColumn({
dataKey: 'bar',
width: 100
})}
</Table>
)
}
For what it's worth, I've done this on Production projects and it works nicely. If you think you have a strong use-case for subclassing Column though let me know and I will consider adding support for it.
I'm afraid you are not subclassing RV.Column at all, you are still subclassing React.Component, just that the name of your component is Column. React will still show the error because your self-defined Column !== RVC.Column.
Why do you want to subclass it in the first place? What does type="Column" do?