How to display the products in modal body - reactjs

I struck in the code that trying to display the products in modal body but not displaying. when i click on image it showing in console but not getting an idea how to display products in modal body. For to display in modal i used react-bootstrap. modal pop up is displaying when i click on image and it displaying header and footer. But in modal body i want to display the product details which i clicked. can any one help ..
import React, { Component } from "react";
import { Grid, Row, Col, Image, Button, Modal } from "react-bootstrap";
import AddToCartView from "./AddToCartView";
// import ProductView from './ProductView';
class ProductList extends Component {
constructor(props){
super(props);
this.state = {
show : false
}
}
handleShow = (item) => {
this.getProductDetails(item);
this.setState({
show : true
})
}
handleClose = () => {
this.setState({
show : false
})
}
getProductDetails = (prod) => {
// console.log(id,'clicked');
console.log(prod);
console.log(prod.title);
console.log(prod.id);
console.log(prod.price);
// let click = document.getElementsByTagName(Image.id);
// console.log(click);
// const { viewProducts } = this.props
// console.log(viewProducts);
// viewProducts.map((prod,id) => {
// console.log(prod.ptype);
// })
}
// console.log(viewProducts,'viewProducts');
render(){
const { viewProducts } = this.props;
return (
<div className="list-container">
<div className="mobile-list">
<h3> Showing { viewProducts.length } mobiles </h3>
</div>
<Grid>
<Row>
{viewProducts.map((item, key) => (
<Col xs={8} md={4} lg={4} key={item.id}>
<figure>
<Image onClick={() => this.handleShow(item) } src={item.image}
thumbnail />
<figcaption>{item.title}</figcaption>
<figcaption>
<label>Rs. </label>
{item.price}
</figcaption>
</figure>
<Button bsStyle="primary" onClick={this.props.onChange}>
<i className="fa fa-shopping-cart" />
Add
</Button>
<hr />
</Col>
))}
</Row>
</Grid>
<Modal show={this.state.show} onHide={() => this.handleClose()}>
<Modal.Header closeButton>
<Modal.Title>Product Details</Modal.Title>
</Modal.Header>
<Modal.Body>
{/* <ProductView displayProductView= { (item) =>
this.props.displayProductDetails(item) }/> */}
</Modal.Body>
<Modal.Footer>
<Button onClick={() => this.handleClose()}>Close</Button>
</Modal.Footer>
</Modal>
</div>
);
};
}
export default ProductList;

You are aware the ProductView component is commented out within the Modal Body right?

I'm not seeing where you pass the item to ProductView. Most likely your ProductView is getting nothing to display. Maybe you could change render of ProductView to just render a 'Hello' to see if that is the case.

Related

How to enable reactstrap collapse to show first dropdown active by default on first load

Here's a working code for the dropdown.. but I'm having trouble on enabling the first dropdown to be active on first load.. the first dropdown should be showing on initial load and then when user click on the other dropdown, the previous will collapse and the new one will open..
please help.. here's the reference sandbox link if needed
import * as React from "react";
import { Button, Card, CardBody, Collapse } from "reactstrap";
import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";
export default function App() {
const [state, setState] = React.useState({});
const { article, moreInfoOpen } = state;
const handleArticleOpen = (article) => {
setState((prevState) => ({
...prevState,
article
}));
};
return (
<div className="app">
<Card className="card">
<CardBody className="card-body">
<div className="section section-articles">
<div className="articles-buttons">
<Button
className="article2-button"
color="primary"
onClick={() => handleArticleOpen("2")}
>
<h3>Article 2</h3>
</Button>
<Button
className="article1-button"
color="primary"
onClick={() => handleArticleOpen("1")}
>
<h3>Article 1</h3>
</Button>
</div>
<Collapse isOpen={article === "2"}>
<Card className="card">
<CardBody className="card-body">
<div>Article 2</div>
</CardBody>
</Card>
</Collapse>
<Collapse isOpen={article === "1"}>
<Card className="card">
<CardBody className="card-body">
<div>Article 1</div>
</CardBody>
</Card>
</Collapse>
</div>
</CardBody>
</Card>
</div>
);
}
useEffect will do the work, set moreInfoOpen to true on load, and
call handleArticleOpen("2") if you want to open first option also
export default function App() {
...
//this
React.useEffect(() => {
setState((prevState) => ({
moreInfoOpen: true
}));
handleArticleOpen("2");
}, []);
return (
...
);
}

React Pass the value input in the other Pages

I have a homepage where they can click the modal button. after the button click the modal will show. then in the modal they will input a text and when they click submit the text they input should be display in the homepage. Currently the one i did is not displaying in homepage when click the submit button. Please help. Thank you
This is the code:
https://codesandbox.io/s/competent-rgb-lk4ws
Modal
In your Modal component you can create a event when the Submit button is clicked:
import React from "react";
import "./modal.css";
// Create new event: onSubmitClick
function Modal({ setOpenModal, onSubmitClick }) {
// It`s function get name value and pass to onSubmitClick
function getData() {
const nameValue = document.getElementById("name").value;
onSubmitClick(nameValue);
setOpenModal(false);
}
return (
<div className="modalBackground">
<div className="modalContainer">
<div className="titleCloseBtn">
<button
onClick={() => {
setOpenModal(false);
}}
>
X
</button>
</div>
<div className="title">Forms</div>
<div className="body">
<input id="name" placeholder="Enter Your Name" />
</div>
<div className="footer">
<button
onClick={() => {
setOpenModal(false);
}}
id="cancelBtn"
>
Cancel
</button>
{/* The onclick should be onClick */}
<button onClick={getData}>Submit</button>
</div>
</div>
</div>
);
}
export default Modal;
Home
In home page you can get the event and use the new name value
import React, { useState } from "react";
import Modal from "../../src/components/Modal/modal.js";
const Home = () => {
const [modalOpen, setModalOpen] = useState(false);
const [name, setName] = useState("");
function handleModalSubmitClick(nameValue) {
// Receive new value, and set in a state
setName(nameValue);
}
return (
<div class="hello">
<h1>Hey, click on the button to open the modal.</h1>
<span>name: {name}</span>
<button
onClick={() => {
setModalOpen(true);
}}
class="button is-pulled-right"
>
Button
</button>
{modalOpen && (
<Modal
setOpenModal={setModalOpen}
onSubmitClick={handleModalSubmitClick} // Bind a function to handle a event
/>
)}
</div>
);
};
export default Home;

Using state data as a props in other component conditionally

Here is my one component DISPLAY,
import React, { Component } from "react";
import ListGroup from "./listGroup";
class Display extends Component {
handleAllClick = (e) => {
e.preventDefault();
return (
<ListGroup
data={this.props.data}
onSubmitted={this.handleSubmit}
onClicked={this.handleAllCheck}
onChanged={this.handleChange}
onCheckChange={this.handleCheckChange}
onDeletion={this.handleDelete}
/>
);
};
handleCompleted = (e) => {
e.preventDefault();
return (
<ListGroup
data={this.props.data}
onSubmitted={this.handleSubmit}
onClicked={this.handleAllCheck}
onChanged={this.handleChange}
onCheckChange={this.handleCheckChange}
onDeletion={this.handleDelete}
/>
);
};
render() {
return (
<div>
<button
type="button"
className=" all btn btn-light p-1 mr-3"
onClick={this.handleAllClick}
>
All
</button>
<button
type="button"
className=" act btn btn-light p-1 mr-3"
onClick={this.handleActiveClick}
>
Active
</button>
<button
type="button"
className=" comp btn btn-light p-1"
onClick={this.handleCompleted}
>
Completed
</button>
</div>
);
}
}
export default Display;
Actually I want to use state which is named by data in the main component and that data contains a boolean variable called completed.
Now I wanted to conditionally use this completed as props with ListGroup component(Which I have imported above).
This should look like this:
handleCompleted = (e) => {
e.preventDefault();
(!this.props.completedItem &&
<ListGroup
data={this.props.data}
onSubmitted={this.handleSubmit}
onClicked={this.handleAllCheck}
onChanged={this.handleChange}
onCheckChange={this.handleCheckChange}
onDeletion={this.handleDelete}
/>
);
};
(I have passed this completed as completedItem in the main component).
But the problem is this is not working the right way!

onScroll when at the bottom of the div then disable button

Trying to achieve something similar to popular T&C's actions, when you scroll down to the very bottom of the div 'accept' button becomes enabled so you can click on it.
For this example, I am using material-UI components & button becomes disabled when I add 'disabled' within the component, that's all.
Here's the code:
import React from 'react';
import PropTypes from 'prop-types';
import Modal from '#material-ui/core/Modal';
import Button from '#material-ui/core/Button';
import './terms-popup.scss';
const handleScroll = (e) => {
const bottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
if (bottom) { console.log('bottom is reached'); }
};
const TermsPopup= ({
isModalOpen,
isOpen,
title,
closeLabel,
showCloseButton,
}) => {
return (
<Modal
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
open={isOpen}
onClose={() => isModalOpen(false)}
>
<div className="terms-container">
<div className="terms-header">
<h2>{title}</h2>
</div>
<div
className="terms-body"
onScroll={handleScroll}
>
<h3>Sample title</h3>
<p>Sample description would go here</p>
<div className="terms-footer">
{(showCloseButton) ? (
<Button
variant="contained"
type="button"
onClick={() => isModalOpen(false)}
>
{closeLabel}
</Button>
) : null}
</div>
</div>
</Modal>
);
};
TermsPopup.propTypes = {
isModalOpen: PropTypes.func.isRequired,
isOpen: PropTypes.bool.isRequired,
title: PropTypes.string.isRequired,
closeLabel: PropTypes.string,
showCloseButton: PropTypes.bool,
};
TermsPopup.defaultProps = {
closeLabel: 'accept',
showCloseButton: true,
};
export default TermsPopup;
And what I'd like to achieve is when the bottom is reached then Button should change to:
<Button
variant="contained"
type="button"
onClick={() => isModalOpen(false)}
disabled
/>
Move your onScroll event handler into the component itself, and use React state to update your component when the bottom is reached. You can use the state variable to then set the 'disabled' prop on your Button component.
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import Modal from '#material-ui/core/Modal';
import Button from '#material-ui/core/Button';
import './terms-popup.scss';
const TermsPopup= ({
isModalOpen,
isOpen,
title,
closeLabel,
showCloseButton,
}) => {
const [bottom, setBottom] = useState(false);
const handleScroll = (e) => {
const bottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
setBottom(bottom)
};
return (
<Modal
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
open={isOpen}
onClose={() => isModalOpen(false)}
>
<div className="terms-container">
<div className="terms-header">
<h2>{title}</h2>
</div>
<div
className="terms-body"
onScroll={handleScroll}
>
<h3>Sample title</h3>
<p>Sample description would go here</p>
<div className="terms-footer">
{(showCloseButton) ? (
<Button
variant="contained"
type="button"
onClick={() => isModalOpen(false)}
disabled={bottom}
>
{closeLabel}
</Button>
) : null}
</div>
</div>
</Modal>
);
};

I am trying to pass a value from one component with a click function to another

My app.js creates a widget layout, within it I have an handleWidgetSelection function which should take an id when an item is clicked in my modal component. When I console log in the handleWidgetSelection function I notice that the state is not updated and it remains null as I originally set it as. I am fairly new to react so any help would be great.
This is my app.js
class App extends Component {
constructor(props) {
super(props);
this.state={
selectedWidgetId: null, //initially set as null because no widget is selected
widgetOptions:[{name:"Data Table", comp:<DataTable/>},{name:"List", comp:<CheckboxList/>}],
widgets:[ //array for layout
{id:1, content: <DataTable/>},
{id:2, content: <CheckboxList/>},
{id:3, content: ""},
{id:4, content: ""}
],
isModalOpen: false
}
}
handleWidgetSelection=(id) => {
this.setState({selectedWidgetId: id})
console.log(this.state.selectedWidgetId); //trying to fix so this value does not always print null
}
.....
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
//I am passing my values to the AddWidgetDialog component here
<AddWidgetDialog handleWidgetSelection={this.handleWidgetSelection} widgets={this.state.widgetOptions} isModalOpen={this.state.isModalOpen} onRequestClose={this.onRequestClose} />
<Grid container spacing={24}>
{
this.state.widgets.map((widget,index)=>{
return(
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}><Swappable id={widget.id} content={widget.content} delete={this.deleteEvent.bind(this,index)} add={this.addEvent.bind(this,index)}/></Paper>
</Grid>
)
})
}
</Grid>
</div>
);
}
This is my AddWidgetDialog component
import React, { PropTypes } from 'react';
import Modal from 'react-modal';
const AddWidgetDialog = ({ handleWidgetSelection, widgets, isModalOpen, onRequestClose}) => {
const widgetItems = widgets.map((widget) => {
return (
<div className="list-group">
<a href="#" onClick={() => handleWidgetSelection(widget.name)} className="list-group-item">
<h6 className="list-group-item-heading">{widget.name}</h6>
</a>
</div>
);
});
return (
<Modal
className="Modal__Bootstrap modal-dialog"
isOpen={isModalOpen}>
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" onClick={onRequestClose}>
<span aria-hidden="true">×</span>
<span className="sr-only">Close</span>
</button>
<h4 className="modal-title">Add a widget</h4>
</div>
<div className="modal-body">
<h5>Pick a widget to add</h5>
{widgetItems}
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" onClick={onRequestClose}>Close</button>
</div>
</div>
</Modal>
);
};
export default AddWidgetDialog;
setState maybe asynchronous. See the docs Why is setState giving me the wrong value?
handleWidgetSelection=(id) => {
this.setState({selectedWidgetId: id})
console.log(this.state.selectedWidgetId); //no guarantee state is updated or not.
}
You should use console.log() in the callback as second argument to the setState
handleWidgetSelection=(id) => {
this.setState({selectedWidgetId: id},() => {
console.log(this.state.selectedWidgetId); //state is updated now.
})
}

Resources