Can't display bootstrap modal onClick - reactjs

I have a problem to display the bootstrap modal in my react-website. Here is my code:
import React,{Component} from 'react';
import './restaurant.css';
import {connect} from "react-redux";
import {IoMdArrowBack} from 'react-icons/io';
import './restaurantMenu.css';
import DishDetailModal from "./dishDetailModal";
class RestaurantMenu extends Component{
renderDishes = (dishes)=>{
console.log(dishes);
return dishes.map((item,index)=>{
console.log(item);
{
if (item.isAvailable === true) {
return (
<div key={index} className="dishContainer">
<button className="dishButton" onClick={()=><DishDetailModal/>}>
<text style={{fontWeight: 'bold'}}>{item.name}</text>
<br/>
<text>{item.discription}</text>
<br/>
<text>{item.price} €</text>
</button>
</div>
)
}else{
return(
<div key={index} className="dishContainer">
<text style={{fontWeight: 'bold'}}>{item.dishTitle}</text>
<br/>
<text>{item.dishDescription}</text>
<br/>
<text>{item.dishPrice} €</text>
</div>
)
}
}
})
}
render(){
return(
<div style={{textAlign:'center'}}>
<br/>
<div className="backButtonClass">
<button
className="backButton"
onClick={this.props.showMenuFunction}
>
<IoMdArrowBack size={40}/>
</button>
</div>
<br/>
{this.renderDishes(this.props.requestedData[this.props.restaurantId].dishes)}
</div>
)
}
}
In the renderDishes-function I want to render return all the dishes and wrap each in a button that opens the modal with specific dish-information. My problem is that the modal doesn't show up onClick. Here is the modal-component:
import React,{Component} from 'react';
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';
export default class DishDetailModal extends Component{
constructor(props) {
super(props);
this.state={
show: true
}
}
handleModal = () =>{
this.setState({show: !this.state.show})
};
render(){
return (
<>
<Button variant="primary" onClick={()=>this.handleModal}>
Launch demo modal
</Button>
<Modal show={this.state.show} onHide={()=>this.handleModal}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={()=>this.handleModal}>
Close
</Button>
<Button variant="primary" onClick={()=>this.handleModal}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
);
}
}

Related

React Modal Submit Form

I'm trying to print out a simple buttton clicked text whenever the submit button is click on my reactstrap modal and somehow my code doesn't do anything, not sure what I have wrong.
I have attached a picture for better visualisation , I'm using reactstrap Modal.
import React, { useState } from "react";
import { Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
import Button from "./Button";
// NOTICE
// Modal is brought in with it's own trigger, so import the component where you want the trigger to be.
const ModalComponent = (props) => {
const {
buttonText,
title,
actionButtonText,
cancelButtonText,
children,
className,
} = props;
const [modal, setModal] = useState(false);
const toggle = () => setModal(!modal);
const alertshow = () => {
alert("button clicked");
};
const closeBtn = (
<button className="close" onClick={toggle}>
×
</button>
);
return (
<div>
<a className="btn_link" onClick={toggle}>
{buttonText}
</a>
<form onSubmit={alertshow}>
<Modal isOpen={modal} toggle={toggle} className={className}>
<ModalHeader className=" border-0" toggle={toggle} close={closeBtn}>
{title}
</ModalHeader>
<ModalBody className="text-left border-0">
<p className="modal-label">Please enter your email address</p>
{children}
</ModalBody>
<ModalFooter className="modal-footer border-0">
<Button className="btn_secondary modal-btn" onClick={toggle}>
{cancelButtonText}
</Button>{" "}
<input
className="btn btn_primary modal-btn"
type="submit"
value={actionButtonText}
/>
</ModalFooter>
</Modal>
</form>
</div>
);
};
export default ModalComponent;
Its happening form should be part of modal not modal should be part of form. This is why its not referencing onSubmit. You need to do this:
<Modal isOpen={modal} toggle={toggle} className={className}>
<form onSubmit={alertshow}>
...rest all content
</Form>
</Modal>
Here is full code:
import React, { useState } from "react";
import "./styles.css";
import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from "reactstrap";
// NOTICE
// Modal is brought in with it's own trigger, so import the component where you want the trigger to be.
const ModalComponent = (props) => {
const {
buttonText,
title,
actionButtonText,
cancelButtonText,
children,
className
} = props;
const [modal, setModal] = useState(false);
const toggle = () => setModal(!modal);
const alertshow = () => {
alert("button clicked");
};
const closeBtn = (
<button className="close" onClick={toggle}>
×
</button>
);
return (
<div>
<div onClick={toggle}>{buttonText}</div>
<Modal isOpen={modal} toggle={toggle} className={className}>
<form onSubmit={alertshow}>
<ModalHeader className=" border-0" toggle={toggle} close={closeBtn}>
{title}
</ModalHeader>
<ModalBody className="text-left border-0">
<p className="modal-label">Please enter your email address</p>
{children}
</ModalBody>
<ModalFooter className="modal-footer border-0">
<Button className="btn_secondary modal-btn" onClick={toggle}>
{cancelButtonText}
</Button>{" "}
<input
className="btn btn_primary modal-btn"
type="submit"
value={actionButtonText}
/>
</ModalFooter>
</form>
</Modal>
</div>
);
};
export default function App() {
return (
<div className="App">
<ModalComponent
title="Hello"
cancelButtonText="Cancel"
actionButtonText="Submit"
buttonText="testing"
/>
</div>
);
}
Here is the demo: https://codesandbox.io/s/fervent-bash-51lxe?file=/src/App.js:0-1826
Accepted answer doesn't work when Modal is scrollable.
Here is how to resolve the issue:
<Modal show={ show } onHide={ onClose }
scrollable={ true }
onSubmit={ handleSubmit(onSave) }
dialogAs={ FormWrappedModal }>
<Modal.Header closeButton>
<Modal.Title>some title</Modal.Title>
</Modal.Header>
<Modal.Body>some body</Modal.Body>
<Modal.Footer>some body</Modal.Footer>
</Modal>
We need to introduce custom component FormWrappedModal for that purpose:
const FormWrappedModal = ( props: any)=>{
return (
<form onSubmit={ props.onSubmit }>
<Modal.Dialog { ...props } />
</form>
);
};

Input control is not editable on Multi Modal of react-bootstrap

I have two Modal Components in my application and on click of edit button in a Modal another Modal will open, and in the second Modal I have input control and its not editable
The following are the files which I used in my application.
import bootstrap css in index.js file as below
import 'bootstrap/dist/css/bootstrap.css'
App.js
function App() {
return (
<div>
<MyButton />
</div>
);
}
MyButton.js
export default class MyButton extends Component {
constructor(props) {
super(props);
this.state = {
personalInfoModalShow: false
};
}
render() {
let handlePersonalInfoModalHide = () => this.setState({
personalInfoModalShow: false
});
return (
<div>
<button className="btn btn-primary" onClick={() => this.setState({
personalInfoModalShow: true
})}
>
Open Modal
</button>
<PersonalInfoModal
show={this.state.personalInfoModalShow}
handlePersonalInfoModalHide={handlePersonalInfoModalHide}
/>
</div>
);
}
}
PersonalInfoModal.js
import React, {Component} from 'react';
import Modal from "react-bootstrap/Modal";
import {Container, Table} from "reactstrap";
import {FaPencilAlt} from "react-icons/fa";
import EditModal from "./EditModal";
export default class PersonalInfoModal extends Component {
constructor(props) {
super(props);
this.state = {
id: 100,
name: 'Sam',
department: 'IT',
isEditClicked: false,
editModalShow: false
};
}
render() {
let handleEditModalHide = () => this.setState({
isEditClicked: false,
editModalShow: false
});
return (
<div>
<Modal
show={this.props.show}
onHide={this.props.handlePersonalInfoModalHide}
size="lg"
centered
>
<Modal.Header closeButton>
<Modal.Title id="personal-modal-title">
Personal Information
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Container fluid>
<Table striped responsive size="sm" className="text-center mt-4">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Department</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>{this.state.id}</td>
<td>{this.state.name}</td>
<td>{this.state.department}</td>
<td>
<div onClick={() => this.setState({
isEditClicked: true,
editModalShow: true
})}
>
<FaPencilAlt />
</div>
{this.state.isEditClicked &&
<EditModal
show={this.state.editModalShow}
handleEditModalHide={handleEditModalHide}
department={this.state.department}
/>
}
</td>
</tr>
</tbody>
</Table>
</Container>
</Modal.Body>
</Modal>
</div>
);
}
}
EditModal.js
import React, {Component} from 'react';
import {Button, Modal} from "react-bootstrap";
export default class EditModal extends Component {
constructor(props) {
super(props);
this.state = {
department: props.department
};
}
handleChange = (e) => {
const input = e.target;
const name = input.name;
const value = input.value;
this.setState({[name]: value});
};
render() {
return (
<div>
<Modal
show={this.props.show}
onHide={this.props.handleEditModalHide}
size="sm"
centered
>
<Modal.Header closeButton>
<Modal.Title id="edit-modal-title">
Edit
</Modal.Title>
</Modal.Header>
<Modal.Body>
<input style={{width: "35%"}} type="text" value={this.state.department} name="department" onChange={this.handleChange} />
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.props.handleEditModalHide}>
Close
</Button>
<Button variant="primary" onClick={() => alert("saved")}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</div>
);
}
}

React-Redux Application: 'props' is not defined'

I am creating a React-Redux application. Before adding the content above render(), props was defined. However, after I started adding said content, the app began having problems reading the variable. I don't know what happened.
Could somebody please help me understand why props isn't being recognized anymore? I'd really appreciate it.
Login.js
import React from 'react';
import Modal from 'react-bootstrap/Modal';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import './login.css';
class LoginForm extends React.Component {
constructor(props) {
super(props);
this.state = {
username: ''
}
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({ [e.target.name]: e.target.value});
}
render() {
return (
<>
<Modal show={props.modalOpen} onHide={props.handleModalOpen}>
<Modal.Header closeButton>
<Modal.Title>Login</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group>
<Form.Label>Username</Form.Label>
<Form.Control
type="text"
name="username"
className="form-control"
/>
</Form.Group>
<Form.Group>
<Form.Label>Password</Form.Label>
<Form.Control
type="text"
name="password"
className="form-control"
/>
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button variant="danger" type="submit" onClick={props.handleModalOpen}>
Submit
</Button>
<Button variant="primary" onClick={props.handleClose}>
Cancel
</Button>
</Modal.Footer>
</Modal>
</>
);
}
}
export default LoginForm;
Navbar.js
import React from "react";
import { Link } from 'react-router-dom';
import './navbar.css';
import LoginForm from '../LoginForm/login.js';
// import SignUpModal from '../SignUpModal/signup.js';
class Navbar extends React.Component {
state = {
modalOpen: false
}
handleModalOpen = () => {
this.setState((prevState) => {
return {
modalOpen: !prevState.modalOpen
}
})
}
render() {
return (
<div>
<nav className="navbar navbar-expand-sm navbar-dark px-sm-5">
<div className="container">
<Link to='/'>
<div className="navbar-brand">
<i class="fas fa-globe fa-2x"></i>
</div>
</Link>
<ul className="navbar-nav align-items-right">
<li className="nav-item ml-5">
<a onClick={this.handleModalOpen} className="nav-link">
Login
</a>
</li>
<li className="nav-item ml-5">
<a onClick={this.handleModalOpen} className="nav-link">
Sign Up
</a>
</li>
</ul>
</div>
</nav>
<LoginForm
modalOpen={this.state.modalOpen}
handleModalOpen={this.handleModalOpen}
/>
{/* <SignUpModal
modalOpen={this.state.modalOpen}
handleModalOpen={this.handleModalOpen}
/> */}
</div>
)
}
}
export default Navbar;
In your Login.js, it's written using class-based syntax, hence it has to be this.props instead of props
<Modal show={this.props.modalOpen} onHide={this.props.handleModalOpen}>
Alternatively, Login.js can be rewrite into functional-based component, you can then use props like below
const Login = props => {
return (
<Modal show={props.modalOpen} onHide={props.handleModalOpen} />
)
}

How to change The style of a reactstrap modal in react?

Problem:
I have created A reactstrap Modal and now I want to add a custom styling to it so that I had a class and wrote CSS styling but it does not seem to work. Can someone help me to solve this problem?. This is my code.
import React, { Component } from "react";
import {
Card,
CardText,
Container,
Row,
Col,
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter
} from "reactstrap";
import "./Dashbord.css";
class YearCard extends Component {
constructor(props) {
super(props);
this.state = {
modal: false
};
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState(prevState => ({
modal: !prevState.modal
}));
}
render() {
return (
<Card className="year">
<Container>
<CardText className="year-text">Year</CardText>
</Container>
<div className="year-full-screen" onClick={this.toggle}>
<i className="fas fa-expand-arrows-alt" />
</div>
<Modal
className="modal-dialog"
isOpen={this.state.modal}
fade={false}
toggle={this.toggle}
>
<ModalHeader toggle={this.toggle}>Modal title</ModalHeader>
<ModalBody>My Modal</ModalBody>
<ModalFooter>
<Button color="primary" onClick={this.toggle}>
Do Something
</Button>{" "}
<Button color="secondary" onClick={this.toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
<hr className="horizentel-line" />
</Card>
);
}
}
export default YearCard;
This is my CSS.
.modal-dialog {
width: 100%;
margin-top: 10%;
}
I searched On the Internet to find a Solution to this problem. But I was unable to find any reasonable solution to this problem. If you can help me It would be a great pleasure for me.
These are the props available for reactstrap modal api,
Reference here
<Modal
className: YourCustomClass,
wrapClassName: YourCustomClass,
modalClassName: YourCustomClass,
backdropClassName: YourCustomClass,
contentClassName: YourCustomClass
/>
Just setting the prop modalClassName as modal-dialog would do the trick.
<Modal
modalClassName="modal-dialog"
isOpen={this.state.modal}
fade={false}
toggle={this.toggle}
>
...
This worked for me
<Modal ClassName={`customClass`} />

onClick Rendering is not happening ReactJs

I am creating a web application with react.js also using react-bootstrap.
What I want to accomplish is when user click on button then modal will appear but that is not happening.
Button code
<div className="rightButtons">
<button name="updateItem" className="btn btn-primary" onClick={() => { this.onUpdateItem(this.props.selectedAppTypeId)}} >Update Item</button>
</div>
function which will be called.
onUpdateItem = (id) => {
return (
<div className="static-modal">
<Modal.Dialog>
<Modal.Header>
<Modal.Title>Modal title</Modal.Title>
</Modal.Header>
<Modal.Body>One fine body...</Modal.Body>
<Modal.Footer>
<Button>Close</Button>
<Button bsStyle="primary">Save changes</Button>
</Modal.Footer>
</Modal.Dialog>
</div>
);
}
Any help would be great help. Thanks.
You are returning HTML into your onClick handler, and not into the Component's render method. If you want to show HTML content after an onClick, you need to actually return those HTML elements within the actual render. Try this:
class Component extends React.Component {
state = {
showModal: false
}
renderModal = () => {
return (
<div className="static-modal">
<Modal.Dialog>
<Modal.Header>
<Modal.Title>Modal title</Modal.Title>
</Modal.Header>
<Modal.Body>One fine body...</Modal.Body>
<Modal.Footer>
<Button>Close</Button>
<Button bsStyle="primary">Save changes</Button>
</Modal.Footer>
</Modal.Dialog>
</div>
);
}
render() {
return(
<div>
<button onClick={() => this.setState({showModal:true})}> Show </button>
{this.state.showModal && this.renderModal()}
</div>
)
}
}
Edit: You can also export that entire Modal return statement into its own component, and conditionally render the component when the showModal state is true.
const ModalComponent = (props) => {
return(
<div className="static-modal">
<Modal.Dialog>
<Modal.Header>
<Modal.Title>Modal title</Modal.Title>
</Modal.Header>
<Modal.Body>One fine body...</Modal.Body>
<Modal.Footer>
<Button>Close</Button>
<Button bsStyle="primary">Save changes</Button>
</Modal.Footer>
</Modal.Dialog>
</div>
)
}
class ParentComponent extends React.Component {
state = {
showModal: false
}
render(){
return(
<div>
<button onClick={() => this.setState({showModal:true})}>
Show Modal
</button>
{this.state.showModal && <ModalComponent id='0af141random'/>}
</div>
)
}
}
The problem that you have is that you're passing a react function component as an event handler; the return value of the function is a react component, but calling the function by itself won't mount that component in the DOM and display it.
A better way to make this happen might be to place your Modal component in your component hiearchy, and control whether it is shown by using a callback to change the state of a parent component.
Something like this:
class ParentComponent extends React.Component {
showModal() {
this.setState{
modalActive: true;
}
}
render() {
<div>
<Button onClick={showModal}>Show me the modal!</Button>
<Modal active={this.state.modalActive} />
</div>
}
}
const modalComponent = (props) => {
return (<div style={{ display: (props.isActive) ? "block" : "none "}}>
<h1>I'm a modal!</h1>
</div>)
}
I haven't checked, but I'm sure React Bootstrap has its own prop for displaying/hiding modals.
EDIT: Here's a code example from the react bootstrap documentation that shows it in use https://react-bootstrap.github.io/components/modal/#modals-live

Resources