How to map on react JS with button? - css

currently I'm trying to create a react app. I have 3 button and I want to show different information and image depending on the button chosen. It will only display the info of the chosen button for example, if user click de'spa it will only show information about id 1.
How can I map each of them with mapping in react? and one more question. Can I directly write the path for my img in the array ? if can't, how to do it ?
Here's the current code I have
import {Carousel, Container, Row, Col} from 'react-bootstrap'
import '../CSS/Facilities.css'
const facsInfo = [
{
Id: "1",
Title: "De'Spa",
Description: "",
upperleftimg:"./Images/photo1.png",
upperrightimg:"./Images/photo2.png",
},
{
Id: "2",
Title: "De'Resto",
Description: "",
upperleftimg:"./Images/photo3.png",
upperrightimg:"./Images/photo4.png",
},
]
const Facilities = () => {
return (
<>
<Container fluid>
<Row className="facsbuttwrapper text-center">
<Col sm={4} lg={4}>
<button className="facsButton">De'Spa</button>
</Col>
<Col sm={4} lg={4}>
<button className="facsButton">De'Resto</button>
</Col>
<Col sm={4} lg={4}>
<button className="facsButton">Meeting Room</button>
</Col>
</Row>
</Container>
<Container fluid>
<Row className="text-center">
<Col md={12} lg={12}>
{facsInfo.map((show) =>{
const {Title, Description, OpeningHours, Id} = show
return(
<div key={Id}>
<h1>{Title}</h1>
<h5>{Description}</h5>
</div>
)
})}
</Col>
</Row>
</Container>
<Container fluid>
<Row>
<Col md={12} lg={12}>
{facsInfo.map((show) =>{
const {upperleftimg, upperrightimg, Id} = show
return(
<div key={Id} className="FacilitiesImg">
<img src={upperleftimg} alt="Image 1"></img>
<img src={upperrightimg} alt="Image 2"></img>
</div>
)
})}
</Col>
</Row>
</Container>
</>
)
}
export default Facilities

You could use a state to do that
In your Facilities component:
const [id, setID] = useState('');
Then in your buttons:
<Row className="facsbuttwrapper text-center">
{facsInfo.map(fac => (
<Col sm={4} lg={4}>
<button className="facsButton" onClick={() => setId(fac.Id)}>
{fac.Title}
</button>
</Col>
))}
<Col sm={4} lg={4}>
<button className="facsButton">Meeting Room</button>
</Col>
</Row>;
To show correct image:
<Row>
<Col md={12} lg={12}>
{facsInfo.find(show => {
if (show.id === id) {
const { upperleftimg, upperrightimg, Id } = show;
return (
<div key={Id} className="FacilitiesImg">
<img src={upperleftimg} alt="Image 1"></img>
<img src={upperrightimg} alt="Image 2"></img>
</div>
);
}
})}
</Col>
</Row>;

Add onClick events on your buttons and pass the ID into the click handler.
Set a State with selected id.
Instead of using facsInfo.map, use facsInfo.find(f => f.id === selectedID) [selectedID being the state].

You need a state to save information.
filter facsInfo based on current information state
const [current, setCurrent] = React.useState(`De'Spa`)
const handleInfoChange = (evt) => {
setCurrent(evt.currentTarget.dataset.info)
}
const filteredFacsInfo = facsInfo.filter(x => x.Title === current)
return (
<Container fluid>
<Row className="facsbuttwrapper text-center">
<Col sm={4} lg={4}>
<button data-info="De'Spa" className="facsButton" onClick={handleInfoChange}>De'Spa</button>
</Col>
<Col sm={4} lg={4}>
<button data-info="De'Resto" className="facsButton" onClick={handleInfoChange}>De'Resto</button>
</Col>
<Col sm={4} lg={4}>
<button data-info="Meeting Room" className="facsButton" onClick={handleInfoChange}>Meeting Room</button>
</Col>
</Row>
</Container>
<Container fluid>
<Row className="text-center">
<Col md={12} lg={12}>
{filteredFacsInfo.map((show) => /* your render content about info */)}
</Col>
</Row>
</Container>
<Container fluid>
<Row className="text-center">
<Col md={12} lg={12}>
{filteredFacsInfo.map((show) => /* your render content about image */)}
</Col>
</Row>
</Container>
)

and one more question. Can I directly write the path for my img in the array ? if can't, how to do it ?
Yes, you can.
For achieving your aim, you need to define a state:
const [currentId, setCurrentId] = useState();
And a function which will filter facs:
const showSelectedFact = () => {
var fac = facsInfo.filter((x) => x.Id == currentId)[0];
const { Title, Description, OpeningHours, Id } = fac;
return (
<div key={Id}>
<h1>{Title}</h1>
<h5>{Description}</h5>
</div>
);
};
Here's the code:
import { Carousel, Container, Row, Col } from "react-bootstrap";
import { useEffect, useState } from "react";
// import '../CSS/Facilities.css'
const facsInfo = [
{
Id: "1",
Title: "De'Spa",
Description: "",
upperleftimg: "./Images/photo1.png",
upperrightimg: "./Images/photo2.png"
},
{
Id: "2",
Title: "De'Resto",
Description: "",
upperleftimg: "./Images/photo3.png",
upperrightimg: "./Images/photo4.png"
},
{
Id: "3",
Title: "Meeting Room",
Description: "",
upperleftimg: "./Images/photo3.png",
upperrightimg: "./Images/photo4.png"
}
];
const Facilities = () => {
const [currentId, setCurrentId] = useState();
useEffect(() => {
console.log(currentId);
}, [currentId]);
const showSelectedFact = () => {
var fac = facsInfo.filter((x) => x.Id == currentId)[0];
const { Title, Description, OpeningHours, Id } = fac;
return (
<div key={Id}>
<h1>{Title}</h1>
<h5>{Description}</h5>
</div>
);
};
return (
<>
<Container fluid>
<Row className="facsbuttwrapper text-center">
<Col sm={4} lg={4}>
<button
value="1"
className="facsButton"
onClick={(e) => setCurrentId(e.target.value)}
>
De'Spa
</button>
</Col>
<Col sm={4} lg={4}>
<button
value="2"
className="facsButton"
onClick={(e) => setCurrentId(e.target.value)}
>
De'Resto
</button>
</Col>
<Col sm={4} lg={4}>
<button
value="3"
className="facsButton"
onClick={(e) => setCurrentId(e.target.value)}
>
Meeting Room
</button>
</Col>
</Row>
</Container>
<Container fluid>
<Row className="text-center">
<Col md={12} lg={12}>
{showSelectedFact()}
</Col>
</Row>
</Container>
<Container fluid>
<Row>
<Col md={12} lg={12}>
{facsInfo.map((show) => {
const { upperleftimg, upperrightimg, Id } = show;
return (
<div key={Id} className="FacilitiesImg">
<img src={upperleftimg} alt="Image 1"></img>
<img src={upperrightimg} alt="Image 2"></img>
</div>
);
})}
</Col>
</Row>
</Container>
</>
);
};
export default function App() {
return <Facilities />;
}

Related

How to Resize Modal height and width in react-bootstrap?

I'm trying to use React Bootstrap Modal in my application but the dialog is too small, and I want to make it bigger. How can I achieve that ? I already finished the Code but i think the css doesn't work
Here's the code:
<Modal show={showModal} onHide={handleClose} className='modalSize'>
<Modal.Body >
<Row>
<Col lg={6}>
<img
className
src= {modalData.picture}
/>
</Col>
<Col lg={6}>
<h1>{modalData.name}</h1>
<h1>{modalData.position}</h1>
</Col>
</Row>
</Modal.Body>
</Modal>
CSS :
.modalSize{
width: 100% !important;
}
From the react-bootstrap docs: Size
You can add a parameter for the size of the modal just using size="lg" as below
function Example() {
const [smShow, setSmShow] = useState(false);
const [lgShow, setLgShow] = useState(false);
return (
<>
<Button onClick={() => setSmShow(true)} className="me-2">
Small modal
</Button>
<Button onClick={() => setLgShow(true)}>Large modal</Button>
<Modal
size="sm"
show={smShow}
onHide={() => setSmShow(false)}
aria-labelledby="example-modal-sizes-title-sm"
>
<Modal.Header closeButton>
<Modal.Title id="example-modal-sizes-title-sm">
Small Modal
</Modal.Title>
</Modal.Header>
<Modal.Body>...</Modal.Body>
</Modal>
<Modal
size="lg"
show={lgShow}
onHide={() => setLgShow(false)}
aria-labelledby="example-modal-sizes-title-lg"
>
<Modal.Header closeButton>
<Modal.Title id="example-modal-sizes-title-lg">
Large Modal
</Modal.Title>
</Modal.Header>
<Modal.Body>...</Modal.Body>
</Modal>
</>
);
}

How to display react-bootstrap card component side by side horizontally

Hi guys so I'm trying to create some e-commerce web app using react-bootstrap. I wanted to map my item by using Card component from bootstrap. I manage to display each of the card, but I can't make them displayed side by side horizontally. I want each row to have 4/5 items anyone know how I can accomplish it ? here's my code:
Product.js
<Row>
<Col lg={4}>
{productList && productList.map(product =>{
const {id, title, price, category,description,image} = product;
return(
<>
<Card key={id} className="productlist">
<Card.Img variant="top" src={"#"} />
<Card.Body>
<Card.Title>{title}</Card.Title>
<Card.Text>{description}</Card.Text>
<Card.Text>{category}</Card.Text>
<Card.Text>
{price}
</Card.Text>
<Button variant="primary">Add to cart</Button>
</Card.Body>
</Card>
</>
)
})}
</Col>
</Row>
You can do it simply using d-flex and flex fill react bootstrap class. It will also fulfill your need of equal height cards in a row.
Try below code may be its work as expected you want.
<Row lg={3}>
{productList &&
productList.map((product) => {
const { id, title, price, category, description, image } =
product;
return (
<Col className="d-flex">
<Card className="flex-fill" key={id} className="productlist">
<Card.Img variant="top" src={"#"} />
<Card.Body>
<Card.Title>{title}</Card.Title>
<Card.Text>{description}</Card.Text>
<Card.Text>{category}</Card.Text>
<Card.Text>{price}</Card.Text>
<Button variant="primary">Add to cart</Button>
</Card.Body>
</Card>
</Col>
);
})}
</Row>
<Row>
{productList &&
productList.map((product) => {
const { id, title, price, category, description, image } =
product;
return (
<Col className="col-6">
<Card key={id} className="productlist">
<Card.Img variant="top" src={"#"} />
<Card.Body>
<Card.Title>{title}</Card.Title>
<Card.Text>{description}</Card.Text>
<Card.Text>{category}</Card.Text>
<Card.Text>{price}</Card.Text>
<Button variant="primary">Add to cart</Button>
</Card.Body>
</Card>
</Col>
);
})}
</Row>

How to align react Boostrap cards

I have cards with different images and texts that make them bigger/smaller, I couldn't find any React-Bootstrap specific answer, but every css and normal Bootstrap alternative that i tried didn't work. The only thing that put a patch in the problem is setting a max height in the cards, but still the cards that have a larger image or text have their image higher or lower and is really bad for rows that have some medium sized images and one larger one. For example:
I tried adapting the top three answers of this answer: Link and it didn't work, for example using d-flex align-items-stretch
import React from "react";
import Product from "./product";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
const Flexbox = (props) => {
return (
<Container>
<Row>
<Col className="d-flex align-items-stretch">
<Product product={props.productList[0]}></Product>
</Col>
<Col className="d-flex align-items-stretch">
<Product product={props.productList[1]}></Product>
</Col>
<Col className="d-flex align-items-stretch">
<Product product={props.productList[2]}></Product>
</Col>
</Row>
</Container>
);
};
export default Flexbox;
The result is every card having their own size.
Using h-100 nothing changes, container code:
import React from "react";
import Product from "./product";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
const Flexbox = (props) => {
return (
<Container fluid className="content-row">
<Row>
<Col>
<Product product={props.productList[0]}></Product>
</Col>
<Col>
<Product product={props.productList[1]}></Product>
</Col>
<Col>
<Product product={props.productList[2]}></Product>
</Col>
</Row>
</Container>
);
};
export default Flexbox;
Card code:
import React from "react";
import "../App.css";
import "../stylesheets/product.css";
import Rating from "./rating";
import Card from "react-bootstrap/Card";
const Product = (props) => {
console.log(props.product);
return (
<div>
<Card className="card rounded shadow-sm border-0 h-100">
<Card.Body className="card-body p-4">
<img src={props.product.img} class="img-fluid d-block mx-auto mb-3" />
</Card.Body>
<Card.Footer>
<h5>{props.product.name}</h5>
<Rating></Rating>
</Card.Footer>
</Card>
</div>
);
};
export default Product;
And using d.flex and flex-fill also nothing changes, container:
import React from "react";
import Product from "./product";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
const Flexbox = (props) => {
return (
<Container fluid>
<Row>
<Col className="col-sm d-flex">
<Product product={props.productList[0]}></Product>
</Col>
<Col className="col-sm d-flex">
<Product product={props.productList[1]}></Product>
</Col>
<Col className="col-sm d-flex">
<Product product={props.productList[2]}></Product>
</Col>
</Row>
</Container>
);
};
export default Flexbox;
Card:
import React from "react";
import "../App.css";
import "../stylesheets/product.css";
import Rating from "./rating";
import Card from "react-bootstrap/Card";
const Product = (props) => {
console.log(props.product);
return (
<div>
<Card className="card rounded shadow-sm border-0">
<Card.Body className="p-4 flex-fill">
<img src={props.product.img} class="img-fluid d-block mx-auto mb-3" />
</Card.Body>
<Card.Footer>
<h5>{props.product.name}</h5>
<Rating></Rating>
</Card.Footer>
</Card>
</div>
);
};
export default Product;
I'm losing my mind and i don't know what to do, i tried everything and nothing changes.
I think if you remove the div around the card and add back h-100 as a class it should align:
const Product = (props) => {
console.log(props.product);
return (
<Card className="card rounded shadow-sm border-0 h-100">
<Card.Body className="p-4 flex-fill">
<img src={props.product.img} class="img-fluid d-block mx-auto mb-3" />
</Card.Body>
<Card.Footer>
<h5>{props.product.name}</h5>
<Rating></Rating>
</Card.Footer>
</Card>
);
};
export default Product;

.flex-grow-1 on react-bootstrap <Row> not filling vertical space

I'm struggling to get .flex-grow-1 in Bootstrap 4.6.0 (with react-bootstrap 1.5.2) to get a component on my layout to expand to fill the remaining vertical space available.
"bootstrap": "^4.6",
"react-bootstrap": "1.5.2",
The following code produces a wireframe of the screen layout that I am trying to build.
import React, { Component } from "react";
import { Col, Row } from "react-bootstrap";
import './SingleSignIn.scss'
class SignUpLayout extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
const { country } = this.state;
return (
<Row>
<Col id="left-column" className="grid bg-warning" style={{height: "100vw"}}>
<Row className="grid flex-nowrap">
<Col className="grid">
{/* left margin */}
</Col>
<Col className="grid" xs={6} sm={6} md={6} lg={6} xl={6}>
<Row className="grid" style={{height: "80px"}}>
Welcome To:
</Row>
<Row className="grid" style={{height: "125px"}}>
logo goes here
</Row>
</Col>
<Col className="grid">
{/* right margin */}
</Col>
</Row>
<Row id="body" className="grid bg-danger flex-grow-1 flex-nowrap">
<Col className="grid">
{/* body left margin */}
</Col>
<Col className="grid" xs={10} sm={10} md={8} lg={8} xl={8}>
<Row className="grid" style={{height: "10%"}}>
e-mail input
</Row>
<Row className="grid" style={{height: "10%"}}>
company name input
</Row>
<Row className="grid" style={{height: "10%"}}>
country input
</Row>
<Row className="grid" style={{height: "10%"}}>
phone number
</Row>
<Row className="grid" style={{height: "10%"}}>
get started button
</Row>
</Col>
<Col className="grid">
{/* body right margin */}
</Col>
</Row>
</Col>
<Col id="right-column" className="grid" style={{height: "100vw"}}>
Right Column
</Col>
</Row>
)
}
}
export default SignUpLayout;
My intention is to get the component identified as #body to grow vertically to fill the remaining vertical space available on the viewport. I'm using the .flex-grow-1 class to try to accomplish this based on other similar posts that I came across in my search but it's not having the desired effect.
The resulting wireframe layout that I get from the above code is the following:
Thanks in advance for the pointers.

Reactjs boostrap grid

I am learning React and I have some trouble with using the bootstrap grid/reactstrap. Somehow when I use the grid system, instead of aligning horizontal columns, I got a vertical one.
Film.js
import React from "react";
import logo from "./ghibli.png";
import { Container, Row, Col } from "reactstrap";
import { Card, CardImg, CardText, CardBody,
CardTitle, CardSubtitle, Button } from 'reactstrap';
const Films = props => (
<Container>
<Row>
<Col md= "3">
<Card>
<CardImg top width="100%" src={logo} alt="Card image cap" />
<CardBody>
<CardTitle>{props.title}</CardTitle>
<CardSubtitle>{props.director}</CardSubtitle>
<CardText>{props.description}</CardText>
<Button>Button</Button>
</CardBody>
</Card>
</Col>
</Row>
</Container>
);
export default Films;
Currently, you only have one column (col) in a row.
As soon as you add more than column into a row, they'll start showing up side by side i.e. horizontally.
I have no clue about reactjs but I suspect that the following code will probably do the trick and produce 2 columns in a row:
const Films = props => (
<Container>
<Row>
<Col md= "3">
<Card>
<CardImg top width="100%" src={logo} alt="Card image cap" />
<CardBody>
<CardTitle>{props.title}</CardTitle>
<CardSubtitle>{props.director}</CardSubtitle>
<CardText>{props.description}</CardText>
<Button>Button</Button>
</CardBody>
</Card>
</Col>
<Col md= "3">
<Card>
<CardImg top width="100%" src={logo} alt="Card image cap" />
<CardBody>
<CardTitle>{props.title}</CardTitle>
<CardSubtitle>{props.director}</CardSubtitle>
<CardText>{props.description}</CardText>
<Button>Button</Button>
</CardBody>
</Card>
</Col>
</Row>
</Container>
);

Resources