I am learning react I want to show movie data when clicking on particular div. currently, I called fancy box which is not right method to get the result
So I need help to show movie data once click on particular div.
class App extends React.Component {
constructor() {
super();
this.state = {
data: [],
search: '',
};
}
updateSearch(event) {
this.setState({search: event.target.value.substr(0, 20)});
}
componentDidMount() {
fetch('http://www.omdbapi.com/?apikey=MyKey&s=fast&plot=full')
.then((Response) => Response.json())
.then((findresponse) => {
console.log(findresponse);
this.setState({
data: findresponse.Search,
});
});
}
render() {
let filteredMovie = this.state.data.filter((dynamicData) => {
return dynamicData.Title.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1;
});
return (
<div className="container movies_list">
<div className="row">
<div className="col-md-12 p-4">
<form>
<input
type="text"
className="form-control"
placeholder="Search"
value={this.state.search}
onChange={this.updateSearch.bind(this)}
/>
</form>
</div>
{filteredMovie &&
filteredMovie.map((dynamicData, key) => (
<div className="col-md-3 mb-3" key={key}>
<div className="card">
<img src={dynamicData.Poster} className="card-img-top" alt="..." />
<div className="card-body">
<h6 className="card-title">{dynamicData.Title} </h6>
<h6 className="card-title">Year: {dynamicData.Year} </h6>
<p className="card-text">{dynamicData.Plot} </p>
<a
data-fancybox
data-src="#hidden-content"
href="javascript:;"
className="btn btn-info"
>
View
</a>
<div id="hidden-content">
<img src={dynamicData.Poster} className="card-img-top" alt="..." />
<h2>{dynamicData.Title}</h2>
<p>{dynamicData.Year}</p>
</div>
</div>
</div>
</div>
))}
</div>
</div>
);
}
}
I highly recommend Reakit for modal & popovers.
Related
I implemented a Card component and basically generating a bunch of cards on some input data. I binded a setter function on button click on every card which basically expands and collapse it. Even after putting unique keys to the div is sort of triggering all the cards to open at once.
Here is the code piece:
import React, { useState } from 'react';
import PrettyPrintJson from './PrettyPrintJson';
import './Card.scss';
import '../App.scss';
const Card = (props) => {
const { data } = props;
const [collapse, toggleCollapse] = useState(true);
return (<div className="card-group">
{data.map((obj, idx)=>{
return <div className="card" key={`${idx}_${obj?.lastModifiedOn}`}>
<div className="card-header">
<h4 className="card-title">{`fId: ${obj?.fId}`}</h4>
<h6 className="card-title">{`name: ${obj?.name}`}</h6>
<h6 className="card-title">{`status: ${obj?.status}`}</h6>
<div className="heading-elements">
<button className="btn btn-primary" onClick={() => toggleCollapse(!collapse)}>Show Json</button>
</div>
</div>
<div className={`card-content ${!collapse ? 'collapse show' : 'collapsing'}`}>
<div className="card-body">
<div className="row">
<PrettyPrintJson data={ obj } />
</div>
</div>
</div>
</div>
})}
</div>
);
}
export default Card;
Create a component that manages it's own state and render that component.
const CardItem = ({ obj }) => {
const [collapse, toggleCollapse] = useState(true);
return (<div className="card">
<div className="card-header">
<h4 className="card-title">{`fId: ${obj?.fId}`}</h4>
<h6 className="card-title">{`name: ${obj?.name}`}</h6>
<h6 className="card-title">{`status: ${obj?.status}`}</h6>
<div className="heading-elements">
<button className="btn btn-primary" onClick={() => toggleCollapse(!collapse)}>Show Json</button>
</div>
</div>
<div className={`card-content ${!collapse ? 'collapse show' : 'collapsing'}`}>
<div className="card-body">
<div className="row">
<PrettyPrintJson data={ obj } />
</div>
</div>
</div>
</div>)
}
then render it like
{data.map((obj, idx)=> (<CardItem obj={obj} key={idx} />))}
I think you can declare a state which is a type of int. After then, you can use the if-statement of index(idx) and state.
Like this:
const [collapsedCardNumbers, toggleCollapseCard] = useState([]);
const addCardNumber = (idx, prevState) => {
const arr_cardNum = prevState
!arr_cardNum .includes(idx) && arr_cardNum .push(idx)
return arr_cardNum
}
...
{data.map((obj, idx)=>{
return <div className="card" key={`${idx}_${obj?.lastModifiedOn}`}>
<div className="card-header">
<h4 className="card-title">{`fId: ${obj?.fId}`}</h4>
<h6 className="card-title">{`name: ${obj?.name}`}</h6>
<h6 className="card-title">{`status: ${obj?.status}`}</h6>
<div className="heading-elements">
<button className="btn btn-primary" onClick={() => toggleCollapseCard(prevState => addCardNumber(idx, prevState))}>Show Json</button>
</div>
</div>
<div className={`card-content ${collapsedCardNumbers.includes(idx) ? 'collapse show' : 'collapsing'}`}>
<div className="card-body">
<div className="row">
<PrettyPrintJson data={ obj } />
</div>
</div>
</div>
</div>
})}
I am displaying two divisions corresponding, to two button's onClick event:
class Home extends React.Component {
constructor() {
super();
this.state = {
isShowaMale: false
};
this.toggleShowMale = this.toggleShowMale.bind(this);
}
toggleShowMale(show) {
this.setState({ isShowaMale:show });
}
render() {
const { isShowaMale } = this.state;
return (
<div className="container py-5">
<div className="row">
<button className="btn col-6 bg-transparent col-12 col-sm-6" onClick={() => this.toggleShowMale(true)} >
<img className="humanbody profile" src={malebody} />
</button>
<button className="btn col-6 bg-transparent col-12 col-sm-6" onClick={() => this.toggleShowMale(false)} >
<img className="humanbody profile" src={femalebody} alt="" />
</button>
</div>
{/* Hidden div */}
<div className="row mx-auto">
{isShowaMale && (
<div className="mx-auto">
Hey man!
</div>
)}
{!isShowaMale && (
<div>
Hey woman!
</div>
)}
</div>
{/* Hidden div */}
</div>
)
}
}
export default Home;
But, can I just display one div and change just the word man and woman in the text Hey ____? And there is also a problem that, after reloading the web page, it always shows Hey woman due to isShowaMale: false being default state. How can I solve these?
Can I just display one div and change just the word man and woman in
the text Hey ____
<div className="row">
{`Hey ${isShowMan? " man" : "woman"}!`}
</div>
And there is also a problem that, after reloading the web page, it always shows Hey woman due to isShowaMale: false being the default
state.
You can think about localStorage
Due to Why are we disallowed to use HTML5 local storage on code snippets?
So you can test the live demo
constructor() {
super();
const isShow = window.localStorage.getItem("data");
this.state = { isShowMan: isShow === "false" || !isShow ? false : true };
}
toggleShowMan(isShow) {
window.localStorage.setItem("data", isShow);
this.setState({ isShowMan: isShow });
}
class Home extends React.Component {
constructor() {
super();
this.state = { isShowMan: true };
}
toggleShowMan(isShow) {
this.setState({ isShowMan: isShow });
}
render() {
const { isShowMan } = this.state;
return (
<div className="container py-5">
<div className="row">
<button
disabled={isShowMan}
className="btn col-6 bg-transparent col-12 col-sm-6"
onClick={() => this.toggleShowMan(true)}
>
malebody{" "}
</button>
<button
disabled={!isShowMan}
className="btn col-6 bg-transparent col-12 col-sm-6"
onClick={() => this.toggleShowMan(false)}
>
femalebody
</button>
</div>
<div className="row">
{`Hey ${isShowMan? " man" : "woman"}!`}
</div>
</div>
);
}
}
ReactDOM.render(<Home />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
[UPDATE] following further clarification in the comments, the issue can be handles in a way similar to this:
class Home extends React.Component {
constructor() {
super();
this.state = {
isShowaMale: false
};
this.toggleShowMale = this.toggleShowMale.bind(this);
}
toggleShowMale(show) {
this.setState({ isShowaMale:show });
}
render() {
const formProps = this.state.isShowMale
? { title: 'Mr', name: 'John', surname: 'Doe' }
: { title: 'Ms', name: 'Jane', surname: 'Doe' };
return (
<div className="container py-5">
<div className="row">
<button className="btn col-6 bg-transparent col-12 col-sm-6" onClick={()=> this.toggleShowMale(true)} >
<img className="humanbody profile" src={malebody} />
</button>
<button className="btn col-6 bg-transparent col-12 col-sm-6" onClick={()=> this.toggleShowMale(false)} >
<img className="humanbody profile" src={femalebody} alt="" />
</button>
</div>
{/* Hidden div */}
<div className="row mx-auto">
<div className="mx-auto">
<form>
<input type="text" id="title" name="title" placeholder={formProps.title} />
<input type="text" id="name" name="name" placeholder={formProps.title} />
<input type="text" id="surname" name="surname" placeholder={formProps.title} />
</form>
</div>
</div>
{/* Hidden div */}
</div>
)
}
}
export default Home;
Or the entire form can be placed into a separate function (or even a separate component).
[ORIGINAL ANSWER]
You simply replace
{/* Hidden div */}
<div className="row mx-auto">
{isShowaMale && (
<div className="mx-auto">
Hey man!
</div>
)}
{!isShowaMale && (
<div>
Hey woman!
</div>
)}
</div>
{/* Hidden div */}
with
{/* Hidden div */}
<div className="row mx-auto">
<div className="mx-auto">
Hey {isShowaMale ? 'man' : 'woman'}!
</div>
</div>
{/* Hidden div */}
I would like to build a simple chart in React using Nivo library to represent percentage values from data in API response.
The data from the response looks like this: https://run.mocky.io/v3/7c46c4ce-09c0-4f95-b4e1-84ae10bd24ab
I need to represent this data in a really simple line chart.
So far I have this code in my component:
import React, {useState, useEffect} from 'react';
import axios from 'axios';
import {useParams} from 'react-router-dom';
import Loader from '../Components/Loader';
import { Bar } from "#nivo/bar";
function ArtistDetail() {
const {artist_uuid} = useParams()
const url = `https://run.mocky.io/v3/${artist_uuid}`;
const [artist, setArtist] = useState({
loading: false,
data: null,
error: false
})
let content = null;
useEffect(() => {
setArtist({
loading: true,
data: null,
error: false
})
axios.get(url)
.then(response => {
setArtist({
loading: false,
data: response.data,
error: false
})
})
.catch(() => {
setArtist({
loading: false,
data: null,
error: true
})
})
}, [url])
if(artist.error) {
content = <p>There was an error loading an artist.</p>
}
if(artist.loading) {
content = <p><Loader/></p>
}
if(artist.data) {
content =
<main className="main">
<section className="section section-artist-detail trending claimed">
<div className="page">
<div className="col visual">
<figure>
<img src= {artist.data.data.image}/>
<figcaption>
<button className="btn btn-claim-music-id">Claim music_id</button>
</figcaption>
</figure>
</div>
<div className="col-wrapper">
<div className="col info">
<div className="col-content">
<div className="info-wrapper">
<div className="title-wrapper">
<button className="btn btn-solid border btn-booking-request">Booking Request</button>
<h1 className="title">
{artist.data.data.name}
<div className="tooltip-wrapper">
<span className="profile-claimed">Profile claimed</span>
<div className="tooltip">
<h3>Vote for subgenres</h3>
<p>Don’t agree with the subgenres? Add the ones you think are missing or vote for existing to get yours on top!</p>
<div className="stats-sheet">
{artist.data.data.subgenres.map(subgenre => {
const {name, score} = subgenre;
return (
<div className="row" key={name, score}>
<h5>{name}</h5>
<div className="graph-line">
<span className="line" style= {{width: score + '%'}}>{score}%</span>
</div>
</div>
);
})}
</div>
<p>
<button className="btn btn-shadow">Vote now</button>
</p>
</div>
</div>
<span className="trending-icon">Trending</span>
</h1>
</div>
<div className="row">
<button className="btn btn-save long">Follow</button>
<button className="btn btn-share">
Share
<span>Link copied to clipboard</span>
</button>
</div>
<div className="row">
<label>Origin</label>
<a className="btn btn-filter-tag">{artist.data.data.country.name}</a>
</div>
<div className="row">
<label>Genre</label>
<span className="btn btn-filter-tag">{artist.data.data.genre.name}</span>
</div>
<div className="row">
<label>Subgenres</label>
{artist.data.data.subgenres.map(subgenre => {
const {name} = subgenre;
return (
<span key={name} className="btn btn-filter-tag">{name}</span>
);
})}
<div className="tooltip-wrapper">
<button className="btn btn-add">Add subgenre</button>
<div className="tooltip">
<h3>Vote for subgenres</h3>
<p>Don’t agree with the subgenres? Add the ones you think are missing or vote for existing to get yours on top!</p>
<div className="stats-sheet">
{artist.data.data.subgenres.map(subgenre => {
const {name, score} = subgenre;
return (
<div className="row" key={name, score}>
<h5>{name}</h5>
<div className="graph-line">
<span className="line" style= {{width: score + '%'}}>{score}%</span>
</div>
</div>
);
})}
</div>
<p>
<button className="btn btn-shadow">Vote now</button>
</p>
</div>
</div>
</div>
</div>
<div className="footer-detail">
<ul className="social-list">
{artist.data.data.social_links.map(item => {
const {channel, link} = item;
return (
<li key={channel, link}>
<a href= {link} className= {`btn social-icon ${channel}`}>{channel}</a>
</li>
);
})}
</ul>
<div className="tooltip-wrapper">
<button className="btn btn-add">Add links</button>
<div className="tooltip">
<h3>Got more info?</h3>
<p>Add Place's links so everyone can see their social media highlights.</p>
<p>
<button className="btn btn-shadow">Add links</button>
</p>
</div>
</div>
</div>
</div>
</div>
<div className="col stats">
<div className="col-content">
<Bar
width={600}
height={400}
margin={{ top: 60, right: 80, bottom: 60, left: 80 }}
data={artist.data.data.popularity}
indexBy="city"
keys={["percentage"]}
labelTextColor="inherit:darker(1.4)"
enableGridX={false}
layout="horizontal"
maxValue={10}
axisTop={null}
axisRight={null}
axisBottom={null}
axisLeft={null}
enableGridX={false}
enableGridY={false}
isInteractive={false}
/>
<div className="stats-sheet">
<label>Most popular in</label>
{artist.data.data.popularity.map(popular => {
const {city} = popular;
return (
<div className="row" key={city}>
<h5>{city}</h5>
<div className="graph-line">
<span className="line" style={{width: 47 + '%'}}>47%</span>
</div>
</div>
);
})}
</div>
</div>
</div>
</div>
<button className="btn btn-scroll-down">Scroll down</button>
</div>
</section>
</main>
}
return (
<div>
{content}
</div>
)
}
export default ArtistDetail;
I have no idea how to display the percentage data inside this div:
<div className="graph-line">
<span className="line" style={{ width: 47 + "%" }}>
47%
</span>
</div>;
It looks like this
For the chart I used the code from here
Good work!
Based on Nivo documentation, I'd try with this
<ResponsiveBar
data={data.popularity}
keys={[ 'city', 'percentage' ]}
maxValue={100}
...
>
..setting maxValue in or to 100 for percentages. Passing data.popularity or artist.data.data.popularity to data attribute and setting up appropriate keys.
{artist.data.data.popularity.map(popular => {
const {city} = popular;
Here might be the problem - destructure both 'city' and 'percentage' from 'popular'.
const { city, percentage } = popular
then
<span>{percentage}%</span>
Looking at the design instead of Nivo you can actually use simple css .Below is the code in which I have used flex to achieve that.
CodeSandbox Link
<div className="App">
<h1>Most Popular in</h1>
{popularity.map((popular) => (
<div>
<div>{popular.city}</div>
<div className="linear-graph">
<div
style={{
background: "black",
flex: popular.percentage
}}
/>
<div
style={{
background: "#c5c5c56b",
flex: 10 - popular.percentage
}}
/>
</div>
</div>
))}
</div>
and the css for that
.App {
font-family: sans-serif;
color: black;
}
.linear-graph {
width: 200px;
display: flex;
position: relative;
height: 6px;
margin-bottom: 10px;
}
Cheers
I have to render a component from an .json file, until then okay, to be able to read and pass the api values to my component ('RecipeItem'). The problem lies in the part of rendering, because the correct one would be the components being in 5 columns instead of only one.
enter image description here
updated codes below !!!
File RecipeItem.js
const RecipeList = ({ searchString }) => {
return(
<div>
{console.log('to aqui')}
<img className="card-img-top img-fluid" src={searchString.thumbnail} alt={searchString.title} />
<div className="card-body">
<h5 className="card-title">{searchString.title}</h5>
<p className="card-text">
<strong>Ingredients: </strong>{searchString.ingredients}
</p>
</div>
</div>
)
}
const RecipeItem = (props) => {
return (
<div className="col-sm-3 mt-4">
<div className="card">
{props.list && props.list.map((searchString, index) =>
<RecipeList searchString={searchString} key={index} />
)}
</div>
</div>
)
}
File App.js
class App extends Component {
constructor(props) {
super(props);
this.state = {
searchString: []
};
}
componentDidMount() {
this.setState({ searchString : data.results })
}
render() {
return (
<div className="App">
<Navbar />
<div className="container mt-10">
<div className="row">
<RecipeItem list={this.state.searchString}/>
</div>
</div>
</div>
);
}
}
Is this working ?
class App extends Component {
render() {
return (
<div className="App">
<Navbar />
<div className="container mt-10">
<div className="row">
{RecipesData.results.map(recipe =>
<RecipeItem
title={recipe.title}
ingredients={recipe.ingredients}
source={recipe.href}
thumbnail={recipe.thumbnail} />
)}
</div>
</div>
</div>
);
}
}
I am learning reactjs by creating a movie listing app. I have created a movie list using reactjs, react-mdl. I could not use infinite scrolling feature. For example at first, 3 movies are shown on the list and when user scrolls down more 3 movies list should be shown but before showing further 3 movies in list a loader icon should be shown. How can i show such on this scenario of code? I know i have to define the state isLoading and isLoadingMore. If the state of isLoading is false loader should be hidden else a loader should be shown.
App.js
class App extends Component {
constructor(props){
super(props);
this.state = {
movie:[
{
title:'The Flash',
id:1,
imageUrl:'http://cdn3-www.superherohype.com/assets/uploads/gallery/the-flash-2x15/12771634_1000420230050280_1499915054664837033_o.jpg',
rottenTomatoes:'85%'
},
{
title:'Silicon Valley',
id:2,
imageUrl:'https://www.wired.com/wp-content/uploads/2016/03/silicon_valley_opener4.jpg',
rottenTomatoes:'90%'
},
{
title:'Scorpion',
id:3,
imageUrl:'http://cdn-uploads.gameblog.fr/images/blogs/36115/202746.jpg',
rottenTomatoes:'80%'
},
],
isLoading:true,
isLoadingMore:false
}
}
showLoaderIcon(){
this.setState({
isLoading:true
});
}
hideLoaderIcon(){
this.setState({
isLoading:false
});
}
render() {
return (
<div className="App">
<div className="demo-big-content">
<Layout fixedHeader>
<Header>
<HeaderRow title="Find TV Shows">
</HeaderRow>
<HeaderRow>
<div className="search">
<span className="material-icons search-icon">search</span>
<input type="text" className="form-control" placeholder="Name of show(e.g Friends)" />
</div>
</HeaderRow>
</Header>
<Drawer title="Title">
</Drawer>
<Content>
<div className="page-content" />
<MovieList movies={this.state.movie} />
</Content>
</Layout>
</div>
</div>
);
}
}
export default App;
MovieListItem.js
const MovieListItem = ({movie}) => {
const imageUrl = movie.imageUrl;
const mainCast = _.map(movie.mainCast, (cast) => {
return(
<li className="list-item">
{cast}
</li>
)
})
return (<li className="list-group-item">
<div className="video-list media">
<div className="media-left">
<img className="media-object" src={imageUrl} alt={movie.title} />
</div>
<div className="media-body">
<div className="media-heading">
<h4 className="title">{movie.title}</h4>
</div>
<div className="main-cast">
<ul id="cast-list">
{mainCast}
</ul>
</div>
<div className="reviewer">
<div className="col-sm-3 col-xs-3">
<img src={imdb} className="reviewer-img img-responsive" alt="imdb" />
</div>
<div className="col-sm-3 col-xs-3">
<p className="reviewer-score">{movie.imdb}</p>
</div>
<div className="col-sm-3 col-xs-3">
<img src={rottenTomatoes} className="reviewer-img img-responsive" alt="rottenTomatoes"/>
</div>
<div className="col-sm-3 col-xs-3">
<p className="reviewer-score">{movie.rottenTomatoes}</p>
</div>
</div>
</div>
</div>
</li>
)
};
export default MovieListItem;