So i am trying to basically add a expand button to my react app that will reveal more information and i would prefer that the app expand the div size to reveal the additional content, so the its basically an expand button, i understand i need to utilize the usestate property and a function however i am having a hard time figuring out how do i update the css of the student div to expand and reveal the added information. The added information is the grades portion (FYI).
UPDATE: I have found a way to display the changes the problem i am facing is to get the state to start as isExpanded false so when a user clicks the plus button it expands to reveal the class hidden information again
here is my App.js file
import React, { useState } from "react";
import "./App.css";
export default function App() {
const [students, setStudents] = useState(null);
const [filterData, setFilterData ] = useState(null);
const [isExpanded, setIsExpanded] = useState(false);
const studentdata = 'https://www.hatchways.io/api/assessment/students';
function getStudents(){
fetch(studentdata)
.then(resp => resp.json())
.then(data => {
setFilterData(data.students);
setStudents(data.students);
setIsExpanded(false);
})
}
const searchByName = (event) => {
event.persist();
// Get the search term
const searchItem = event.target.value.toLowerCase().trim();
// If search term is empty fill with full students data
if(!searchItem.trim()) {
setFilterData(students);
}
// Search the name and if it found retun the same array
const serachIn = (firstName, lastName) => {
if(firstName.indexOf(searchItem) !== -1 || lastName.indexOf(searchItem) !== -1) {
return true;
}
let fullName = firstName.toLowerCase()+" "+lastName.toLowerCase();
if(fullName.indexOf(searchItem) !== -1) {
return true;
}
return false;
};
// Filter the array
const filteredData = students.filter((item) => {
return serachIn(item.firstName, item.lastName);
});
// Set the state with filtered data
setFilterData(filteredData);
}
function exp() {
if(isExpanded){
setIsExpanded(true);
}
}
return (
<div className="App">
<h1>Students</h1>
<div>
<button className="fetch-button" onClick={getStudents}>
Get Students
</button>
<br />
</div>
<div className="search" id="search">
<input type="text" name="serachByName" id="searchbar" placeholder="Search by name" onChange={(e) => searchByName(e)} ></input>
</div>
{filterData && filterData.map((student, index) => {
var total = 0;
for(var i = 0; i < student.grades.length; i++) {
var grade = parseInt(student.grades[i]);
total += grade;
}
const avg = total / student.grades.length;
const average = avg.toString();
const grade1 = student.grades[0];
const grade2 = student.grades[1];
const grade3 = student.grades[2];
const grade4 = student.grades[3];
const grade5 = student.grades[4];
const grade6 = student.grades[5];
const grade7 = student.grades[6];
const grade8 = student.grades[7];
return(
<div className={'student' + isExpanded ? 'expanded' : '' } key={index}>
<div className="image">
<img src={student.pic} id="icon"></img>
</div>
<div className="text">
<h3 id="name">{student.firstName} {student.lastName}</h3>
<p id="detail"><strong>EMAIL:</strong> {student.email}</p>
<p id="detail"><strong>COMPANY:</strong> {student.company}</p>
<p id="detail"><strong>SKILL:</strong> {student.skill}</p>
<p id="detail"><strong>AVERAGE:</strong>: {average}%</p>
<p id="detail" className="hidden">
<br></br>Test 1 :{grade1}
<br></br>Test 2 :{grade2}
<br></br>Test 3 :{grade3}
<br></br>Test 4 :{grade4}
<br></br>Test 5 :{grade5}
<br></br>Test 6 :{grade6}
<br></br>Test 7 :{grade7}
<br></br>Test 8 :{grade8}
</p>
</div>
<div className="expand">
<button className="expand_btn" onClick={exp()} id="expand_btn">+</button>
</div>
</div>
)}
)}
</div>
);
}
and my css file
@import url('https://fonts.googleapis.com/css?family=Bebas+Neue&display=swap');
@import url('https://fonts.googleapis.com/css?family=Roboto:300,400&display=swap');
.root{
width: 100vw;
height: 100vh;
background-color: black;
}
.App {
text-align: center;
width: 1000px;
height: 750px;
background-color: aliceblue;
border: 4px solid black;
border-radius: 5%;
margin-top: 75px;
margin-left: auto;
margin-right: auto;
overflow: scroll;
}
.student{
width: 80%;
height: 200px;
background-color: white;
display: flex;
align-items: center;
padding-top: 3%;
padding-bottom: 3%;
border: 2px solid lightblue;
margin-left: auto;
margin-right: auto;
}
.text{
text-align: left;
padding-left: 7%;
width: 300px;
}
.image{
padding-left: 15%;
}
#icon{
border-radius: 50%;
width: 150px;
height: 150px;
border: 2px solid black;
}
#name{
text-transform: capitalize;
font-family: 'Bebas Neue';
letter-spacing: 4px;
font-size: 40px;
margin-bottom: 10px;
margin-top: 10px;
}
#detail {
font-family: 'Roboto';
font-weight: 300;
line-height: normal;
margin: 0;
}
.search {
width: 80%;
height: 20px;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
margin-bottom: 20px;
}
#searchbar {
width: 100%;
height: 30px;
font-family: 'Roboto';
font-size: 18px;
font-weight: 300;
}
.expand {
width: 100px;
height: 100px;
padding-left: 3%;
margin-bottom: 5%;
}
#expand_btn {
font-family: 'Bebas Neue';
font-size: 50px;
color: lightskyblue;
background-color: transparent;
border: none;
}
.hidden {
display: none;
}
.expanded{
width: 80%;
height: 300px;
background-color: white;
display: flex;
align-items: center;
padding-top: 3%;
padding-bottom: 3%;
border: 2px solid lightblue;
margin-left: auto;
margin-right: auto;
}
I have fixed the issue in this codesandbox - https://codesandbox.io/s/purple-bird-j5vrm
Check and let me know if this helps.
There are many ways to solve your problem. One way is adding isExpanded
flag to each object in the students array so that each student object would know if that is expanded or not. And I have used the flag like this
className={"student " + student.isExpanded ? "expanded" : " "}
As per your implementation, isExpanded was being set globally so every student item would be set as Expanded and there was no way to know which item was expanded.
Note: I have implemented only for getStudents and not filterStudents.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.