I am using react-data-grid component. It provides a grid structure with edit and lot more options. When we click on each cell, we are able to edit the content of the cell. In my project, I have a situation like when the date column is focused I want to bind a UI where the user can able to select the date.for that, I have used react-datepicker component. I am able to give react-datepicker component as a formatter in the date column option. I can able to change the date in the react datepicker component, but that is not updating the cell value (when you click on the console data button you can able to see the changes have been updated or not).so guys help me how I can update the cell value when a different date is selected in the react-datepicker component. It happening automatically when the value is changed in other cells.
import React from 'react';
import ReactDOM from 'react-dom';
import ReactDataGrid from 'react-data-grid';
import DatePicker from 'react-datepicker';
import moment from 'moment';
//helper to generate a random date
function randomDate(start, end) {
return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toLocaleDateString();
}
//helper to create a fixed number of rows
function createRows(numberOfRows){
var _rows = [];
for (var i = 1; i < numberOfRows; i++) {
_rows.push({
id: i,
task: 'Task ' + i,
startDate: randomDate(new Date(2015, 3, 1), new Date())
});
}
return _rows;
}
//function to retrieve a row for a given index
var rowGetter = function(i){
return _rows[i];
};
//renders react datepicker component
var ExampleDate = React.createClass({
displayName: 'Example',
getInitialState: function() {
return {
startDate:moment(this.props.value,"MM-DD-YYYY")
};
},
consoleDate:function(){
console.log(this.state.startDate);
},
handleChange: function(date) {
this.setState({
startDate: date
});
},
render: function() {
return (
<div>
<DatePicker selected={this.state.startDate} onChange={this.handleChange} />
</div>
);
}
});
//Columns definition
var columns = [
{
key: 'id',
name: 'ID',
width: 80
},
{
key: 'task',
name: 'Title',
editable : true,
width:100
},
{
key: 'startDate',
name: 'Start Date',
editable : true,
formatter:<ExampleDate />,
width:100
}
]
var Example = React.createClass({
getInitialState : function(){
return {rows : createRows(5)}
},
rowGetter : function(rowIdx){
return this.state.rows[rowIdx]
},
handleRowUpdated : function(e){
//merge updated row with current row and rerender by setting state
var rows = this.state.rows;
Object.assign(rows[e.rowIdx], e.updated);
this.setState({rows:rows});
},
output:function(){
console.log(this.state.rows);
},
render:function(){
return(
<div>
<ReactDataGrid
enableCellSelect={true}
columns={columns}
rowGetter={this.rowGetter}
rowsCount={this.state.rows.length}
minHeight={200}
onRowUpdated={this.handleRowUpdated} />
<button onClick={this.output} > Console data </button>
</div>
)
}
});
ReactDOM.render(<Example />, document.getElementById('container'));
I encounter some issues when I tried to reproduce. Anyway, after some changes I works fine:
- I removed the random date to avoid "Invalid Date"
- I fixed the formatter like this
formatter: ({value}) => <ExampleDate value={value} />
All works fine, but I always get the warning, because of the key props of your columns :(
Related
I have a React app with Fluent-UI 8 set up using npm install #fluentui/react according to the documents from Microsoft.
When I try their combobox or dropdown components, the dropdown list doesn't appear when clicked on it. I use their examples from the docs, which compiles without errors. But none of their examples work out of the box, and no other information is provided.
The problem is that the dropdown list does not appear when clicked on. Not in Edge, not in Firefox. When I check the elements on the page, I do not see the html elements with the list items, although I can cycle through them with the arrow keys. The list appears from the side when the window is tablet format, and setting ResponsiveMode did nothing. Whith a normal screen however, nothing is displaying, and no onchange events are fired.
This is my code for the dropdown:
import { IStackTokens, ResponsiveMode, Stack } from '#fluentui/react';
import { Dropdown, DropdownMenuItemType, IDropdownOption, IDropdownStyles } from '#fluentui/react/lib/Dropdown';
const dropdownStyles: Partial<IDropdownStyles> = { dropdown: { width: 300 } };
const DropdownControlledMultiExampleOptions = [
{ key: 'fruitsHeader', text: 'Spooler status', itemType: DropdownMenuItemType.Header },
{ key: 'apple', text: 'Apple' },
{ key: 'banana', text: 'Banana' },
{ key: 'grape', text: 'Grape' },
{ key: 'broccoli', text: 'Broccoli' },
{ key: 'carrot', text: 'Carrot' },
{ key: 'lettuce', text: 'Lettuce' },
];
export const DropdownList: React.FunctionComponent = () => {
const stackTokens: IStackTokens = { childrenGap: 20 };
return (
<Stack tokens={stackTokens}>
<Dropdown
placeholder="Select an option"
label="Disabled responsive"
options={DropdownControlledMultiExampleOptions}
styles={dropdownStyles}
responsiveMode={ResponsiveMode.unknown}
/>
<Dropdown
placeholder="Select an option"
label="Responsive with panel"
options={DropdownControlledMultiExampleOptions}
styles={dropdownStyles}
/>
</Stack>
);
};
Which I load in my app.tsx
function App() {
return (
<div className="App">
<DropdownList/>
</div>
);
}
Does anyone have an idea how I can get this to work? Or what is causing this?
EDIT and possible solution: It seems that removing the <React.Strict> tags in index.tsx does the job. Don't know why, but then the Fluid-UI controls work fine.
Does Grommet have a built in solution to only allow single or multiple selections within a dataTable? I came up with this useState function that clears the array before setting it but it has an adverse reaction of forcing the user to click twice. If array > 1 user clicks which sets the select array to [] forcing the user to click again.
import React from "react";
import ReactDOM from "react-dom";
import {Grommet, DataTable, Text, Meter, Box} from 'grommet';
const GridExample = () => {
const [select, setSelect] = React.useState([])
function handleRowSelect(selection) {
console.log(`You picked ${selection}`);
if (selection.length > 1) {
setSelect(selection[selection.length - 1].toArray)
} else {
setSelect(selection)
}
}
return (
<Grommet>
<DataTable
select={select}
onSelect={handleRowSelect}
columns={[
{
property: 'name',
search: true,
header: <Text>Name</Text>,
primary: true,
},
{
property: 'percent',
search: true,
header: 'Complete',
render: datum => (
<Box pad={{vertical: 'xsmall'}}>
<Meter
values={[{value: datum.percent}]}
thickness="small"
size="small"
/>
</Box>
),
},
]}
data={[
{name: 'Alan', percent: 20},
{name: 'Bryan', percent: 30},
{name: 'Chris', percent: 40},
{name: 'Eric', percent: 80},
]}
/>
<Text>Selected: {select}</Text>
</Grommet>
)
}
export default GridExample;
ReactDOM.render(
<GridExample/>,
document.getElementById("root")
);
Update: Using Slice in the function fixes the double click.
function handleRowSelect(selection) {
if (selection.length > 1) {
setSelect(selection.slice(-1))
} else {
setSelect(selection)
}
}
I don't think there is a built-in solution (for grommet 2.17.5).
Though, you can always try to manipulate select and onSelect in different ways, for example, one way for that will be to add a condition to onSelect and disable selection option once one row had been selected already:
onSelect={select.length < 1 && handleRowSelect}
This will make sure only one row is selected at any given point.
If you'd like the users to be able to reset their decision, you can always add a reset button that clears the array of selection, and the checkboxes will be enabled again.
I am using react-date-range plugin to select a date range.
import { DateRangePicker} from 'react-date-range';
import 'react-date-range/dist/styles.css';
import 'react-date-range/dist/theme/default.css';
Following function is used to handle the date range when a range is selected
function handleSelect() {
}
I have added the DateRangePicker like this
const selectionRange = {
startDate: new Date(),
endDate: new Date(),
key: 'selection',
}
<div>
<DateRangePicker
ranges={[selectionRange]}
onChange={handleSelect}/>
</div>
I want to make some operations on the selected date range in side the handleChange function. But I cannot find how to identify which date range is selected and the respective start and end dates.
In documentation onChange callback is described as
But I cannot understand how to get these startDate and endDate parameters.
Can someone help me to get this values.
Documentation: https://openbase.io/js/react-date-range/documentation
According to the documentation the onChange callback receives the ranges as an argument:
import { DateRangePicker } from 'react-date-range';
class MyComponent extends Component {
handleSelect(ranges){
console.log(ranges);
// {
// selection: {
// startDate: [native Date Object],
// endDate: [native Date Object],
// }
// }
}
render(){
const selectionRange = {
startDate: new Date(),
endDate: new Date(),
key: 'selection',
}
return (
<DateRangePicker
ranges={[selectionRange]}
onChange={this.handleSelect}
/>
)
}
}
It should be an object that has a key selection which is itself an object that contains the startDate and endDate.
My solution is:
const onChange = (item) => {
if (item.selection.endDate !== item.selection.startDate) {
console.log(item);
setIsPopoverOpen(false);
}
setRange([item.selection]);
}
I work on a React app and there is a component using DataTable (reference is here).
The default font-size looks too small so I want to change to make it look bigger.
I try to set the style to the table as the code below but it doesn't work.
Here is my code:
import React from 'react';
import ReactDOM from 'react-dom';
import DataTable from 'react-data-table-component';
export default class MyTable2 extends React.Component {
constructor(props) {
super(props);
const data = [];
for (var i = 0; i < 200; i++) {
data.push({ id: i, title: 'Conan the Barbarian' + i, summary: 'Orphaned boy Conan is enslaved after his village is destroyed...', year: '1982', expanderDisabled: true, image: 'http://conan.image.png' })
}
this.state = {
rs: data
}
}
render() {
const columns = [
{
name: 'Title',
selector: 'title',
sortable: true,
},
{
name: 'Year',
selector: 'year',
sortable: true
},
];
const handleChange = (state) => {
console.log('Selected Rows: ', state.selectedRows);
};
let styleobj = { "font-size": "25px" } //try to set the font-size here
return (
<DataTable
className="dataTables_wrapper"
title="Arnold Movies"
columns={columns}
data={this.state.rs}
selectableRows // add for checkbox selection
onTableUpdate={handleChange}
pagination
style={styleobj}
/>
)
}
}
Is there anyone here can suggest me a solution?
Thank you in advanced.
Can you try this
// Override the row font size
const myNewTheme= {
rows: {
fontSize: '25px'
}
}
<DataTable
className="dataTables_wrapper"
title="Arnold Movies"
columns={columns}
data={this.state.rs}
selectableRows // add for checkbox selection
onTableUpdate={handleChange}
pagination
customTheme={myNewTheme}
/>
Theme reference
Source file
If you want to change an individual cell font size, you can do this
const columns = [
{
name: 'Title',
selector: 'title',
sortable: true,
cell: row => <div style={{fontSize: 25}}>{row.title}</div>
}]
Hi #humanbean answer is correct, you can fix the inline stile or, if you want, you also can set the style directly in your app.css
Based on your custom classname (.dataTables_wrapper) I think that this css should work.
.dataTables_wrapper .rdt_TableCell{
font-size:25px;
}
this is the className used by react-data-table-component
rdt_Table
rdt_TableRow
rdt_TableCol
rdt_TableCol_Sortable
rdt_TableCell
rdt_TableHeader
rdt_TableFooter
rdt_TableHead
rdt_TableHeadRow
rdt_TableBody
rdt_ExpanderRow
I would like to resolve one problem.
How can I show/hide columns in table using Ant Design in React?
export const columns = () => [
{
key: "anyKeyOne",
title: "Title one",
dataSource: "AnyOne",
hide: true
},
{
key: "anyKeyTwo",
title: "TitleTwo",
dataSource: "AnyTwo",
hide: false
}
]
hideColumns = () => {
//
}
render() {
return (
<div>
<Table
dataSource={store.data}
columns={this.hideColumns}
/>
</div>
)
}
Thank you for answers.
You can set a boolean state property like hideColumn
<div>
<Table
dataSource={store.data}
columns={this.state.hideColumn? this.state.columns: this.state.columns}
/>
</div>
Use this function to build your visible column array. It uses dataIndex to compare the column name needed to be shown.
Form the arrayOfColumnNeeded by pushing values from a checkbox group maybe.
let columnsDisplayed = _.remove(columns, function(n) {
return arrayOfColumnsNeeded.includes(n.dataIndex);
});
You can add a className field in the object and add a css property 'display: none' to that class
{
key: "anyKeyOne",
title: "Title one",
dataSource: "AnyOne",
className: "hide"
}