This is my movie list component. I tried different attributes in the div section to get the cards in a row. But all the cards are aligned in a column.should i use either flex or grid.If yes how can i use them. Even i referred to many resources for this.But didn't worked for me. What should I do to get the cards as I wish . Please assist me.
import React, { useState } from 'react'
import { useSelector } from 'react-redux'
import MovieCard from './MovieCard'
const MoviesList = (props) => {
const [search, setSearch] = useState('')
const [filterBy, setFilterBy] = useState([])
const [orderBy, setOrderBy] = useState('')
const movies = useSelector((state) => {
console.log(state.movies)
return state.movies
})
const handleChange = (e) => {
const inputValue = e.target.value
setSearch(inputValue)
const filteredValue = movies.filter((movie) => {
return movie.Title.toLowerCase().includes(inputValue)
})
setFilterBy(filteredValue)
console.log(filteredValue)
}
const handleSelectChange = (e) => {
setOrderBy(e.target.value)
}
const show = (movies) => {
switch (orderBy) {
case 'a-z': return [...movies.sort((a, b) => a.Title.localeCompare(b.Title))]
case 'z-a': return [...movies.sort((a, b) => b.Title.localeCompare(a.Title))]
case '1-100': return [...movies.sort((a, b) => a.imdbRating - b.imdbRating)]
case '100-1': return [...movies.sort((a, b) => b.imdbRating - a.imdbRating)]
default: return [...movies]
}
}
return (
<div className='container'>
<div className='d-flex mb-3 '>
<h1 style={{ textAlign: 'center', border: 'solid lightgreen', backgroundColor: 'white' }} >My Movie List</h1>
<form style={{ float: 'right', marginRight: '35px' }}>
<input type="text" placeholder='search by name' value={search} onChange={handleChange} />
<select value={orderBy} onChange={handleSelectChange} >
<option value="">orderBy</option>
<option value="a-z">a-z</option>
<option value="z-a">z-a</option>
<option value="1-100">1-100</option>
<option value="100-1">100-1</option>
</select>
</form>
</div>
<div className=" row pt-2 justify-content-around " style={{ textAlign: 'center', width: '100%' }}>
{
filterBy.length > 0 ? (
filterBy.map((movie) => {
return <MovieCard key={movie.imdbID} Poster={movie.Poster} Title={movie.Title} imdbRating={movie.imdbRating} imdbID={movie.imdbID} />
})
) : (
show(movies).map((movie) => {
return <MovieCard key={movie.imdbID} {...movie} />
})
)
}
</div>
</div >
)
}
export default MoviesList
And this is Movie card component
import React from 'react'
import { useDispatch } from 'react-redux'
import { removeMovie } from '../actions/moviesAction'
const MovieCard = (props) => {
console.log(props)
const { Title, Poster, imdbRating, imdbID } = props
const dispatch = useDispatch()
return (
<div className="card mt-2 p-2 bd-highlight border shadow rounded" style={{ width: '16rem' }}>
<img className="card-img-left pt-2" src={Poster} alt={Title} style={{ width: '200px', height: '200px' }} />
<div className="card-body">
<h4 className="card-title">Name : {Title}</h4>
<h5 className="card-title">Ranking : #{imdbRating}</h5>
<ion-icon name="trash" style={{ color: 'red' }} onClick={() => {
dispatch(removeMovie(imdbID))
}}>
</ion-icon>
</div>
</div>
)}
export default MovieCard
Please help me to resolve this. Thankyou
CodePudding user response:
Try providing display: flex
, to the div
rendering MovieCard
, like this:
<div className=" row pt-2 justify-content-around "
style={{ textAlign: 'center', width: '100%', display: 'flex' }}>
{
filterBy.length > 0 ? (
filterBy.map((movie) => {
return <MovieCard key={movie.imdbID} Poster={movie.Poster} Title={movie.Title} imdbRating={movie.imdbRating} imdbID={movie.imdbID} />
})
) : (
show(movies).map((movie) => {
return <MovieCard key={movie.imdbID} {...movie} />
})
)
}
</div>
CodePudding user response:
You can just use flex
here.
add the below code to your parent div (div containing all the cards).
If you have a css file add a class to that div and add the following styles.
display: flex;
flex-wrap: wrap;
justify-content: center;
or if you want to use inline styling do the following:
<div className=" row pt-2 justify-content-around " style={{ textAlign: 'center', width: '100%', display: "flex", flexWrap: "wrap", justifyContent: "center" }}>
{filterBy.length > 0 ? (
filterBy.map((movie) => {
return <MovieCard key={movie.imdbID} Poster={movie.Poster} Title={movie.Title} imdbRating={movie.imdbRating} imdbID={movie.imdbID} />
})
) : (
show(movies).map((movie) => {
return <MovieCard key={movie.imdbID} {...movie} />
}
)
)}
</div>
CodePudding user response:
Try using a grid method something like the code below will allow you control the number of rows and columns you want as well as size them.
**
<h1>Example { grid-template-rows: 40% 50% 50px;}</h1>
<p><strong style="color: red">The shorthand property, grid-template, can replace both </strong>grid-template-rows and grid-template-columns.</p>
<hr>
<p style="font-family: Courier">When using grid-template, the values before the slash will determine the size of each row. The values after the slash determine the size of each column. </p><hr>
<p style="font-family: Courier">In this example there are 3 rows and 3 columns added to the grid.</p><h1>Example {grid-template: 40% 50% 50px/100px 50% 200px;}</h1><br>
<p><strong style="color: red">By using the (fr) unit, we can define the size of columns and rows as a fraction of the grid’s length and width.</strong><br>Using (fr) makes it easier to prevent grid items from overflowing the boundaries of the grid.</p>
<h1>Example {grid-template: 1fr 1fr 1fr / 3fr 50% 1fr;}<br> width: 400px;<br>
**
CodePudding user response:
If you're using Bootstrap then you don't need to use flex
nor grid
directly. This is the Bootstrap's way to achieve the desired layout:
<div className="row">
{movies.map(item => (
<div className="col">
// then here yo can put your card for the movie
</div>
))}
</div>