sending data through a datalist in react - javascript

So over the last few months i started from 0 and started learning react. While it is a challenge i was heavily encouraged to keep going. Ive been pointed in the right direction a multitude of times thanks to stack overflow and am asking for help again. Right now i have a react component that makes a model popup.
In that popup i want to have a selectable list that can be submitted and posted. The idea is exactly like a data list. Which i am trying to do in react, currently the only way i know to send something in react is using axois library but im not able to render anything in the modal model. So i decide to make a jsx datalist in the modal body itself.
Is this the right way to go about it? is there an easier way to accomplish what i want to do within the model?
const ModalExample = (props) => {
const {
className
} = props;
const [modal, setModal] = useState(false);
const toggle = () => setModal(!modal);
const externalCloseBtn = <button className="close" style={{ position: 'absolute', top: '15px', right: '15px' }} onClick={toggle}>×</button>;
return (
<div>
<Button color="danger" onClick={toggle}>OTHER</Button>
<Modal isOpen={modal} toggle={toggle} className={className} external={externalCloseBtn}>
<ModalHeader>Add any soft skills that you believe you have</ModalHeader>
<ModalBody>
<form action="/amazonaws.com/updateSkill">
<input list="other1" name="other2" />
<datalist id="other1">
</option><option value="excellent Communication ">
</option><option value="Leadership experience">
</option><option value="Ability to work under pressure">
</option><option value="High work ethic">
</option><option value="Organized">
</option></datalist>
<input type="submit" />
</form>
</ModalBody>
<ModalFooter>
{/* <Button color="primary" onClick={toggle}>Do Something</Button>{' '}*/}
<Button color="secondary" onClick={toggle}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
);
}
export default ModalExample;
Thank you in advance

As I understand you want to get a data list from API and show it in the HTML section so add your API response to the state and use it in return section to show data in proper HTML tags.
const ModalExample = (props) => {
const {
className
} = props;
const [modal, setModal] = useState(false);
const [response, setResponse] = useState(false);
const apiCall = () => {
axios
.get("http://")
.then((response) => {
setResponse(response);
}).catch((error) => {
console.err(error);
});
}
useEffect(() => {
apiCall();
}, [value]);
const toggle = () => setModal(!modal);
const externalCloseBtn = <button className="close" style={{ position: 'absolute', top: '15px', right: '15px' }} onClick={toggle}>×</button>;
return (
<div>
<Button color="danger" onClick={toggle}>OTHER</Button>
<Modal isOpen={modal} toggle={toggle} className={className} external={externalCloseBtn}>
<ModalHeader>Add any soft skills that you believe you have</ModalHeader>
<ModalBody>
<form action="/amazonaws.com/updateSkill">
<input list="other1" name="other2" />
<datalist id="other1">
{response}
</datalist>
<input type="submit" />
</form>
</ModalBody>
<ModalFooter>
{/* <Button color="primary" onClick={toggle}>Do Something</Button>{' '}*/}
<Button color="secondary" onClick={toggle}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
);
}
export default ModalExample;

Related

How to access function component's state variables in ReactJS?

I've been developing a website and I'm faced with an issue about accessing state varibles to a component. I've a address page(Addresses.jsx file) which has address modal. I'm also have a component which contains address modal's content (Address.jsx). I would like to access state inside Address.jsx file. How can I do that? If you can help me. I would be very appreciate.
Here is my code blocks;
Address.jsx file;
const Addresses = () => {
const [selectedAddress, setSelectedAddress] = useState();
const [modalType, setModalType] = useState();
const {
elementRef: addressModalRef,
show: showAddressModal,
hide: hideAddressModal,
} = useModal();
return (
<>
<div className="bg-light px-3 px-lg-4 py-4">
<h1 className="h4 mb-4">My Addresses</h1>
<div className="row g-3">
<div className="col-12 col-md-6 col-lg-4">
<AddressButton
onClick={() => {
setSelectedAddress(undefined);
setModalType("NewAddress");
showAddressModal();
}}
/>
</div>
{ADDRESSES.map((address, i) => (
<div className="col-12 col-md-6 col-lg-4" key={i}>
<AddressButton
{...address}
onClick={() => {
setSelectedAddress(address);
setModalType("EditAddress");
showAddressModal();
}}
/>
</div>
))}
</div>
</div>
<AddressModal
address={selectedAddress}
elementRef={addressModalRef}
hide={hideAddressModal}
modalType={modalType}
/>
</>)};
export default Addresses;
Address Modal file;
const AddressModal = ({ address, elementRef, hide, modalType }) => {
const onSaveAddress = () => {
console.log(address);
hide();
};
return (
<Modal elementRef={elementRef} centered size="lg" fullscreen>
<ModalBody>
<AddressForm address={address} /> // I would like to get this component's state in onSaveAddress funtion
</ModalBody>
<ModalFooter>
<button
type="button"
className="btn btn-primary flex-grow-1 px-5"
onClick={onSaveAddress}>
Kaydet
</button>
</ModalFooter>
</Modal>)};
export default AddressModal;
Instead of accessing child components state, which is not possible, do the following
Address Model
<AddressForm
address={address}
onSave={onSaveAddress}
/>
Address Form
const AddressForm = ({ onSave }) => {
const handleFormSubmit = () => {
onSave(formData);
};
return (
<form onSubmit={handleFormSubmit}>
</form>
);
}
Then in onSaveAddress, you will have access to the form data.

React Component Re-Renders when updating input using React Hooks

I'm working on a React Project. I'm building a form with about 5 fields in it. I've used React Hooks to manage the state of the updates however when I enter in an input into the field. I can see the component re-render each time I enter a key stroke. the re-render is causing issues because it sets a state of a form field back to empty. Any help would be greatly appreciated!
Thanks,
Link to a gif of the re-render on keystroke can be found here: https://gph.is/g/ZxDqzmN
Link to clearing the form field: https://gph.is/g/4LjmDpd
import React, { useState } from "react";
import styled from "styled-components";
import {
Button,
CardContent,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Card as MuiCard,
Paper as MuiPaper,
TextField,
} from "#material-ui/core";
import { spacing } from "#material-ui/system";
export default function EmployeeFormDialog() {
const [open, setDialog] = useState(null);
const [carName, setCarName] = useState([""]);
const onSubmit = (data, event) => {
event.preventDefault();
console.log(data);
setDialog(false);
};
console.log("re-render");
const Card = styled(MuiCard)(spacing);
const Paper = styled(MuiPaper)(spacing);
return (
<Card mb={6}>
<CardContent>
<Paper mt={4}>
<div>
<Button variant="contained" color="primary" onClick={() => setDialog(true)}>
Add New Cars
</Button>
<Dialog open={open} aria-labelledby="form-dialog-title" disableEnforceFocus="true">
<form onSubmit={onSubmit}>
<DialogTitle id="form-dialog-title">Add New Car</DialogTitle>
<DialogContent>
<DialogContentText>To add new car</DialogContentText>
<TextField
onChange={(e) => setCarName(e.target.value)}
defaultValue={carName}
name="carName"
margin="dense"
id="carName"
label="Car Name"
type="text"
fullWidth
/>
<TextField
autoFocus
name="carYear"
margin="dense"
id="carYear"
label="Car Year"
type="text"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button type="button" onClick={() => setDialog(false)} color="primary">
Cancel
</Button>
<Button type="submit" color="primary">
Add Car
</Button>
</DialogActions>
</form>
</Dialog>
</div>
</Paper>
</CardContent>
</Card>
);
}

How to pass data from a table row and pass it to another component when it renders?

I have a component that shows a table and one of its columns have a field Actions which has buttons (view, edit, delete etc.). On button click, I need to render another component (component is a popup) and pass the data from the table so that it displays the data in some form which I need to further add.
I have managed to get the current data from its row by passing in onClick. I tried to use state for another component to render but it didn't work out. I'm using Semantic-UI React components to display the button with animations.
Here is the code that has the table,
const MainContent = () => {
const [actions, setActions] = useState(false);
const handleView = (rowData) => {
console.log(rowData);
setActions(true);
if (actions == true) return <ParentView />;
};
....
....
const contents = (item, index) => {
return item.routeChildEntry ? (
<>
<tr key={index}>
<td>{item.appName}</td>
<td></td>
<td>{item.createdTs}</td>
<td>{item.pattern}</td>
<td></td>
<td></td>
<td></td>
<td>
<Button animated onClick={() => handleView(item)}>
<Button.Content visible>View</Button.Content>
<Button.Content hidden>
<Icon name="eye" />
</Button.Content>
</Button>
</td>
</tr>
{item.routeChildEntry.map(routeContents)}
</>
) : (
....
....
....
);
};
return (
<div>
....
{loading ? (
<div className="table-responsive">
<table className="table">
<thead>
<tr>
<th>AppName</th>
<th>Parent_App</th>
<th>Created_Date</th>
<th>Req_Path</th>
<th>Resp_Code</th>
<th>Resp_Content_Type</th>
<th>Resp_Delay</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{data.map((routes, index) => {
return routes.map(contents, index);
})}
</tbody>
</table>
</div>
) : (
....
....
)}
</form>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default MainContent;
Below is the component to render on button click,
import React from "react";
import Popup from "reactjs-popup";
import { Icon } from "semantic-ui-react";
const Parent = (props) => {
return (
<Popup trigger={<Icon link name="eye" />} modal closeOnDocumentClick>
<h4>in parent</h4>
</Popup>
);
};
export default Parent;
How can I render the other component and pass data to it on button click?
Data can be passed to other components as props.
For example, if your component is <ParentView />, and the data you are passing is contained in the variable rowData, you can pass it as:
<ParentView dataPassedByAkhil = {rowData}/>
Then in your ParentView component,
export default function ParentView({dataPassedByAkhil}) {
console.log(dataPassedByAkhil);
Alternatively, you can accept the data as props as below
export default function ParentView(props) {
console.log(props.dataPassedByAkhil);
If you want to open and close another popup, you can pass a state just like above.
<PopupComponent open={stateSetForPopupByParent}/>
Example of popup using state.
Updated link above with how to pass data to the dialog from rows of buttons
Here is the full code:
export default function FormDialog() {
const [open, setOpen] = React.useState(false);
const [valueofRow, setValueOfRow] = React.useState();
const handleClickOpen = (value) => {
setValueOfRow(value);
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Button
variant="outlined"
color="primary"
onClick={() => {
handleClickOpen("John");
}}
>
Row 1 - value is John
</Button>
<br />
<br />
<Button
variant="outlined"
color="primary"
onClick={() => {
handleClickOpen("Sally");
}}
>
Row 2 Value is Sally
</Button>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="edit-apartment"
>
<DialogTitle id="edit-apartment">Edit</DialogTitle>
<DialogContent>
<DialogContentText>Dialog fired using state</DialogContentText>
<h1>{valueofRow} was clicked and passed from the row</h1>
<TextField
autoFocus
margin="dense"
id="field"
label="some field"
type="text"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="secondary">
Cancel
</Button>
<Button onClick={handleClose} color="primary">
Submit
</Button>
</DialogActions>
</Dialog>
</div>
);
}

How to use multiple material ui dialog with React?

I want to use two dialog in sign up page and login page.
the implement that I want to do are signup screen showing up when click to sign up button on the Top page, and login screen showing up when click to login Button on signup page.
I wrote open state on App.js.
but the trouble is when it's written in App.js, two of modal open..
Does anyone know how to settle it?
App.js
const App = () => {
const [open, setOpen] = useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Top handleClickOpen={handleClickOpen}/>
<SignupModal open={open} handleClose={handleClose} />
<LoginModal open={open} handleClose={handleClose} />
</div>
)
Top.js
const Top = (props) => {
const classes = useStyles();
return (
<React.Fragment>
<div style={style}>
<Button variant="outlined" className={classes.loginButton} onClick={props.handleClickOpen}>
Login
</Button>
</div>
<h1>Toppage</h1>
</React.Fragment>
);
}
SignupModal.js
const SignupModal = (props) => {
return (
<div>
<Dialog
open={props.open}
onClose={props.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title" className={classes.title}>Sign up</DialogTitle>
<DialogContent className={classes.content}>
<div className={classes.text}>
<TextField id="standard-basic" label=“name” fullWidth/>
<TextField id="standard-basic" label=“email” fullWidth/>
<TextField id="standard-basic" label=“password” fullWidth/>
<TextField id="standard-basic" label=“pass”word fullWidth/>
</div>
</DialogContent>
<p className={classes.toLogin}>to Login</p>
<DialogActions>
<Button onClick={props.handleClose} className={classes.signUpButton}>
Send
</Button>
</DialogActions>
</Dialog>
</div>
);
}
LoginModal.ls
const LoginModal = (props) => {
return (
<div>
<Dialog
open={props.open}
onClose={props.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title" className={classes.title}>Login</DialogTitle>
<DialogContent className={classes.content}>
<div className={classes.text}>
<TextField id="standard-basic" label=“name” fullWidth/>
<TextField id="standard-basic" label=“pass”word fullWidth}/>
</div>
</DialogContent>
<DialogActions>
<Button onClick={props.handleClose} className={classes.signUpButton}>
Login
</Button>
</DialogActions>
</Dialog>
</div>
);
}
export default LoginModal
You are sharing the state on both of your modals that's why.
The solution is simple, have 2 states; one that will determine if SignupModal is opened or not and another one for LoginModal.
const App = () => {
const [openLogin, setOpenLogin] = useState(false);
const [openSignup, setOpenSignup] = useState(false);
return (
<div>
<Top
onClickLogin={() => setOpenLogin(true)}
onClickSignup={() => setOpenSignup(true)}
/>
<SignupModal open={openLogin} handleClose={() => setOpenLogin(false)} />
<LoginModal open={openSignup} handleClose={() => setOpenSignup(false)} />
</div>
);
};
const Top = (props) => {
return (
<React.Fragment>
<div>
<Button
variant="outlined"
className={classes.loginButton}
onClick={props.onClickLogin}
>
Login
</Button>
<Button
variant="outlined"
className={classes.loginButton}
onClick={props.onClickSignup}
>
Signup
</Button>
</div>
<h1>Toppage</h1>
</React.Fragment>
);
};

scrollIntoView onClick reactjs

hello I have a few buttons and I want to scroll to them when clicked.
const [active, setActive] = useState(0);
useEffect(() => {
// I´m not using useRef. is there other way to automatically scroll to the element and stop at 0 0 of the page?
})
<div style={{height: '10000px'}} />
<button onClick={() setActive(1)}>button 1</button>
<button onClick={() setActive(2)}>button 2</button>
<button onClick={() setActive(3)}>button 3</button>
<div style={{height: '10000px'}} />
as you can see there´s a lot of scroll caused by those 2 divs. the idea is to scroll down and when you reach the buttons and click the one you need. the page scrolls to that button leaving it in the top of the page
image 1: scroll in random position
image 2: when you click on button 1
image 3: when you click on button 2
image 4: when you click on button 3
For scrolling react view to top there is a simple function.
use window.scrollTo(0, 0);
inside your code try this.
<button onClick={()=> window.scrollTo(0, 0) }>button 1</button>
edited:
I could come up with this solution after you edited your question.
import React, { useRef } from "react";
export default function App() {
const button1Ref = useRef();
const button2Ref = useRef();
const button3Ref = useRef();
const handleScroll = ref => {
window.scrollTo({
behavior: "smooth",
top: ref.current.offsetTop
});
};
return (
<div className="App">
<div style={{ height: "10000px" }} />
<div>
<button ref={button1Ref} onClick={() => handleScroll(button1Ref)}>
button 1
</button>
</div>
<div>
<button ref={button2Ref} onClick={() => handleScroll(button2Ref)}>
button 2
</button>
</div>
<div>
<button ref={button3Ref} onClick={() => handleScroll(button3Ref)}>
button 3
</button>
</div>
<div style={{ height: "10000px" }} />
</div>
);
}
Please try it out. Let me know if this is what you asked for.
Edited after question asked in comment for using single component with Ref and using that component in multiple numbers:
If you want to use a single component for button then try this,
import React, { useRef } from "react";
export default function App() {
return (
<div className="App">
<div style={{ height: "10000px" }} />
<MyButton>button 1</MyButton>
<MyButton>button 2</MyButton>
<MyButton>button 3</MyButton>
<div style={{ height: "10000px" }} />
</div>
);
}
const MyButton = props => {
const buttonRef = useRef();
const handleScroll = () => {
window.scrollTo({
behavior: "smooth",
top: buttonRef.current.offsetTop
});
};
return (
<div>
<button ref={buttonRef} onClick={handleScroll}>
{props.children}
</button>
</div>
);
};
Here you want to use an event handler.
const handleClick = (e) => {
// scrollIntoView logic and set state
}
<div onClick={handleClick}/>
//action
const goDown= (e) => {
const anchor = document.querySelector('#some-id')
anchor.scrollIntoView({ behavior: 'smooth', block: 'center' })
}
// click to scroll
<Link onClick={goDown}>Choose Health</Link>
//element you want to scroll to
<div id='some-id'>
</div>

Categories