0

I'm trying to create a "see more" button that will only appear after another button has been clicked. I can't find anything online for it.

The site is just a cat API with a button that will randomly generate a cat image, but I want to have a button that will appear at the bottom of the page to generate another image. My problem is that I cant get the button to be invisible until the first button is clicked.

let generate_btn =  document.querySelector(".generate_btn, see_more");

generate_btn.addEventListener("click", fetchPics);

function fetchPics() {

fetch('https://api.thecatapi.com/v1/images/search')
    .then(response => response.json())
    .then((data) => {
        let catsImgUrl = data[0].url

        let catsImgElement = document.createElement("img")
        catsImgElement.setAttribute('src', `${catsImgUrl}`)
        catsImgElement.classList.add("showcase")

        let catsImg = document.querySelector(".catsImg")
        catsImg.appendChild(catsImgElement)

    })
    .catch((err => console.log(err)))
};
<!doctype html>
    <html>
    <head>
        <title>CatHub | Random Cat Generator</title>
<link rel="stylesheet" href="../css/bootstrap.css">
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>    
</head>
<body class="jumbotron">
   <nav class="navbar navbar-expand-lg navbar-light bg-light navbar-brand dark">
      <div class="container-fluid">
        <img class="navbar-brand" src="../images/LogoMakr-6dBdy9.png" width="150" height="57"></img>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="#">Home</a>
            </li>
          </ul>
        </div>
      </div>
    </nav>

    <div class="main-content">
<h1>Welcome to CatHub, wanna see some cats?</h1>
<button type="button" class="btn btn-danger btn-grad generate_btn">Yes!</button>
<button type="button" class="btn btn-danger btn-grad generate_btn see_more">Show more</button>
</div>
<div class="catsImg main-content"></div>

<style>
.showcase {
   width: 60%;
   align-items: center;
   justify-content: center;
   margin-bottom: 10%;
}
</style>
<script src="../js/script.js"></script>
</body>
</html>
pilchard
  • 12,414
  • 5
  • 11
  • 23
knava
  • 3
  • 2
  • simply hide the `see more` button in the initial HTML, and then show it when the `yes` button is clicked. see: [Show/hide 'div' using JavaScript](https://stackoverflow.com/questions/21070101/show-hide-div-using-javascript) – pilchard Jul 05 '21 at 17:12
  • try to initially hide the button at the first place such ``````. after that, at your 2nd chain of ```then``` show the button by adding classes or ```btn.style.display = 'block';``` . the downside with this approach, if the user disabled javascript, the button will never be appeared. – Raden Kriting Jul 05 '21 at 17:17

3 Answers3

0

Hide the button using CSS, then add an event listener on the .generate_btn button that selects the other button and sets its display style property to block.

Also, take note that querySelector(".generate_btn, see_more") only selects the 'Yes!' button, since querySelector only selects the first element. Instead, use querySelectorAll and loop through the array.

let generate_btn = document.querySelectorAll(".generate_btn, see_more");

generate_btn.forEach(e => e.addEventListener("click", fetchPics));

function fetchPics() {

  fetch('https://api.thecatapi.com/v1/images/search')
    .then(response => response.json())
    .then((data) => {
      let catsImgUrl = data[0].url

      let catsImgElement = document.createElement("img")
      catsImgElement.setAttribute('src', `${catsImgUrl}`)
      catsImgElement.classList.add("showcase")

      let catsImg = document.querySelector(".catsImg")
      catsImg.appendChild(catsImgElement)

    })
    .catch((err => console.log(err)))
};

document.querySelector('.generate_btn').addEventListener('click', function() {
  this.style.display = "none";
  document.querySelector('.see_more').style.display = "block";
})
.see_more {
  display: none;
}
<!doctype html>
<html>

<head>
  <title>CatHub | Random Cat Generator</title>
  <link rel="stylesheet" href="../css/bootstrap.css">
  <!-- JavaScript Bundle with Popper -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</head>

<body class="jumbotron">
  <nav class="navbar navbar-expand-lg navbar-light bg-light navbar-brand dark">
    <div class="container-fluid">
      <img class="navbar-brand" src="../images/LogoMakr-6dBdy9.png" width="150" height="57"></img>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
      <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
          <li class="nav-item">
            <a class="nav-link active" aria-current="page" href="#">Home</a>
          </li>
        </ul>
      </div>
  </nav>

  <div class="main-content">
    <h1>Welcome to CatHub, wanna see some cats?</h1>
    <button type="button" class="btn btn-danger btn-grad generate_btn">Yes!</button>
    <button type="button" class="btn btn-danger btn-grad generate_btn see_more">Show more</button>
  </div>
  <div class="catsImg main-content"></div>

  <style>
    .showcase {
      width: 60%;
      align-items: center;
      justify-content: center;
      margin-bottom: 10%;
    }
  </style>
  <script src="../js/script.js"></script>
</body>

</html>
Spectric
  • 30,714
  • 6
  • 20
  • 43
0

let generate_btn = document.querySelector(".generate_btn");

generate_btn.addEventListener("click", fetchPics);

function fetchPics() {

  document.querySelector(".see_more").style.display = 'inline-block';


  fetch('https://api.thecatapi.com/v1/images/search')
    .then(response => response.json())
    .then((data) => {
      let catsImgUrl = data[0].url

      let catsImgElement = document.createElement("img")
      catsImgElement.setAttribute('src', `${catsImgUrl}`)
      catsImgElement.classList.add("showcase")

      let catsImg = document.querySelector(".catsImg")
      catsImg.appendChild(catsImgElement)

    })
    .catch((err => console.log(err)))
};
.see_more {
  display: none;
}
<!doctype html>
<html>

<head>
  <title>CatHub | Random Cat Generator</title>
  <link rel="stylesheet" href="../css/bootstrap.css">
  <!-- JavaScript Bundle with Popper -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</head>

<body class="jumbotron">
  <nav class="navbar navbar-expand-lg navbar-light bg-light navbar-brand dark">
    <div class="container-fluid">
      <img class="navbar-brand" src="../images/LogoMakr-6dBdy9.png" width="150" height="57"></img>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
      <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
          <li class="nav-item">
            <a class="nav-link active" aria-current="page" href="#">Home</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>

  <div class="main-content">
    <h1>Welcome to CatHub, wanna see some cats?</h1>
    <button type="button" class="btn btn-danger btn-grad generate_btn">Yes!</button>
    <button type="button" class="btn btn-danger btn-grad generate_btn see_more">Show more</button>
  </div>
  <div class="catsImg main-content"></div>

  <style>
    .showcase {
      width: 60%;
      align-items: center;
      justify-content: center;
      margin-bottom: 10%;
    }
  </style>
  <script src="../js/script.js"></script>
</body>

</html>
Spectric
  • 30,714
  • 6
  • 20
  • 43
DCR
  • 14,737
  • 12
  • 52
  • 115
0

A few issues:

  • The selector .generate_btn, see_more will only select one button. see_more will not select anything, since there is no . before it, and so it is looking for an element with that tag name.

  • With querySelector you still only select one element, even if the selector would match with multiple elements

  • addEventListener can be called on one DOM element. So for this reason and the above reasons, you are not listening to clicks on the second button.

  • The style tag should better be placed in the head section of the document.

Instead of using two buttons, it will be much easier, if you just change its caption after the first image has loaded. It will be good to wait with this caption change until the image's load event has fired:

// Only one button:
let generate_btn =  document.querySelector(".generate_btn");
generate_btn.addEventListener("click", fetchPics);

function fetchPics() {
    fetch('https://api.thecatapi.com/v1/images/search')
        .then(response => response.json())
        .then((data) => {
            let catsImgUrl = data[0].url;
            let catsImgElement = document.createElement("img");
            // Add this:
            catsImgElement.onload = () => generate_btn.textContent = "Show more...";
            catsImgElement.setAttribute('src', `${catsImgUrl}`);
            catsImgElement.classList.add("showcase");
            let catsImg = document.querySelector(".catsImg");
            catsImg.appendChild(catsImgElement);
        })
        .catch(console.log)
};
.showcase {
   width: 60%;
   align-items: center;
   justify-content: center;
   margin-bottom: 10%;
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>    

   <nav class="navbar navbar-expand-lg navbar-light bg-light navbar-brand dark">
      <div class="container-fluid">
        <img class="navbar-brand" src="../images/LogoMakr-6dBdy9.png" width="150" height="57"></img>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="#">Home</a>
            </li>
          </ul>
        </div>
      </div>
    </nav>

    <div class="main-content">
<h1>Welcome to CatHub, wanna see some cats?</h1>
<button type="button" class="btn btn-danger btn-grad generate_btn">Yes!</button>
</div>
<div class="catsImg main-content"></div>
trincot
  • 317,000
  • 35
  • 244
  • 286
  • Thank you very much! That solved my issue. However, I am having trouble sticking the button to the bottom of the page now. It sticks to the bottom of the screen but will follow you as you scroll, I want it to be at the very bottom like a footer would be. Any tips? – knava Jul 05 '21 at 18:37
  • 1
    That is a different question. If the button should be below the image, then just change the static HTML accordingly. If you need more features, and cannot make it work, then feel free to ask a new question: make sure to focus a question on *one* problem though. – trincot Jul 05 '21 at 18:44