I have a exercise I am working on/attempting to replicate and I am trying to add a modal button to the file. I have the button and the modal from React Bootstrap, however, I am unable to get the actual modal to show up. I was using the documentation from React-Bootstrap but getting the actual modal to come up is not working, I have tried to import the various modals but to no avail, am I missing something in my code?
import React from 'react';
import { Modal, Form, FormControl, Button, ButtonToolbar, InputGroup } from 'react-bootstrap';
import { connect } from 'react-redux';
import { addItem } from '../actions/itemActions';
function ItemModal(props) {
return (
<div>
<Button
variant="dark"
style={{marginBottom: '2em'}}
>Add Item
</Button>
<Modal
{...props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
Add to Shopping List
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Label for="item">Item</Form.Label>
<InputGroup className="mb-3">
<FormControl
type="text"
name="name"
id="item"
aria-label="Add Shopping Item"
aria-describedby="basic-addon2"
/>
<InputGroup.Append>
<Button onClick={props.onHide} variant="outline-dark">Add</Button>
</InputGroup.Append>
</InputGroup>
</Form>
</Modal.Body>
</Modal>
</div>
);
}
function App() {
const [modalShow, setModalShow] = React.useState(false);
return (
<ButtonToolbar>
<Button variant="dark" onClick={() => setModalShow(true)}>
Add Item
</Button>
<ItemModal
show={modalShow}
onHide={() => setModalShow(false)}
/>
</ButtonToolbar>
);
}
export default connect()(ItemModal);
I do have this extra bit of code that I though would function to open the modal but I don't think it works with this version of Bootstrap?
state = {
modal: false,
name: ''
}
toggle = () => {
this.setState({
modal: !this.state.modal
});
};
onChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
}
From your code snippet, I found an issue.
You have 2 component's in a single file, App and ItemModal. From which App component is your base / parent component and ItemModal is your child component.
But you are exporting child compoennt,
export default connect()(ItemModal);
You should export the parent component,
export default connect()(App);
Related
I have a Chakra UI Modal which opens up onClick of a button. I want to be able to extract the values that a user puts into the inputs/radio buttons when they close the Modal. The Modal class and the Modal/Button render is shown below. Since the input and radio buttons are defined within the Modal class, is it possible to get their final values onClose?
Modal.tsx
import React from 'react'
import {
Modal as ChakraModal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
ModalCloseButton,
RadioGroup,
Stack,
Radio,
VStack
} from "#chakra-ui/react"
import Button from './Button'
import Input from './Input'
type Props = { isOpen : boolean } & { onClose : () => void} & { label : string }
const Modal = ({ label, isOpen, onClose, ...rest }: Props) => (
<ChakraModal {...rest} isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>{label}</ModalHeader>
<ModalCloseButton />
<ModalBody>
<VStack spacing={4}>
<RadioGroup>
<Stack direction="row">
<Radio value="1">Annually</Radio>
<Radio value="2">Semi-Annual</Radio>
<Radio value="3">Quarterly</Radio>
<Radio value="4">Monthly</Radio>
</Stack>
</RadioGroup>
<Input
label="Custom Interest rate"
name="Custom Interest rate"
/>
</VStack>
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Save
</Button>
</ModalFooter>
</ModalContent>
</ChakraModal>
)
export default Modal
Render
<Button onClick={onOpen}> Settings </Button>
<Modal
label="Custom Settings"
isOpen={isOpen}
onClose={onClose}
/>
You should probably send a state as the modal's prop.
const [state, setState] = React.useState();
<Modal
label="Custom Settings"
isOpen={isOpen}
onClose={onClose}
onChange={setState}
/>
To get the type of setState, hover over the variable and you can see the type definition.
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>
);
}
During the development of my next React app, I had to use a modal component from react-bootstrap. It's actually working fine, but it looks like there are no stylesheets imported?
Here is my code
import React from "react";
import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';
class Nav extends React.Component {
constructor(props, context) {
super(props, context);
this.handleShow = this.handleShow.bind(this);
this.handleClose = this.handleClose.bind(this);
this.state = {
show: false,
};
}
handleClose() {
this.setState({ show: false });
}
handleShow() {
this.setState({ show: true });
}
render() {
return (
<>
<nav>
<h5>a pack of free css animations</h5>
<ul>
<li><button variant="primary" onClick={this.handleShow}>how to use ></button></li>
<li>
<form method="get" action="file">
<button type="submit">download ></button>
</form>
</li>
<li>see on github ></li>
</ul>
</nav>
<Modal
show={this.state.show}
onHide={this.handleClose}
aria-labelledby="ModalHeader"
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">How to use?</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>Once you downloaded <i>animation.min.css</i>, you have to link that to your project.<br />
To do that, use a 'link' tag, or just copy code of animation you like.</p>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.handleClose}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
);
}
}
export default Nav;
And it looks like that (Chrome)
Click me
Modal is displayed on bottom, text is not centered etc...
What do you think?
How to improve that?
Load the style from react-bootstrap, like below:
https://react-bootstrap.github.io/getting-started/introduction/
You are missing the stylesheet from react-bootstrap which is why the model is not getting styled properly. Add following to your html and it should work.
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
crossorigin="anonymous"
/>
Please go through the link to integrate your app and use with react-bootstrap.
In the below code, why does a call to the classes object work? It seems like the call should be to the styles object defined as a const up top.
For example, in this demo:
className={classes.button}
works as written. But it seems like it should be
className={styles.button}
Is there any actual classes object defined anywhere? If so, where is it defined? The markup implies a this.props.classes object. But there are no props passed to <Demo /> when called in index.js.
What's going on here?
https://codesandbox.io/s/qxv466wlq
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
const styles = theme => ({
button: {
margin: theme.spacing.unit,
},
input: {
display: 'none',
},
});
function OutlinedButtons(props) {
const { classes } = props;
return (
<div>
<Button variant="outlined" className={classes.button}>
Default
</Button>
<Button variant="outlined" color="primary" className={classes.button}>
Primary
</Button>
<Button variant="outlined" color="secondary" className={classes.button}>
Secondary
</Button>
<Button variant="outlined" disabled className={classes.button}>
Disabled
</Button>
<Button variant="outlined" href="#outlined-buttons" className={classes.button}>
Link
</Button>
<input
accept="image/*"
className={classes.input}
id="outlined-button-file"
multiple
type="file"
/>
<label htmlFor="outlined-button-file">
<Button variant="outlined" component="span" className={classes.button}>
Upload
</Button>
</label>
</div>
);
}
OutlinedButtons.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(OutlinedButtons);
If you look at this line:
export default withStyles(styles)(OutlinedButtons);
the answer to your question is provided I believe. Material UI has a function withStyles that takes a styles object, and then returns another function that takes a component to return a new component. This is a Higher Order Component, and can be read about on the React docs.
If you look at the linked code of withStyles, you can see the following line where it renders the passed in component:
return <Component {...more} classes={this.getClasses()} ref={innerRef} />;
And is providing the classes prop, making it available to any component exported with withStyles.
Im following this tutorial on bootstrap modal for react. This is the code i have:
import React, { Component } from 'react';
import { Modal } from 'react-bootstrap';
import { Button } from 'react-bootstrap';
import { Popover } from 'react-bootstrap';
import { OverlayTrigger } from 'react-bootstrap';
import { Tooltip } from 'react-bootstrap';
class Login extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
show: false
};
this.handleShow = this.handleShow.bind(this);
this.handleClose = this.handleClose.bind(this);
}
handleClose() {
this.setState({ show: false });
}
handleShow() {
console.log("Show")
this.setState({ show: true });
}
render() {
const popover = (
<Popover id="modal-popover" title="popover">
very popover. such engagement
</Popover>
);
const tooltip = <Tooltip id="modal-tooltip">wow.</Tooltip>;
return (
<div>
<p>Click to get the full Modal experience!</p>
<Button bsStyle="primary" bsSize="large" onClick={this.handleShow}>
Launch demo modal
</Button>
<Modal show={this.state.show} onHide={this.handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>
<h4>Text in a modal</h4>
<p>
Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
</p>
<h4>Popover in a modal</h4>
<p>
there is a{' '}
<OverlayTrigger overlay={popover}>
popover
</OverlayTrigger>{' '}
here
</p>
<h4>Tooltips in a modal</h4>
<p>
there is a{' '}
<OverlayTrigger overlay={tooltip}>
tooltip
</OverlayTrigger>{' '}
here
</p>
<hr />
<h4>Overflowing text to show scroll behavior</h4>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.handleClose}>Close</Button>
</Modal.Footer>
</Modal>
</div>
);
}
}
export default Login;
My issue is that when i click on the "Launch demo modal" - button the modal is not shown. I checked to see in the console if the boolean value for "show" is set to true when clicking which it is but somehow the modal is not shown anyway.
This is the entry-point for the application:
import Login from './Components/Modal/Login';
class App extends Component {
render() {
return (
<div className="App">
<Login/>
</div>
);
}
}
export default App;
I have tried to figure it out for hours now but i have no idea. I even used the exact same code as the tutorial at one point but with no luck. Any help is appretiated.
You forgot to add style.css files. add below links to your index.html file .
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
EDIT 1:
or without CDN (on your index.html)
import 'bootstrap/dist/css/bootstrap.css';
It may be useful to take a look at Conditional Rendering With React
:-)
render () {
return (
<div>
{this.state.show ? /*Your component*/ : null /*Or another component*/}
</div>
)
}
side note : Taking this approach means that your Modal component is not instantiated in the first place is this.state.show is false which could be beneficial application speed.
If you pass a show prop into your Modal this implies the Modal is being instantiated and some un needed logic is being applied whithin.
You can show modal using && operator with state like below. I have removed show prop to modal. Try below approach it will work
{this.state.show && (
<Modal onHide={this.handleClose}>
...... // place remaining code here
</Modal>
)}