I am getting the checkboxes based on table columns. If I select check box I am getting only one checked value. I want to get multiple checked values.
How do I achieve that?
class StudentTable extends React.Component {
state = {
columns: [
{
title: "StudentID",
dataIndex: "studentid",
key: "studentid"
},
{
title: "Name",
dataIndex: "name",
key: "name"
}
]
};
onChange = e => {
alert(JSON.stringify(e));
console.log(`checked = ${e.target.checked}`);
console.log(`checked = ${e.target.name}`);
this.setState({
[e.target.name]: e.target.value
});
if (e.target.checked === true) {
let filterData = this.state.columns.filter(columnData => {
return e.target.name === columnData.dataIndex;
});
CsvData.push(filterData[0].dataIndex);
console.log("After Filter", filterData[0].dataIndex);
}
};
render() {
return (
<div>
{this.state.columns.map(columData => {
return (
<div key={columData.key}>
<Checkbox name={columData.dataIndex} onChange={this.onChange}>
{columData.dataIndex}
</Checkbox>
</div>
);
})}
<CSVLink data={CsvData}>Download me</CSVLink>;<h2>Student Data</h2>
<Table
dataSource={data}
columns={this.state.columns}
pagination={{ pageSize: 5 }}
rowKey={record => record.id}
onChange={this.handleChange}
/>
</div>
);
}
}
Use checkbox group instead of checkbox
<Checkbox.Group
options={this.state.columns.map(column => ({label:column.dataIndex, value: column.dataIndex}))}
onChange={this.onChange}
/>
I hope this would help
Antd's Checkbox Group https://ant.design/components/checkbox/#components-checkbox-demo-group
Related
I am facing an issue where my 2nd dropdown is receiving values but is not expanding:-
class clusterServersDropdown extends Component {
constructor() {
super();
this.state = {
clusterslist: [],
servertype: [],
selectserver: "",
selectcluster: ""
};
}
componentDidMount() {
this.setState({
clusterslist:[
{label: "cluster1", servertype:["test1","test2","test3"]},
{label: "cluster2", servertype:["test1","test2","test3"]},
{label: "cluster3", servertype:["test1","test2","test3"]},
]
});
}
selectclusterChange(e) {
console.log(e.label)
this.setState({ selectcluster: e.label },() =>{
console.log(this.state.selectcluster)
});
this.setState({
servertype: this.state.clusterslist.find(
(x) => x.label === e.label
).servertype
},() =>{
console.log(this.state.servertype)
}
);
}
routeChange = (e) => {
console.log(e.label)
this.setState({ selectserver: e.label}, () => {
console.log(this.state.selectserver);
let path = "/inventory/cluster/" + this.state.selectcluster +"/servertype/" + this.state.selectserver;
console.log(path);
this.props.history.push(path);
});
};
render() {
return (
<div>
<center>
<label>
Select cluster and server type
<Select className="react-select" classNamePrefix="react-select"
onChange={this.selectclusterChange.bind(this)}
options={this.state.clusterslist.map((x) => {
return {label: x.label};
})}
/>
<Select className="react-select" classNamePrefix="react-select"
onChange={this.routeChange.bind(this)}
options={this.state.servertype.map((y) => {
return {label: y};
})}
/>
</label>
</center>
</div>
);
}
}
export default withRouter(clusterServersDropdown);
Please see below snaps:-
Whenever I am clicking on the 2nd dropdown it retracts and am not able to select the value and proceed. Strangely this works if i replace label by h5, see as below:-
Am i using label wrongly?
Removed label and used h5 with some font formatting instead.
render() {
return (
<div>
<center>
<h5 style={{'font-family':"Pacifico"}}>
Select cluster and server type from dropdown to view its inventory
<Select className="react-select" classNamePrefix="react-select"
onChange={this.selectclusterChange.bind(this)}
options={this.state.clusterslist.map((x) => {
return {label: x.label};
})}
/>
<Select className="react-select" classNamePrefix="react-select"
onChange={this.routeChange}
options={this.state.servertype.map((y) => {
return {label: y};
})}
/>
</h5>
</center>
</div>
);
}
}
Working as expected now.
It doesn't work correctly, I want to select only one value, but I can select one and more... and can't deselect
there is code for that function.
const RadioButtonField = ({type, options, disabled, onChange}) => {
const handleChange = (value) => {
onChange(type, value);
};
return (
<div>
{options.map(({ value, label }) =>
<Radio.Group key={value}>
<Radio
disabled={disabled}
onChange={() => handleChange(value)}
>
{label}
</Radio>
</Radio.Group>
)}
</div>
);
};
You can try this for single selection and also you can reselect too
import React from "react";
import "./styles.css";
import Radio from "#material-ui/core/Radio";
export default class App extends React.Component {
state = {
selectedValue: null,
radioOptions: [
{ id: 1, title: "1" },
{ id: 2, title: "2" },
{ id: 3, title: "3" },
{ id: 4, title: "4" }
]
};
handleChange = id => {
this.setState({
selectedValue: id
});
};
render() {
const { selectedValue, radioOptions } = this.state;
return (
<div className="App">
{radioOptions.map(option => {
return (
<div className="radio-parent">
<lable
onClick={() => this.handleChange(option.id)}
className="radio-btn"
>
<Radio
color="default"
value={option.id}
name="radioValue"
checked={selectedValue == option.id}
/>
{option.title}
</lable>
</div>
);
})}
</div>
);
}
}
codesandBox link for Demo
You can refer to the following code:
class App extends React.Component {
state = {
initialValue: "A",
options: ["A", "B", "C", "D"]
};
onChange = e => {
console.log("radio checked", e.target.value);
this.setState({
value: e.target.value
});
};
render() {
return (
<Radio.Group value={this.state.initialValue}>
{this.state.options.map((value, index) => {
return (
<Radio onChange={this.onChange} key={index} value={value}>
{" "}
{value}{" "}
</Radio>
);
})}
</Radio.Group>
);
}
}
Working codesandbox demo
I think you do not need to pass anything to the function. Whenever the option will be clicked, the event (e) object will be passed to onChange(e) and you will get the value of clicked item and checked value in onChange(e) e.target.value and e.target.checked respectively.
export class FruitShopPage extends Component {
return (
<div>
<Button onClick={this.toggle}>Fruit Shop</Button>
<Modal isOpen={this.state.collapse} size="lg">
<ModalHeader>Fruit shop</ModalHeader>
<ModalBody>
<div className="form-group">
<div>
<ReactTable
data={this.state.listFruitsData}
columns={columns}
defaultPageSize={10}
getTrProps={onRowClick}
/>
</div>
<div>
<Row>
<Button type="submit" onClick=
{this.toggle}>Buy</Button>
</Row>
</div>
</div>
</ModalBody>
</Modal>
</div>
)
}
}
I am using React Table where I am populating data(listFruitsData) from post request
eg)listFruitData contains key-value pair fruitCode:'1234'
Now suppose there are many records with same fruitcode(1234) many times
when I add filter code its shows data but it shows all records with fruitcode 1234 I wanted that in react-table it should show unique list not repeated data.
below is my code for filtering data
<Select
onChange={entry => {
this.setState({ selectFruitcode: entry });
if (entry === null) {
this.onFilteredChangeCustom('', 'fruitCode');
} else {
this.onFilteredChangeCustom(
entry.map(o => {
return o.value;
}),
'fruitCode',
);
}
}}
value={this.state.selectFruitcode}
options={this.state.listFruitData.map((o, i) => {
return {
id: i,
value: o.fruitCode,
label: o.fruitCode,
};
})}
isMulti
name="fruitCode"
className="basic-multi-select"
classNamePrefix="select"
/>
onFilteredChangeCustom = (value, accessor) => {
let filtered = this.state.filtered;
let insertNewFilter = 1;
if (filtered.length) {
filtered.forEach((filter, i) => {
if (filter['id'] === accessor) {
if (value === '' || !value.length) filtered.splice(i, 1);
else filter['value'] = value;
insertNewFilter = 0;
}
});
}
if (insertNewFilter) {
filtered.push({ id: accessor, value: value });
}
this.setState({ filtered: filtered });
};
I am trying to use react-select. I have certain condition (boolean), when the param is true, some property/attribute of the react-select would change base on the logic. One if them is menuList. My objective, if the param is true, I want the menuList displayed and searchable, but when false, I want the menuList hidden but still available (not disabled, thats why I use onChange and onInputChange prop). Here is what I've set so far:
const isExist = true;
return (
<div style={{ width: '50%', margin: 20 }}>
<Select
id="asd"
value={selectedOption}
onChange={isExist ? this.handleChange : null}
onInputChange={isExist ? null : e => this.tests(e) }
options={options}
isClearable={true}
styles={style}
placeholder="Please type"
noOptionsMessage={() => isExist ? 'Zero Result' : null}
components={{ MenuList: () => isExist ? 'display the menu but how?' : null }}
/>
</div>
);
any help would be helpful. Thank you!
Based on the behaviour you describe you could use a controlled menuIsOpen props like this:
class App extends Component {
constructor(props) {
super(props);
this.state = {
isExist: false,
menuIsOpen: false,
selectedOption: null
};
}
onChange = e => {
this.setState({
selectedOption: e
});
};
onInputChange = (options, { action }) => {
if (this.state.isExist) {
if (action === "menu-close") {
this.setState({ menuIsOpen: false });
}
} else {
if (action === "input-change") {
// do whatever you want with the entered value
}
}
};
onFocus = e => {
if (this.state.isExist) this.setState({ menuIsOpen: true });
};
render() {
return (
<div style={{ width: "50%", margin: 20 }}>
<Select
id="asd"
value={this.state.selectedOption}
onFocus={this.onFocus}
onChange={this.onChange}
onInputChange={this.onInputChange}
options={options}
isClearable={true}
placeholder="Please type"
noOptionsMessage={() => (this.state.isExist ? "Zero Result" : null)}
menuIsOpen={this.state.menuIsOpen}
/>
</div>
);
}
}
Here a live example.
is there a way how to define that only "data" greater than * should be added to my columns in data grid?
I have tried add filter, but it support only exact value.
In my example i want to add only columns which has "combinationId" greater than 100.
class App extends React.Component {
constructor(props) {
super(props);
this.state = this.getCleanState();
this.reload();
}
getCleanState() {
return {
columns:[
{ name: 'combinationId', title: 'ID kombinace'},
{ name: 'name', title: 'Název kombinace'},
],
defaultColumnWidths: [
{ columnName: 'combinationId', width: 160 },
{ columnName: 'name', width: 200 },
],
rows:[]
};
}
reload() {
axios.get('http://private-anon-27979f8bb8-bulgur.apiary-mock.com/api/v1/combinationInfo').then((response) => {
this.loading = false;
var newState = {columns: this.state.columns, rows: response.data
.map(x => x.combinations)
.reduce((a, b) => a.concat(b))};
this.setState(newState);
}, (error) => {
this.loading = false;
})
}
render() {
const { columns, rows, defaultColumnWidths, integratedFilteringColumnExtensions } = this.state;
return (
<div>
{/* <button onClick={() => this.reload()}>Load</button>*/}
<div className="grids">
<div className="patient-container">
<Grid
rows={rows}
columns={columns}>
<Table />
<TableColumnResizing defaultColumnWidths={defaultColumnWidths} />
<TableHeaderRow />
</Grid>
</div>
<div className="patient-container2">
<Grid
rows={rows}
columns={columns}>
<FilteringState defaultFilters={[{ columnName: 'combinationId', value: 100 }]} /> <IntegratedFiltering />
<Table />
<TableColumnResizing defaultColumnWidths={defaultColumnWidths} />
<TableHeaderRow />
</Grid>
</div>
</div>
</div>)
}
}
Thanks for answers. I wish you great day.
does it have to be dynamic filtering? else you could just filter it before returning
render() {
const { columns, rows, ... } = this.state;
const filteredRows = rows.map(row => row.combinationId >= 100);
return ( ...