Toggle Between Icons & Edit Table - React - javascript

Actually I am facing three issues that is
I have used useState and trying to toggle between icons & button but vise versa is not happening
If I call the edit Icon it All table the Edit Icon are changing to other save button
Once I am on edit I need to target the paticular row only
All above three table will be handled by one change but How i am not sure
Here is the code
import React, { useState } from 'react';
import { ReactComponent as EditIcon } from '../../../assets/icons/edit-icon.svg';
import './ProductLineTable.css';
import { ReactComponent as AddIcon } from '../../../assets/icons/add-icon.svg';
import {
Typography,
Table,
TableHead,
TableRow,
TableCell,
TableContainer,
TableBody,
Button,
Input,
InputAdornment,
TextField
} from '#material-ui/core';
export const data= [
{ id:1,Name:'test1',Class: 6Gender:'M'},
{ id:2,Name:'test1',Class: 6Gender:'M'},
{ id:3,Name:'test1',Class: 6Gender:'M'},
];
const Table = props => {
const [isEdit, setIsEdit] = useState(false);
const editClick=()=>{
setIsEdit(true);
}
const cancelClick=()=>{
setIsEdit(false);
}
return (
<>
<TableContainer className='product-line-table'>
<Table>
{data.map((k, index) => (
<TableRow key={k.Id}>
<TableCell>
<Typography>
{isEdit ? (
<TextField
data-test='firstname-input'
// label='Enter Product Code'
className='form-input user-search-textbox'
value={k.Name}
// onChange={e => {
// handleChange(e, index, 'Product');
// }}
/>
) : (
k.Name
)}
</Typography>
</TableCell>
<TableCell>
<Typography>{k.Class}</Typography>
</TableCell>
<TableCell>
<Typography>{k.Gender}</Typography>
</TableCell>
<TableCell align='center'>
<Typography>
{isEdit ? (
<>
<Button
variant='contained'
color='primary'
size='small'
onClick={() => {
cancelClick
}}
>
Save
</Button>
<Button
color='secondary'
variant='outlined'
type='reset'
size='small'
className='user-reset-btn'
onClick={() => {
cancelClick
}}
>
Cancel
</Button>
</>
) : (
<Button
onClick={editClick}
>
<EditIcon />
</Button>
)}
</Typography>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</>
);
};
export default Table;

Related

React TypeError: Cannot read properties of undefined (reading 'state')

I want to update the text of a button when i click on that button. I am using setState for that but i am unable to use it as it gives me the following error:
TypeError: Cannot read properties of undefined (reading 'state')
Here is my code:
import Head from 'next/head';
import { Box, Container, Grid, Pagination } from '#mui/material';
import { products } from '../__mocks__/products';
import { ProductListToolbar } from '../components/product/product-list-toolbar';
import { ProductCard } from '../components/product/product-card';
import { DashboardLayout } from '../components/dashboard-layout';
import { CustomerListResults } from '../components/trip/trip-list-results';
import { customers } from '../__mocks__/customers';
import { trips } from '../__mocks__/trips';
import { TripListResults } from '../components/customer/customer-list-results';
import {
Avatar,
Card,
Checkbox,
Table,
TableBody,
TableCell,
TableHead,
TablePagination,
TableRow,
Typography,
Button
} from '#mui/material';
import NextLink from 'next/link';
const TripRequests = () => {
const accept =()=> {
this.setState({accept: 'Payment Pending'})
console.log("fsfdsa");
};
this.state = {
accept: "Accept"
};
return (
<>
<Head>
<title>
Trip Requests
</title>
</Head>
<Box
component="main"
sx={{
flexGrow: 1,
py: 8
}}
>
<Container maxWidth={false}>
<Box sx={{ mt: 3 }}>
{/* <CustomerListResults customers={trips} /> */}
<h2>Trip Requests (2)</h2>
</Box>
<Box sx={{ minWidth: 1050, mt: 3 }}>
<Table>
<TableHead>
<TableRow>
<TableCell padding="checkbox">
{/* <Checkbox
// checked={selectedCustomerIds.length === customers.length}
color="primary"
// indeterminate={
// selectedCustomerIds.length > 0
// && selectedCustomerIds.length < customers.length
// }
// onChange={handleSelectAll}
/> */}
</TableCell>
{/* <TableCell>
Trip Id
</TableCell> */}
<TableCell>
Customer
</TableCell>
<TableCell>
Departure
</TableCell>
<TableCell>
Destination
</TableCell>
<TableCell>
Truck / Driver
</TableCell>
<TableCell>
Action
</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow
hover
// key={customer.id}
// selected={selectedCustomerIds.indexOf(customer.id) !== -1}
>
<TableCell padding="checkbox">
{/* <Checkbox
checked={selectedCustomerIds.indexOf(customer.id) !== -1}
onChange={(event) => handleSelectOne(event, customer.id)}
value="true"
/> */}
</TableCell>
<TableCell>
Rohan Joshi
</TableCell>
<TableCell>
<Box
sx={{
alignItems: 'center',
display: 'flex'
}}
>
{/* <Avatar
src={customer.avatarUrl}
sx={{ mr: 2 }}
>
{getInitials(customer.name)}
</Avatar> */}
<Typography
color="textPrimary"
variant="body1"
>
A-50, Sec 67, Noida
</Typography>
</Box>
</TableCell>
<TableCell>
HUDA City Center
</TableCell>
<TableCell>
fds
</TableCell>
<TableCell>
<Button onClick={accept}>{state.accept}</Button>
<Button>Decline</Button>
</TableCell>
{/* <TableCell>
{format(customer.createdAt, 'dd/MM/yyyy')}
</TableCell> */}
</TableRow>
</TableBody>
</Table>
</Box>
</Container>
</Box>
</>
);
TripRequests.getLayout = (page) => (
<DashboardLayout>
{page}
</DashboardLayout>
)};
export default TripRequests;
Looks like you are mixing class-based components with function components. In your case this refers to the module-level this which is undefined. Function components don't make use of this.
To use state in function components you need to use the useState hook:
const TripRequests = () => {
const [acceptState, setAcceptState] = useState('Accept')
const accept = () => setAcceptState('Payment Pending')
// ...
}

how to send the data from one component to another component when i press a button. React.js

I have a table where i render a data from the pokemon api, well in the table i have a button and when you press the button you get the data from the arrow, so i want to send that data from my component table to another component card and in that card render only the data which you select from the table. But i don't know how to send the data to my component Card whitout render my card five times in my table. Now i get the data when i press the button, i just need to send him.
Rows on the table component
export const Lista = (props) => {
const [, setPokeSelec] = useState({
})
const selectArrow = ( poke ) => {
setPokeSelec( poke );
console.log(poke);
}
return (
<>
<TableRow key={ props.info.id }>
<TableCell component="th" scope="row">
{ props.info.id }
</TableCell>
<TableCell align="right">{ props.info.name }</TableCell>
<TableCell align="right">{ props.info.abilities[0].ability.name}</TableCell>
<TableCell align="right">
<img src={ props.info.sprites.front_default } alt={ props.info.name } style={{ height: 60 }} />
</TableCell>
<TableCell align="right">
<Button
variant="contained"
color="primary"
size="small"
onClick={ () => selectArrow( props.info ) }
>
Seleccionar
</Button>
</TableCell>
</TableRow>
</>
)
}
Card component
export const Informacion = () => {
const classes = useStyles();
return (
<div className={ classes.margen } >
<Box display="flex" justifyContent="center" alignItems="center">
<Card className={classes.root}>
<CardMedia
className={classes.cover}
image={pika}
title="Live from space album cover"
/>
<div className={classes.details}>
<CardContent className={classes.content}>
<Typography component="h5" variant="h5">
Pikachu
</Typography>
<Divider/>
<Typography variant="subtitle1" color="textPrimary">
Tipo:
</Typography>
</CardContent>
</div>
</Card>
</Box>
</div>
)
}
PokemonApi Component
Here i call the API, render the table and send to my component table the data
export const PokemonApi = () => {
const classes = useStyles();
const [poke, setPoke] = useState([]);
const data = () => {
axios.get(`https://pokeapi.co/api/v2/pokemon?limit=100`).then(( response ) => {
for(let i = 0; i < response.data.results.length; i++ ) {
axios.get(response.data.results[i].url)
.then( result => {
setPoke(prevArray => [...prevArray, result.data])
// console.log(result.data);
})
}
})
.catch( err => {
console.log(err);
})
}
useEffect(() => {
data()
}, []);
return (
<>
<TableContainer className={ classes.margin } component={Paper}>
<Table className={ classes.table } size="small" aria-label="a dense table">
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell align="right">Name </TableCell>
<TableCell align="right">Type </TableCell>
<TableCell align="right">Img </TableCell>
<TableCell align="right">Actions </TableCell>
</TableRow>
</TableHead>
<TableBody>
{ poke.map((infos, name) => <Lista key={name} info={infos}/>) }
</TableBody>
</Table>
</TableContainer>
</>
)
}
This is the page where i render the card and the PokemonApi
export const Pokes = () => {
return (
<Container maxWidth="md">
<PokemonApi />
<Informacion />
</Container>
)
}
Thanks for your time!!
Here are the common ways to pass data from a component A to a component B :
Having the component B as a child of the component A (see this link)
Having the component A as a child of the component B, with a callback prop that gets fired in the component A (see this link)
Using the context API
Hope that this answer helped you

How to subtract only selected value from Array

Hello here is my problem, I have implemented a table that table fill when I choose some suggestion. The table contains three columns of (product, qty, balance and add button) So when I click add button it displays some popup form.
So I want to do when adding some quantity in the popup menu and after that click the add button it will reduce from the balance field in the table according to the selected product. Below is the table array.
import React, { useState } from "react"
import {
Grid,
Table,
TableContainer,
TableHead,
TableRow,
TableCell,
Paper,
TableBody,
Button
} from "#material-ui/core"
import AddItem from "./AddItem"
import { useStyles } from "../../../../styles/classes"
export default function ItemsList({
cart,
handleChange,
handleBlur,
values,
setFieldValue,
volumes
}) {
const [open, setOpen] = useState(false)
const [productId, setProductId] = useState("")
const [factoryId, setFactoryId] = useState("")
const handleClickOpen = (productId, factoryId) => {
setProductId(productId)
setFactoryId(factoryId)
setOpen(true)
}
const handleClose = (value) => {
setOpen(false)
}
const addToList = (factory) => {
setOpen(false)
const product = cart.find(
(item) => item.productId === Number(productId)
)
const item = {
productId: productId,
productName: product.productName,
containerNo: values.containerNo,
sealNo: values.sealNo,
qty: values.qty,
factoryId: factory.id,
factory: factory.name,
printDate: values.printDate,
printTime: values.printTime,
palletNo: values.palletNo,
}
const idx = values.volumes.findIndex(e=>e.number === Number(values.noOfContainers))
console.log(idx)
const current = values.volumes[idx].data;
current.push(item)
setFieldValue(`volumes[${idx}].data`,current)
//sum of qty in loaded volumes for this product
values.invoiceItems.forEach((item, idx) => {
item.balance = (Number(item.balance) - Number(values.qty))
})
setFieldValue('invoiceItems', values.invoiceItems)
}
const classes = useStyles()
return (
<Grid item md={12} sm={12} xs={12}>
<TableContainer component={Paper} >
<Table className={classes.table} size="small">
<TableHead>
<TableRow>
<TableCell align="left">Product</TableCell>
<TableCell align="left">Quantity</TableCell>
<TableCell align="left">Balance</TableCell>
<TableCell align="left">Add</TableCell>
</TableRow>
</TableHead>
<TableBody>
{cart.map((row, i) => (
<TableRow key={i}>
<TableCell align="left">{row.productName}</TableCell>
<TableCell align="left">{row.qty}</TableCell>
<TableCell align="left">{row.balance}</TableCell>
<TableCell align="left">
<Button
variant="outlined"
size="small"
color="secondary"
onClick={() => {
handleClickOpen(row.productId)
}}>
add
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<AddItem
open={open}
onClose={handleClose}
handleChange={handleChange}
handleBlur={handleBlur}
values={values}
addToList={addToList}
volumes={volumes}
/>
</Grid>
)
}
import React, { useState} from "react"
import {
Grid,
Card,
CardContent,
CardActions,
Button,
CardHeader,
} from "#material-ui/core"
import Alert from "#material-ui/lab/Alert"
import axios from 'axios'
//validation
import { Formik, Form } from "formik"
import * as Yup from 'yup'
import { useStyles } from "../../../styles/classes"
import ItemList from "./subComponents/ItemsList"
import MetaData from "./subComponents/MetaData"
import ContainerList from "./subComponents/ContainerList"
import {useInitialValues} from '../../../hooks/useLoadingInfoData'
// validation schema
let validationSchema = Yup.object().shape({
volumes: Yup.string().required(),
})
export default function LoadingInfo(props) {
const classes = useStyles()
const [initialValues, setInitialValues] = useInitialValues()
const [volumes, setVolumes] = useState([])
const [alert, setAlert] = useState({
showAlert: false,
severity: "success",
message: "",
})
// create method
const submit = async (e, { resetForm }) => {
try {
await axios.post("/loadingInfo", e)
resetForm()
setAlert({
showAlert: true,
severity: "success",
message: "Loading Information created successfully!",
})
} catch (error){
if (error.response.status === 422) {
setAlert({
showAlert: true,
severity: 'error',
message: 'Loading information already exists!',
})
} else {
setAlert({
showAlert: true,
severity: 'error',
message: 'Loading information creation failed!',
})
}
}
}
return (
<Grid container className={classes.root} spacing={1}>
<Grid item xs={12} sm={12} md={12}>
<Formik
initialValues={initialValues}
onSubmit={submit}
validationSchema={validationSchema}
enableReinitialize>
{({
isValid,
dirty,
values,
handleChange,
handleBlur,
setFieldValue,
errors,
}) => {
return (
<Form>
<Card variant="outlined" style={{marginBottom: '1rem'}}>
<CardHeader title="Loading Information"></CardHeader>
<CardContent>
<Grid container spacing={1}>
<MetaData
values={values}
handleChange={handleChange}
handleBlur={handleBlur}
setAlert={setAlert}
setFieldValue={setFieldValue}
/>
<ItemList
cart={values.invoiceItems}
values={values}
handleChange={handleChange}
handleBlur={handleBlur}
setFieldValue={setFieldValue}
volumes={volumes}
/>
</Grid>
</CardContent>
</Card>
<Card variant="outlined">
<CardContent>
{values.volumes.map( (data , idx) =>
<ContainerList values={data} idx={idx} setFieldValue={setFieldValue}/>
)}
</CardContent>
<CardActions>
<Button
variant="contained"
color="primary"
type="submit"
disabled={!dirty || !isValid}>
create
</Button>
</CardActions>
</Card>
</Form>
)
}}
</Formik>
</Grid>
<Grid></Grid>
{alert.showAlert && (
<Grid item md={12}>
<Alert
severity={alert.severity}
onClose={() =>
setAlert({
...alert,
showAlert: false,
})
}>
{alert.message}
</Alert>
</Grid>
)}
</Grid>
)
}

Open Dialog From Other Page In React

I'm opening a dialog component when i click the DELETE function button on my users list. When i click it, should show the dialog component. My problem is why i can't open it. I'm using redux to pass data to it.
Pls see this codesandbox link
CLICK HERE
import { dialogConstants } from "../constants";
export const initialState = {
title: null,
details: null,
isOpen: null
};
const dialogReducer = (state = initialState, action) => {
console.log(action.payload);
switch (action.type) {
case dialogConstants.SET_DIALOG_DETAILS:
return {
...state,
isOpen: action.payload.isOpen,
title: action.payload.title,
details: action.payload.details
};
default:
return state;
}
};
export default dialogReducer;
You are not importing Dialogs in user.js. So when you click button your dialog will not open. Try this:
In user.js:
...
import DeleteDialog from "./dialog";
import { useDispatch } from "react-redux";
import { deleteUser } from "./actions";
export default function User() {
const dispatch = useDispatch();
const [selectedUser, setSelectedUser] = React.useState({});
const [open, setDialogOpen] = React.useState(false);
const handleOnDelete = user => {
setSelectedUser(user);
setDialogOpen(true);
};
const handleOnAgree = () => {
// do action to handle on agree deleting an user
dispatch(deleteUser({ title: "Delete User", details: selectedUser }));
setDialogOpen(false);
};
return (
<div>
<Paper>
<TableContainer>
<Table stickyHeader aria-label="sticky table">
<TableHead>
<TableRow>
<TableCell>First Name</TableCell>
<TableCell>Last Name</TableCell>
<TableCell>Email Address</TableCell>
<TableCell>Actions</TableCell>
<TableCell />
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>JJJ</TableCell>
<TableCell>BBB</TableCell>
<TableCell>enfoie</TableCell>
<TableCell>
<Button variant="contained">Edit</Button>
<Button
variant="contained"
onClick={() => handleOnDelete({ id: 1, name: "JJJ" })}
>
Delete
</Button>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</Paper>
<DeleteDialog
user={selectedUser}
open={open}
onAgree={handleOnAgree}
onDisagree={() => setDialogOpen(false)}
/>
</div>
);
}
In dialog.js:
import React from "react";
import Button from "#material-ui/core/Button";
import Dialog from "#material-ui/core/Dialog";
import DialogActions from "#material-ui/core/DialogActions";
import DialogTitle from "#material-ui/core/DialogTitle";
import Slide from "#material-ui/core/Slide";
const Transition = React.forwardRef(function Transition(props, ref) {
return <Slide direction="up" ref={ref} {...props} />;
});
const DeleteDialog = ({ user, open, onAgree, onDisagree }) => {
return (
<div>
<Dialog
open={open}
TransitionComponent={Transition}
keepMounted
onClose={onDisagree}
aria-labelledby="alert-dialog-slide-title"
aria-describedby="alert-dialog-slide-description"
>
<DialogTitle id="alert-dialog-slide-title">
<span style={{ fontWeight: "bold" }}>
{" "}
User: {user.name} - {user.id}
</span>
</DialogTitle>
<DialogActions>
<Button variant="contained" size="small" onClick={onDisagree}>
Cancel
</Button>
<Button variant="contained" size="small" onClick={onAgree}>
Confirm
</Button>
</DialogActions>
</Dialog>
</div>
);
};
export default DeleteDialog;

How to create checkbox in A React Function

I am trying to create a Checkbox to display and hide my React Table with some data in it. I have only used classes and am new to using Functions and as a result am struggling to implement a way to create a checkbox that can hide my React Table or a column.
import "react-table/react-table.css";
import React, { Component, useState, useEffect } from "react";
function dataquery() {
return fetch("www.website.com").then(response =>
response.json()
);
}
function Offence() {
const [count, setCount] = useState([]);
useEffect(() => {
dataquery().then(headlines => {
setCount(headlines);
});
}, []);
//event.preventDefault();
console.log(count.offences);
let data = [{}];
if (typeof count.offences !== "undefined" ) {
let newdata = count.offences.map(count => data.push({ name: count }));
// console.log("???");
}
console.log(typeof count.offence);
const columns = [
{
Header: "Name",
accessor: "name",
},
];
// trying to hide this react table or just hide the column
return <ReactTable data={data} columns={columns} filterable />;
}
export default Offence;
I am exporting this function into another file in which I render 'Offence'.
The fetch website is not the actual website as it needs a private login to work, so I replaced it with this placeholder for the purpose of this.
Thank you.
You can easily add an useState hook, which stores a boolean to show/not show the table. Then toggle this state when changing a checkbox. For example:
function Offence() {
// ... your component code
const [showTable, setShowTable] = useState(true);
// output
return (
<>
<input
type="checkbox"
checked={showTable}
onChange={() => { setShowTable(p => !p); }}
/>
{showTable ? <ReactTable ... /> : null}
</>
);
}
I have only used classes and am new to using Functions
In such a situation, I highly recommend to use materialui components. It would make your life much easier because you need not to step into gory details of styling anymore if you do not want to.
Below I roughly drafted a component which contains a table and a list of checkboxes for switching hide/show columns.
Hope it helps :)
import React, { useState, useEffect } from 'react'
import Grid from '#material-ui/core/Grid';
import Card from '#material-ui/core/Card';
import CardHeader from '#material-ui/core/CardHeader';
import CardContent from '#material-ui/core/CardContent';
import Table from '#material-ui/core/Table';
import TableBody from '#material-ui/core/TableBody';
import TableCell from '#material-ui/core/TableCell';
import TableHead from '#material-ui/core/TableHead';
import TableRow from '#material-ui/core/TableRow';
import FormControl from '#material-ui/core/FormControl';
import FormGroup from '#material-ui/core/FormGroup';
import FormControlLabel from '#material-ui/core/FormControlLabel'
import Checkbox from '#material-ui/core/Checkbox';
function App() {
const [showName, setshowName] = useState(true);
const [showQty, setshowQty] = useState(true);
const [showPrice, setshowPrice] = useState(true);
const dummydata = [{ name: "apple", qty: 12, price: 3.3 }, { name: "orange", qty: 3, price: 1.5 }, { name: "grape", qty: 10, price: 4.3 }]
return (
<Grid
container
direction="row"
justify="space-around"
alignItems="center"
>
<Grid item xs={12} sm={5}>
<Card>
<Table>
<TableHead>
<TableRow>
{showName ? <TableCell>Name</TableCell> : ""}
{showQty ? <TableCell >Qty.</TableCell> : ""}
{showPrice ? <TableCell >Price</TableCell> : ""}
</TableRow>
</TableHead>
<TableBody>
{dummydata.map(item => (
<TableRow>
{showName ? <TableCell component="th" scope="row" padding="none">
{item.name}
</TableCell> : ""}
{showQty ? <TableCell>{item.qty}</TableCell> : ""}
{showPrice ? <TableCell>{item.price}</TableCell> : ""}
</TableRow>
))}
</TableBody>
</Table>
</Card>
</Grid>
<Grid item xs={12} sm={5}>
<Card>
<CardHeader
title="Hide any column?"
/>
<CardContent>
<FormControl style={{ margin: 4 }}>
<FormGroup>
<FormControlLabel
control={
<Checkbox onChange={(e, checked) => setshowName(checked)} checked={showName} />
}
label="Hide Name"
/>
<FormControlLabel
control={
<Checkbox onChange={(e, checked) => setshowQty(checked)} checked={showQty} />
}
label="Hide Quantity"
/>
<FormControlLabel
control={
<Checkbox onChange={(e, checked) => setshowPrice(checked)} checked={showPrice} />
}
label="Hide Price"
/>
</FormGroup>
</FormControl>
</CardContent>
</Card>
</Grid>
</Grid>
);
}
export default App;

Categories