Reputation: 25
I'm new to react and fairly new to programming in general.
I'm using react and want a box to expand on click while the 3 other boxes hide simultaneously. Right now I've just gotten it to add a class of 'hidee' (named that way because 'hide' is actually a feature) on click and send an alert.
Wanting the expanded area to be almost full window size as it will house content.. and then would add a nav bar to the top of that. Below is the concept and my current code is in a sandbox below that.
Here's my code so far for this component and corresponding css and html. Code Sandbox
import React, { Component } from 'react';
// onclick= (this.expand)
//outside of render:
// expand =(e) => {
// e.target (targets the one they clicked on)
// hide every other element of the class add a class to e.target to increase width and height
// add div to top with nav
// }
class AdminPanel extends Component {
constructor(){
super();
}
expand = (event) => {
event.preventDefault();
var elements = document.querySelectorAll('.title');
debugger;
for (var i=0; i<elements.length; i++){
elements[i].classList.add('hidee');
//hide everything except the one we clicked on
//if event.target != elements[i] then add a class of hidee
//add a class to event.target called expand
//make a css file and put in hidee and expand classes and put the css in
//import that css file at the top of this file
}
alert('hi');
}
render(){
return (
<div class="box">
<div class="container">
<div class="row">
<div className="col-sm-6 ">
<a href="#"/>
<div class="box-part text-center">
<div class="title" onClick={this.expand}>
<img class="card-img-top" src="https://visualpharm.com/assets/224/Folder-595b40b85ba036ed117dd27b.svg" alt=" image"/>
</div>
<div className="text">
<span><h2>Thought Archives</h2></span>
</div>
</div>
</div>
<div className="col-sm-6 ">
<a href="#"/>
<div class="box-part text-center">
<div class="title" onClick={this.expand}>
<img class="card-img-top" src="https://visualpharm.com/assets/168/Read%20Message-595b40b75ba036ed117d88f5.svg" alt=" image"/>
</div>
<div className="text">
<span><h2>Incoming Requests</h2></span>
</div>
</div>
</div>
<div className="col-sm-6 ">
<a href="#"/>
<div class="box-part text-center">
<div class="title" onClick={this.expand}>
<img class="card-img-top" src="https://visualpharm.com/assets/375/Create-595b40b75ba036ed117d7bbf.svg" alt=" image"/>
</div>
<div className="text">
<span><h2>Create New</h2></span>
</div>
</div>
</div>
<div className="col-sm-6 ">
<a href="#"/>
<div class="box-part text-center">
<div class="title" onClick={this.expand}>
<img class="card-img-top" src="https://static.thenounproject.com/png/5040-200.png" alt=" image"/>
</div>
<div className="text">
<span><h2>Your Community</h2></span>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default AdminPanel;
/* css for AdminPanel.js*/
@import url('https://fonts.googleapis.com/css?family=Josefin+Sans:100,300,400,600,700');
body{
background: #f2f2f2;
font-family: 'Josefin Sans', sans-serif;
}
h3{
font-family: 'Josefin Sans', sans-serif;
}
.box{
padding:60px 0px;
}
.card-img-top {
height: 100px;
width: 30%;
}
.box-part{
background:#FFF;
border-radius:10px;
padding:60px 10px;
margin:30px 0px;
}
.box-part:hover{
background:#4183D7;
}
.box-part:hover .fa ,
.box-part:hover .title ,
.box-part:hover .text ,
.box-part:hover a{
color:#FFF;
-webkit-transition: all 1s ease-out;
-moz-transition: all 1s ease-out;
-o-transition: all 1s ease-out;
transition: all 1s ease-out;
}
.text{
margin:20px 0px;
}
.fa{
color:#4183D7;
}
/* end css for adminPanel.js*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
</body>
</html>
Upvotes: 1
Views: 12837
Reputation: 1063
if I were your, I'd definitely split the div
's with the class of title
into a separate component and have an initial data with everything each div
needs.
If you make that, then you just have to loop through your source of data and render the elements your them to be rendered. As a result, you can show/hide the navbar
.
I've created a sandbox in which you can see how to control the state of your component and render whatever you want accordingly.
Assume that each
div
is calledcard
Hope that could help!
Upvotes: 1
Reputation: 1474
You can do it easily as below :
class AdminPanel extends React.Component {
state = {
//Create sections obj in state to maintain your section's class
sections : {
thoughtArchives: {
key: 1,
class: 'hidee',
//add extra data if you want for further use
},
incomingRequests: {
key: 2,
class: 'hidee'
},
createNew: {
key: 3,
class: 'hidee'
},
yourCommunity: {
key: 4,
class: 'hidee'
}
}
}
constructor(props) {
super(props);
}
expand = (sectionKey) => {
//get the prevState
this.setState(prevState => {
//if key matches with section to expand add expand class or add hidee class
for (let k in prevState.sections) {
prevState.sections[k].class = prevState.sections[k].key === sectionKey ? 'expand' : 'hidee'
}
//return sections to update state
return prevState
})
}
render() {
let {sections} = this.state;
return (<div className="box">
<div className="container">
<div className="row">
<div className="col-sm-6 ">
<a href="#"/>
<div className="box-part text-center">
{/* Append expand/hidee class & attach onCLick listener and pass key of section to expand function*/}
<div className={"title " + sections.thoughtArchives.class} onClick={this.expand.bind(this, sections.thoughtArchives.key)}>
<img className="card-img-top" src="https://visualpharm.com/assets/224/Folder-595b40b85ba036ed117dd27b.svg" alt=" image"/>
</div>
<div className="text">
<span>
<h2>Thought Archives</h2>
</span>
</div>
</div>
</div>
<div className="col-sm-6 ">
<a href="#"/>
<div className="box-part text-center">
<div className={"title " + sections.incomingRequests.class} onClick={this.expand.bind(this, sections.incomingRequests.key)}>
<img className="card-img-top" src="https://visualpharm.com/assets/168/Read%20Message-595b40b75ba036ed117d88f5.svg" alt=" image"/>
</div>
<div className="text">
<span>
<h2>Incoming Requests</h2>
</span>
</div>
</div>
</div>
<div className="col-sm-6 ">
<a href="#"/>
<div className="box-part text-center">
<div className={"title " + sections.createNew.class} onClick={this.expand.bind(this, sections.createNew.key)}>
<img className="card-img-top" src="https://visualpharm.com/assets/375/Create-595b40b75ba036ed117d7bbf.svg" alt=" image"/>
</div>
<div className="text">
<span>
<h2>Create New</h2>
</span>
</div>
</div>
</div>
<div className="col-sm-6 ">
<a href="#"/>
<div className="box-part text-center">
<div className={"title " + sections.yourCommunity.class} onClick={this.expand.bind(this, sections.yourCommunity.key)}>
<img className="card-img-top" src="https://static.thenounproject.com/png/5040-200.png" alt=" image"/>
</div>
<div className="text">
<span>
<h2>Your Community</h2>
</span>
</div>
</div>
</div>
</div>
</div>
</div>)
}
}
export default AdminPanel;
Upvotes: 0
Reputation: 871
Update the state of the component in the expand function using setState, When the state changes to true, the render method gets the new state.
constructor(){
super();
this.expand = this.expand.bind(this);
this.state = {
hide: !this.state.hide
};
}
expand = (event) => {
event.preventDefault();
this.setState({
hide: true
});
alert('hi');
}
{ this.state.hide ?
<div className="col-sm-6 ">
<a href="#"/>
<div class="box-part text-center">
<div class="title" onClick={this.expand}>
<img class="card-img-top" src="https://visualpharm.com/assets/168/Read%20Message-595b40b75ba036ed117d88f5.svg" alt=" image"/>
</div>
<div className="text">
<span><h2>Incoming Requests</h2></span>
</div>
</div>
</div>
: null }
Upvotes: 1