This is the table:
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>
{column.render('Header')}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return (
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
);
})}
</tr>
);
})}
</tbody>
</table>
Column format:
{
Header:'STUDENT ID',
accessor:'studentid',
},
{
Header:'Name',
accessor:'name',
},
{
Header:'ADDRESS',
accessor:'address',
},
{
Header: "Actions",
Cell: ({ cell }) => (
<span>< button>Edit<button>
/> < button onClick ={ ()=>{handleClick(cell.getCellProps())}} >Delete
<button/> </span>
)
}
Table format:
STUDENTID NAME ADDRESS ACTIONS
154 xyx xyx EDIT&DELETE buttons
564 abc abc EDIT&DELETE buttons
On clicking delete button, need to get student Id for API call to delete a particular record of student. I have used functional component for react table.
Handle click function:
const handleClick = (cell) => {
alert("clicked",cell.studentid);
console.log(cell);
}
Related
I am creating a table in React from a JSON like this:
[
{
"Id_side": 123,
"Name_side": "R4",
"Name_cycle": "C1"
},
{
"Id_side": 345,
"Name_side": "M1",
"Name_cycle": "C2"
},
{
"Id_side": 567,
"Name_side": "V5",
"Name_cycle": "C3"
},
{
"Id_side": 45,
"Name_side": "U4",
"Name_cycle": "C4"
}
]
The table, I am rendering it like this:
import tableData from "./actions/tableData.json"
const BrandTable = () => {
let tb_headers = tableData.map((item)=>{
return(
<td key={item.Id_side}>{item.Name_cycle}</td>
)
})
// this function is only for testing, I know it does not achieve anything.
function renderChecks() {
console.log("checkbox")
for (var i = 0; i < tableData.length; i++){
return <td><input type="checkbox" value="Test" /></td>
} }
let tb_data = tableData.map((item)=>{
return(
<tr key={item.Id_side}>
<td>{item.Name_side}</td>
{renderChecks()}
</tr>
)
})
return(
<table id="table">
<thead>
<tr>
<td></td>
{tb_headers}
</tr>
</thead>
<tbody>
{tb_data}
</tbody>
</table>
)
};
export default BrandTable;
For now I am only able to get a table like this:
Table1
but what I'm looking to do is to make a table with checkboxes in all the cells and have them checked as they come in the JSON.
For example, according to the JSON I show above the table should look like this:
table2
I need that each header has checkboxes in each of the cycles that exist and that these are activated or not depending on whether they come together in the json.
You can do it like below :
const cells = ['C1', 'C2', 'C3', 'C4'];
export default function App() {
return (
<div>
<table border="1" style={{ width: '100%' }}>
<thead>
<th></th>
<th> C1</th>
<th> C2</th>
<th> C3</th>
<th> C4</th>
</thead>
<tbody>
{data.map((item) => {
return <TableRow data={item} key={item.id} />;
})}
</tbody>
</table>
</div>
);
}
const TableRow = ({ data }) => {
return (
<tr>
<td> {data.Name_side} </td>{' '}
{cells.map((cell) => {
return (
<td key={cell}>
<input
type="checkbox"
checked={data.Name_cycle === cell}
// add event listener
/>
</td>
);
})}
</tr>
);
};
Example : Working demo
First step would be to create a basic map of Name_side & Name_cycles
var map = data.reduce((a,b) => {
a[b.Name_side] = a[b.Name_side] || [];
a[b.Name_side].push(b.Name_cycle);
return a;
}, {});
This would give an output like
[object Object] {
M1: ["C2"],
R4: ["C1"],
U4: ["C4", "C2"],
V5: ["C3", "C1", "C2"]
}
Now we have unique Name_side mapped to the Name_cycle values. We can now iterate on the object keys & create the rows.
<tbody>
{Object.keys(map).map((row) => (
<tr>
<td>{row}</td>
{cycleNames.map((cell) => {
const checked = map[row].includes(cell);
return (
<td>
<input checked={checked} type="checkbox" value="Bike" />{" "}
{cell}
</td>
);
})}
</tr>
))}
</tbody>
I have a table and edit/delete button on that table(each row) to edit/delete corresponding row.
I want to open a popup when the edit is clicked but I want to open the popup with some parameters to show like "old value, new value" etc.
Here is my code for table and I put an EditUserPopup component at bottom.
function MainPanel(props) {
const [isEditPopupOpen, setEditPopup] = useState(true);
const deleteCustomer = async (id) => {
await service.deleteCustomerById(id);
props.refreshTableParam();
}
const editCustomer = async (id, name, surname) => {
setEditPopup(true);
//WHAT I NEED HERE ?
props.refreshTableParam();
}
return (
<>
<ReactBootStrap.Table striped bordered hover>
<thead>
<tr>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{props.param &&
props.param.map((item) => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.firstName}</td>
<td>{item.lastName}</td>
<td><Button className='editButton' onClick={() => editCustomer(item.id, item.firstName, item.lastName)}><FontAwesomeIcon icon={faUserEdit} /></Button></td>
<td><Button className='deleteButton' onClick={() => deleteCustomer(item.id)}><FontAwesomeIcon icon={faTrashRestore} /></Button></td>
</tr>
))}
</tbody>
</ReactBootStrap.Table>
{
//HOW TO OPEN THAT COMPONENT WITH PARAMS
isEditPopupOpen && <EditUserPopup someParamHere={null}/>
}
</>
);
}
I am calling editCustomer() function by the button on table and I am thinking to make EditPopup somehow visible with some param, and in other component(popup's itself) I'll do some logic.
But I cannot reach the id,firstName,lastName values in popup. How can I send corresponding table row values to the popup ?
The page is this:
You can create a react state and set them inside the edit function. Then you should send them as props to your pop up.
function MainPanel(props) {
const [isEditPopupOpen, setEditPopup] = useState(true);
const [customerInfo, setCustomerInfo] = useState({id: '', name: '', surname: ''})
const deleteCustomer = async (id) => {
await service.deleteCustomerById(id);
props.refreshTableParam();
}
const editCustomer = async (id, name, surname) => {
setCustomerInfo({id: id, name: name, surname: surname})
setEditPopup(true);
//WHAT I NEED HERE ?
props.refreshTableParam();
}
return (
<>
<ReactBootStrap.Table striped bordered hover>
<thead>
<tr>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{props.param &&
props.param.map((item) => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.firstName}</td>
<td>{item.lastName}</td>
<td><Button className='editButton' onClick={() => editCustomer(item.id, item.firstName, item.lastName)}><FontAwesomeIcon icon={faUserEdit} /></Button></td>
<td><Button className='deleteButton' onClick={() => deleteCustomer(item.id)}><FontAwesomeIcon icon={faTrashRestore} /></Button></td>
</tr>
))}
</tbody>
</ReactBootStrap.Table>
{
//HOW TO OPEN THAT COMPONENT WITH PARAMS
isEditPopupOpen && <EditUserPopup customerInfo={customerInfo} someParamHere={null}/>
}
</>
);
}
I have a react table that contains information in my Electron application. However, whenever data in the table is updated or a button is clicked, the table scrolls to the top, frustrating users.
Example code is as follows:
const tableContent = listItem.map((item: any, index: number) => {
return (
<Tr key={index.toString()} className="section">
<Td>{item.<item1>}</Td>
<Td>
<Icon
onClick={() => exampleFunction()}
/>
</Td>
</Tr>
);
});
return (
<Div className="round-card page-content-table table-responsive padding-20">
{<Table className="table table-striped">
<Thead>
<Tr>
<Th>TH1</Th>...
<Th>TH2</Th>
</Tr>
</Thead>
{<Tbody>{tableContent}</Tbody>}
</Table>}
</Div>)
How can I avoid these scroll jumps in the element during updates?
Update:
I was able to get the scroll position to save however, when the table updates, the scroll is stuck to the previous point, making it impossible for users to scroll when the table is updating. Any way to avoid this?
const [scrollPostion, setScrollPosition] = useState(
parseInt(localStorage.getItem('scrollPos')) || 0
);
const TableRef = useRef(null);
const scrollEvent = (e) => {
setScrollPosition(e.target.scrollTop);
localStorage.setItem('scrollPos', scrollPostion.toString());
};
React.useEffect(() => {
localStorage.setItem('scrollPos', scrollPostion.toString());
}, [scrollPostion]);
For anyone who runs into this issue in the future, I solved by moving the table into new component and putting it in the div
const myTable = () => {
const tableContent = listItem.map((item: any, index: number) => {
return (
<Tr key={index.toString()} className="section">
<Td>{item.<item1>}</Td>
<Td>
<Icon
onClick={() => exampleFunction()}
/>
</Td>
</Tr>
);
};
return (
<Table className="table table-striped">
<Thead>
<Tr>
<Th>TH1</Th>...
<Th>TH2</Th>
</Tr>
</Thead>
{<Tbody>{tableContent}</Tbody>}
</Table>}
)
}
const pageContent = () = {
return (
<Div className="round-card page-content-table table-responsive padding-20">
<myTable></myTable>
</Div>)
)
}
At the moment, all the available flights that was received from API are successfully loaded on the page. However, I would like to enable the end user to search specific flight, let's say, by flight number and departure date. How can I integrate this searching functionality in the existing codes?
FlightPage.js
render() {
return (
<>
<h2>Flights</h2>
{this.props.loading ? (
<div>Loading...</div>
) : (
<FlightList flights={this.props.flights} />
)}
</>
);
}
}
As you can see the bellow code, I have used table to present the results.I would like to show only one result or blank table when searching is applied. Can you help me to achieve this?
FlightList.js
const FlightList = ({ flights }) => (
<table className="table">
<thead>
<tr>
<th />
<th>Date</th>
<th>Provider</th>
<th>Dest</th>
</tr>
</thead>
<tbody>
{flights.map((f, i) => {
return (
<tr key={i}>
<td>
<input type="checkbox" name="flightListCheckbox" />
</td>
<td>{f.date}</td>
<td>{f.pnr}</td>
<td>{f.flightNumber}</td>
</tr>
);
})}
</tbody>
</table>
);
You could use filter to create a searching functionality like
I would at first add an input where I can insert my filter values
FlightPage.js
handleInput: (event) => {
const { name, value } = event.target
this.setState({ [name]: value })
}
render () {
const { filter } = this.state
return (
<>
<input onChange=(this.handleInput) value={filter} name='filter' />
<FlightList flights={this.props.flights} filterValues={filter} />
</>
)
}
Then I would use my state to filter my Object like
FlightList.js
const FlightList = ({ flights, filterValue }) => {
const filterdFlights = flights.filter(flight => Object.values(flight).includes(filterValue))
return (
<table className="table">
<thead>
<tr>
<th />
<th>Date</th>
<th>Provider</th>
<th>Dest</th>
</tr>
</thead>
<tbody>
{filterdFlights.map((f, i) => {
return (
<tr key={i}>
<td>
<input type="checkbox" name="flightListCheckbox" />
</td>
<td>{f.date}</td>
<td>{f.pnr}</td>
<td>{f.flightNumber}</td>
</tr>
);
})}
</tbody>
</table>
)};
You need an input for search and filter flights by value of input. Try this
class FlightPage extends React.Component {
state = {
keyword: '',
}
...
getFlights = () => {
const { keyword } = this.state
const { flights } = this.props
return flights.filter(flight => flight.name.includes(keyword)) // name or something else
}
onInputChange = e => {
this.setState({ keyword: e.target.value })
}
render () {
return (
<>
<input onChange=(this.onInputChange) value={this.state.keyword} />
<FlightList flights={this.getFlights()} />
</>
)
}
}
You can filter your flights array using flights.filter or sort it using flights.sort.
You could try to use jquery datatable. It adds a lot of funcionality to tables easy to implement.
DataTable doc
Any clue why this code won't be able to do sorting properly base on columns?
sort(key){
this.setState({
[`toggle-${key}`]: !this.state[`toggle-${key}`],
data: sortBy(this.state.data, [key], this.state[`toggle-${key}`]).map(v => v)
})
}
render() {
return (
<div style={styles}>
<table>
<thead>
{Object.keys(this.state.data[0]).map(v => {
return(
<th onClick={()=>this.sort(v)}>
{v.toUpperCase()}
</th>
)
})}
</thead>
<tbody>
{this.state.data.map(v=>{
return(
<tr>
<td>{v.id}</td>
<td>{v.name}</td>
</tr>
)
})}
</tbody>
</table>
</div>
);
}
The toggling of the state seems to be correct but the reflection is only happening for the first time.
https://codesandbox.io/s/zqno7m7j4p
Lodash's _.sortBy() doesn't have the ability to select descending or ascending. Use _.orderBy() instead (sandbox):
sort(key) {
const columnState = !this.state[`toggle-${key}`];
this.setState({
[`toggle-${key}`]: columnState,
data: orderBy(
this.state.data,
[key],
columnState ? 'desc' : 'asc'
)
});
}