简体   繁体   中英

create an expand content or show more content button in react app

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM