i am trying to select all rows Id that contains in html table by one click i tried to do this but that function does not work and array list shows empty how to do that i can select all rows id by single checkbox and i want all rows id in selectedItems as list form . here is my code that i did.
this.state = {
checkedBoxCheck: false,
selectedItems: [],
stats: [],
}
componentDidMount() {
...
}
toggleSelectAll() {
let selectedItems = [];
if (this.state.selectAll === 0) {
this.state.stats.forEach(x => {
selectedItems[x.id] = true;
});
}
this.setState({
selectedItems: selectedItems,
checkedBoxCheck: true
});
console.log(selectedItems);
}
<thead>
<tr style={{ marginTop: "-88px" }}>
<th class="active" style={{ width: "20px" }}>
<input
type="checkbox"
class="select-all checkbox"
onChange={this.onChange}
name="first_name"
onClick={this.toggleSelectAll.bind(this)}
/>
</th>
<th className="" style={{ width: "20px" }}>
{t("Id")}
</th>
</thead>
<tbody>
{stats.map((c, i) => (
<tr key={c.id}>
<td>
<input
type="checkbox"
id="togBtn"
className="checkbox"
name="selectOptions"
onClick={() => this.onItemSelect(c.id)}
/>
</td>
<td>{c.id}</td>
</tbody>
Related
I'm trying to get only checked items saved in an array So that I'm going to export it as a CSV file. need help, that's my sandbox below;
https://codesandbox.io/s/laughing-bush-5fvl7b?file=/src/App.js
You can save the selected items id in state. Have a look:
import { useState } from "react";
import { CategoriesData } from "../data";
import "./styles.css";
export default function App() {
const [selectedIds, setSelectedIds] = useState([]);
return (
<div className="App">
<table id="categories">
<thead>
<tr id="titres">
<td className="input-check">
<input type="checkbox" className="checkbox" />
</td>
<td>CATEGORIES</td>
<td>DESCRIPTION</td>
</tr>
</thead>
<tbody>
{CategoriesData.map((category, index) => (
<tr
id={`element-${index}`}
key={category._id}
className={
selectedIds.includes(category.id) ? "product active" : "product"
}
>
<td className="input-check">
<input
type="checkbox"
className="checkbox"
onClick={(e) => {
var selected = e.target.checked;
if (selected) {
setSelectedIds([...selectedIds, category.id]);
} else {
setSelectedIds([
...selectedIds.filter((x) => x !== category.id)
]);
}
}}
/>
</td>
<td>{category.designation}</td>
<td id="category-desc">{category.description}</td>
</tr>
))}
</tbody>
</table>
</div>
**react js **
what I want is when i check any checkbox from the table in the particular button gets disabled but i have to click the checkbox two times to make it check i have also tried with onClick it is also giving the same output Please help me i am get the data through api call form localost only in useEffect and storing the data in a state Array with addon key to make
checkbox checked and button disabled and the state checked is to toggel the value of checkbox and button; But the only problem is User have to click it 2 times i am not able to figure out
const Table1 = () => {
const [supervisors, setSupervisors] = useState([]);
const [checked, setChecked] = useState(false);
useEffect(() => {
const fetchTableList = async () => {
const { data } = await axios("http://localhost:4000/users");
let newData = data.map((item) => {
item.checked = false;
item.disabled = false;
return item;
});
setSupervisors(newData);
};
fetchTableList();
}, []);
console.log(supervisors);
return (
<div className="table-component" style={{ minHeight: "91vh" }}>
<h2 className="main-heading text-center">Supervisor Mapping</h2>
<Table striped bordered hover className="table text-center">
<thead className="heading">
<tr style={{ fontSize: "1.125rem" }}>
<th className="table-heading">OID</th>
<th className="table-heading">Supervisor </th>
<th className="table-heading">Title</th>
<th className="table-heading">Project</th>
<th className="table-heading">Industry</th>
<th className="table-heading">Supervisee</th>
<th className="table-heading">Receiver</th>
<th className="table-heading">Actions</th>
</tr>
</thead>
<tbody>
{supervisors.map((item, index) => (
<tr key={item.supervisorId} style={{ fontSize: "0.938rem" }}>
<td>{item.supervisorId}</td>
<td className="mx-5">{item.supervisor} </td>
<td>{item.title}</td>
<td>{item.project}</td>
<td>{item.industry}</td>
<td
style={
item.supervisee.length > 5
? { backgroundColor: "red", color: "white" }
: item.supervisee.length > 1
? { backgroundColor: "yellowgreen", color: "white" }
: { backgroundColor: "#FFD580", color: "white" }
}
>
{item.supervisee.length}{" "}
</td>
<td>
{" "}
<input
className="checkBox"
type="checkbox"
onChange={() => {
setChecked(!checked);
item.checked = checked;
}}
checked={item.checked}
/>
</td>
<td>
<Button
className="fas fa-eye"
disabled={item.checked}
id={index}
data-id={item.supervisorId}
data-name={item.supervisor}
></Button>
</td>
</tr>
))}
</tbody>
</Table>
</div>
)}
Do not mutate the state directly.
onChange={() => {
setChecked(!checked);
item.checked = checked; //
}}
checked={item.checked}
Always update a clone of the state.
onChange={() => {
// create a clone of the supervisors array
const newSupervisors = supervisors.slice(0);
// mutate the cloned array
newSupervisors[index].checked = !item.checked;
// replace the state with the mutated clone
setSupervisors(newSupervisors);
}}
This is not necessary.
const [checked, setChecked] = useState(false);
I have been struggling with react-virtualised docs They have full-featured example tables.
All I want is simple infinite scrolling for my table. Please if anyone can help.
I just want to render my content when it's visible on the screen.
NOTE: I am not pulling the data from any API I have static data(an array of objects) saved into my local folder.
Please see a screenshot of my app below.
Below is my code.
const renderRows = items.map((data, index) => {
return (
<tr
className="table__row"
key={data.id}
onClick={() => onRowClick(data.id)}
>
<td style={{ marginRight: '2px' }}>
<img
onClick={(e) => {
toggleStarSelect(e, data.id);
}}
src={Star}
className="star"
alt="star"
style={{ padding: '2px' }}
/>
{data['#']}
</td>
<td>
<ImageLoadHandler
isloaded={isloaded}
handleImage={handleImage}
data={data}
/>
<span style={{ padding: '10px' }}>{data.Name}</span>
<span
style={{
backgroundColor: 'lightgray',
opacity: '0.5',
fontSize: '13px',
}}
>
{data.Symbol}
</span>
</td>
<td>{data.Price}</td>
<td>{data['1h']}</td>
<td className={data['24h'] > 0 ? 'green' : 'red'}>
{data['24h'] > 0 ? (
<img className="arrowicon" src={SortUpGreen} alt="sort-up-green" />
) : (
<img className="arrowicon" src={SortDownRed} alt="sort-down-red" />
)}
{data['24h']}%
</td>
<td>{data['7d']}</td>
<td>{data['Mkt Cap']}</td>
<td>{data['24h Vol']}</td>
<td style={{ padding: '0', paddingRight: '8px' }}>
<Suspense fallback={<div className="loading">loading...</div>}>
<Graph data={data} idx={index} />
</Suspense>
</td>
</tr>
);
});
return (
<div className="app">
<header>
<Header />
</header>
<table className="app__table">
<thead className="app__tablehead">
<tr>
<th
onClick={() => requestSort('#')}
className={getClassNamesFor('#')} //returns ascending or descending
>
#
</th>
<th
onClick={() => requestSort('Name')}
className={getClassNamesFor('Name')}
>
Coin
</th>
<th
onClick={() => requestSort('Price')}
className={getClassNamesFor('Price')}
>
Price
</th>
<th
onClick={() => requestSort('1h')}
className={getClassNamesFor('1h')}
>
1h
</th>
<th
onClick={() => requestSort('24h')}
className={getClassNamesFor('24h')}
>
24h
</th>
<th
onClick={() => requestSort('7d')}
className={getClassNamesFor('7d')}
>
7d
</th>
<th
onClick={() => requestSort('Mkt Cap')}
className={getClassNamesFor('Mkt Cap')}
>
Mkt Cap
</th>
<th
onClick={() => requestSort('24h Vol')}
className={getClassNamesFor('24h Vol')}
>
24h Vol
</th>
<th className="nohover">Last 7 days</th>
</tr>
</thead>
<tbody>{renderRows}</tbody>
</table>
</div>
);
A working example of infinite scroll on a table element. Also a working a repl.
import React, {useState, useEffect} from 'react';
import './App.css';
function App() {
let items = [];
for (let i = 0; i < 100; i++) {
items.push({
key: 'foo' + i,
value: 'bar' + i,
});
}
let dataTable = React.createRef();
const [list, setList] = useState({
itemsDisplayed: 20,
data: items.slice(0, 20),
});
let onScroll = () => {
let tableEl = dataTable.current;
if (tableEl.scrollTop === (tableEl.scrollHeight - tableEl.offsetHeight)) {
if (list.itemsDisplayed + 10 <= items.length) {
setList({
itemsDisplayed: list.itemsDisplayed + 10,
data: items.slice(0, list.itemsDisplayed + 10),
});
}
}
};
return (
<div className="App">
<table id="data-table" ref={dataTable} onScroll={onScroll}>
<tbody>
{list.data.map((item) => {
return (
<tr key={item.key}>
{item.value}
</tr>
);
})}
</tbody>
</table>
</div>
);
}
export default App;
Also to mention, the problem of scrolling firing only once solved by this question. The point is to use React's built-in onScroll event.
I am new to react. I am using an addrow method to add the values to the table I created using {this.state.rows.map}. The table appears with the values of the input fields. However on pressing the continue button to go to the next page and then coming back from the page by pressing the back button, the row disappears.
Here is the code:
<Grid item xs={10} direction="row" alignItems="center">
<table
className="table table-bordered table-hover"
id="tab_logic"
>
<thead>
{this.state.rows.length > 0 ? (
<tr>
<th className="text-center"> # </th>
<th className="text-center"> KPI </th>
<th className="text-center"> UOM </th>
<th className="text-center"> Base </th>
<th className="text-center"> Target </th>
<th className="text-center"> Target Date </th>
<th className="text-center"> Delete Row </th>
</tr>
) : null}
</thead>
<tbody>
{this.state.rows.map((item, idx) => (
<tr id="addr1" key={idx}>
<td>{idx + 1}</td>
<td>
<input
type="text"
name="Kpi_Before"
defaultValue={Kpi_Before}
onChange={this.handleChangeRows(idx)}
className="form-control"
readOnly
/>
</td>
<td>
<input
type="text"
name="UOM_Before"
defaultValue={UOM_Before}
onChange={this.handleChangeRows(idx)}
className="form-control"
readOnly
/>
</td>
<td>
<input
type="text"
name="Base_Before"
defaultValue={Base_Before}
onChange={this.handleChangeRows(idx)}
className="form-control"
readOnly
/>
</td>
<td>
<input
type="text"
name="Target_Before"
defaultValue={Target_Before}
onChange={this.handleChangeRows(idx)}
className="form-control"
readOnly
/>
</td>
<td>
<input
type="text"
name="dateTime"
defaultValue={dateTime}
onChange={this.handleChangeRows(idx)}
className="form-control"
readOnly
size="38"
/>
</td>
<td>
The code for changes and going back and forward is this:
continue = e => {
e.preventDefault();
this.props.nextStep();
}
};
back = e => {
e.preventDefault();
this.props.prevStep();
};
handleChangeRows = idx => e => {
const { name, value } = e.target;
const rows = [...this.state.rows];
rows[idx] = {
[name]: value
};
this.setState({
rows
});
};
handleAddRow = () => {const item = {
Kpi_Before: [],
UOM_Before: "",
Base_Before: "",
Target_Before: "",
dateTime: "",
rows:[]
};
this.setState({
rows: [...this.state.rows, item]
});
}
};
nextStep = () => {
const { step } = this.state;
this.setState({
step: step + 1
});
};
//Go back to previous step
prevStep = () => {
const { step } = this.state;
this.setState({
step: step - 1
});
};
How do I keep the rows from disappearing and keep it constant on moving back and forward?
Your state re-renders when you navigate between pages or refresh which means everything inside state is lost to combat this you can either:
1) Use redux to store changes and retrieve data from there.
2) Use Context API which is the same as redux but builtin to react.
3) Consume a REST API which means have some sort of backend to store the values and get them on component mount.
I'm working on a project named "Food Recipes", where a user can create, edit, delete his own recipes.
When creating a new recipe, the user must select the ingrediets.
So here is where I need your help:
By an axios call, I'm getting all the ingredients and show them into a table. The table looks like this:
|---------------------|------------------|-----------------|
| Ingredient | Check | Amount |
|---------------------|------------------|-----------------|
| Tomato | true | 2 kg |
|---------------------|------------------|-----------------|
| Potato | false | |
|---------------------|------------------|-----------------|
| Onion | true | 1 kg |
|---------------------|------------------|-----------------|
After checking some ingredient to TRUE, I want to have onChange function that will create list of IDs, from all ingredients that are CHECKED (in this case, I will have list with two elements: ID from Tomato, and ID from Onion)
To mention, i put ingredient ID as a value inside the <input type="checkbox"/>
Here is my code:
import React, {Component, useEffect, useState} from 'react'
import axios from "../../../axios/axios"
class Ingredient extends Component {
constructor(props){
super(props)
this.state = {
ingredients: [],
ingedientsList: [],
isChecked: false,
}
}
onIngredientChange = (e) => {
//HERE
};
componentDidMount() {
axios.get("/ingredients").then((data) => {
const ingredients = Object.keys(data.data).map((ingredient, index) => {
return (
<tr key={index}>
<td scope="col">
<label>{data.data[index].name}</label>
</td>
<td scope="col">
<input
id={data.data[index].id}
key={index}
type="checkbox"
name={"newIngredients"}
value={data.data[index].id}
onChange={this.onIngredientChange}
/>
</td>
<td scope="col">
<input
id={data.data[index].id + "amount"}
key={index}
type="number"
min="0"
max="500"
name="amount"
placeholder="grams"
onChange={this.onIngredientChange}
/>
</td>
</tr>
);
});
this.setState({ingredients: ingredients});
});
}
render() {
return (
<div className="form-group">
<table className="table tr-history table-striped small">
<thead>
<tr>
<th scope="col">
<h5>Ingredient</h5>
</th>
<th scope="col">
<h5>Check</h5>
</th>
<th scope="col">
<h5>Amount</h5>
</th>
</tr>
</thead>
<tbody>
{this.state.ingredients}
</tbody>
</table>
</div>
)
}
}
export default Ingredient;
Update
Try the code below.
const data = {
data:[
{
id:1,
name:"A"
},
{
id:2,
name:"B"
},
{
id:3,
name:"C"
}
]
}
class Ingredient extends React.Component {
constructor(props){
super(props)
this.state = {
ingredients: [],
ingedientsList: [],
checkedList:[],
isChecked: false,
}
}
componentDidMount() {
const ingredients = data.data.map((ingredient, index) => {
return (
<tr key={index}>
<td scope="col">
<label>{data.data[index].name}</label>
</td>
<td scope="col">
<input
id={data.data[index].id}
key={index}
type="checkbox"
name={"newIngredients"}
value={data.data[index].id}
onChange={(e)=>this.onIngredientChange(e,data.data[index].id)}
/>
</td>
<td scope="col">
<input
id={data.data[index].id + "amount"}
key={index}
type="number"
min="0"
max="500"
name="amount"
placeholder="grams"
onChange={this.onIngredientChange}
/>
</td>
</tr>
);
});
this.setState({ingredients: ingredients});
}
onIngredientChange = (e,id) => {
let resultArray = []
if(e.target.checked) //if checked (true), then add this id into checkedList
{
resultArray = this.state.checkedList.filter(CheckedId=>
CheckedId !== id
)
resultArray.push(id)
}
else //if not checked (false), then remove this id from checkedList
{
resultArray = this.state.checkedList.filter(CheckedId=>
CheckedId !== id
)
}
console.log(resultArray)
this.setState({
checkedList:resultArray
})
}
render() {
return (
<div className="form-group">
<table className="table tr-history table-striped small">
<thead>
<tr>
<th scope="col">
<h5>Ingredient</h5>
</th>
<th scope="col">
<h5>Check</h5>
</th>
<th scope="col">
<h5>Amount</h5>
</th>
</tr>
</thead>
<tbody>
{this.state.ingredients}
</tbody>
</table>
</div>
)
}
}
// Render it
ReactDOM.render(
<Ingredient />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
First, have a checked list in state
this.state = {
ingredients: [],
ingedientsList: [],
checkedList:[]
isChecked: false,
}
Then change element a little bit,
<input
id={data.data[index].id}
key={index}
type="checkbox"
name={"newIngredients"}
value={data.data[index].id}
onChange={(e)=>this.onIngredientChange(e,data.data[index].id)}
/>
Then change handler,
onIngredientChange = (e,id) => {
let resultArray = []
if(e.target.checked) //if checked (true), then add this id into checkedList
{
resultArray = this.state.checkedList.filter(CheckedId=>
CheckedId !== id // filter(checkID=>{CheckedId !== id}) remove {}
)
resultArray.push(id)
}
else //if not checked (false), then remove this id from checkedList
{
resultArray = this.state.checkedList.filter(CheckedId=>
CheckedId !== id // filter(checkID=>{CheckedId !== id}) remove {}
)
}
this.setState({
checkedList:resultArray
})
console.log(resultArray) // get all checked ID
};
Try this. Use a state array instead of simple array.
onIngredientChange = (e, value) => {
if (array.includes(value) && !e.target.checked) {
array.splice( array.indexOf(value), 1 );
} else if (!array.includes(value) && e.target.checked) {
array.push(value)
}
};
<input id={data.data[index].id} key={index}
type="checkbox" name={"newIngredients"}
value={data.data[index].id}
onChange={(e) =>this.onIngredientChange(e, value)} />
...
onIngredientChange = e => {
const checkedIngrediants = {
...this.state.checkedIngrediants
[e.target.id]: !e.target.value
};
this.setState({
checkedIngredients,
ingredientsList: Object.keys(checkedIngredients)
.filter(key => checkedIngredients[key])
})
}
...
<input
id={data.data[index].id}
key={index}
type="checkbox"
name={"newIngredients"}
value={this.state.checkedIngrediants[data.data[index].id]}
onChange={this.onIngredientChange} />