Home > Software design >  how to return rating on a span element?
how to return rating on a span element?

Time:11-16

I am trying to make a interactive rating component. I have no clue how I can return the result on a span element after a rating is chosen.

When I enter the rating on buttons:

enter image description here

After I submit the rating:

enter image description here

There I want to return the result.

I was trying an if statement in the forEach function but didn't know how to return the result on the span element.

const allBtns = document.querySelectorAll('.btn');


allBtns.forEach(btn => {
  btn.addEventListener('click', function onClick() {
    btn.style.backgroundColor = 'orange';
  })
});

function ShowAndHide() {

  let y = document.querySelector('.ratingbox');
  let x = document.querySelector('.thankyou');
  if (x.style.display == 'none') {
    y.style.display = 'none';
    x.style.display = 'block';


  } else {
    x.style.display = 'none';
  }

}
<div >
  <div >
    <img src="images/icon-star.svg" alt="" >
  </div>

  <div >
    <h1>How did we do?</h1>

    <p>Please let us know how we did with your support request. All feedback is appreciated to help us improve our offering! </p>
  </div>

  <div >
    <ul>
      <li><button ><p id="num">1</p></button></li>
      <li><button ><p id="num">2</p></button></li>
      <li><button ><p id="num">3</p></button></li>
      <li><button ><p id="num">4</p></button></li>
      <li><button ><p id="num">5</p></button></li>
    </ul>

    <button  onclick="ShowAndHide()">SUBMIT</button>
  </div>
</div>

<div  style="display: none; ">
  <div >
    <img src="https://via.placeholder.com/50" alt=" " >
    
    <div >
      <span id="rating "></span>
    </div>
    
    <div >
      <h2>Thank you!</h2>
      
      <p id="appreciate ">We appreciate you taking the thime to give a rating.<br> If you ever need more support, don't hesitate to <br> get in touch!
      </p>
    </div>
  </div>
</div>

CodePudding user response:

There are multiple issues with your code. The main issue is you are using the same id, num, for multiple elements, which is invalid. Change those id's to class instead, like this:

<ul>
    <li><button ><p >1</p></button></li>
    <li><button ><p >2</p></button></li>
    <li><button ><p >3</p></button></li>
    <li><button ><p >4</p></button></li>
    <li><button ><p >5</p></button></li>
</ul>

After doing that, one way to acquire the most recently selected button is to find the nested .num within your button click eventListeners, such as var rating = parseInt(btn.querySelector(".num").textContent)

Here is how you might do that with minimal changes to your current code:

const allBtns = document.querySelectorAll('.btn');
var currentRating = null;

allBtns.forEach(btn => {
  btn.addEventListener('click', function onClick() {
    btn.style.backgroundColor = 'orange';
    currentRating = parseInt(btn.querySelector(".num").textContent)
  })
});

function ShowAndHide() {
  if (currentRating){
    alert(currentRating);
  }
  let y = document.querySelector('.ratingbox');
  let x = document.querySelector('.thankyou');
  if (x.style.display == 'none') {
    y.style.display = 'none';
    x.style.display = 'block';

  } else {
    x.style.display = 'none';
  }
}

Here is a JsFiddle that does just this and alerts the selected rating: https://jsfiddle.net/eg4Ly0nd/

Note: I would recommend using hidden checkbox inputs within each of the li buttons and adding to code your event listener to check the selected input associated with a button and uncheck the others. Then you don't need the global currentRating variable that is included in my solution; you can just find the input that is checked. I only wrote it this way to make minimal changes to the code you provided while still giving a solution.

CodePudding user response:

Just an alternative solution, you can set the rating value for each button by Javascript only, so it is independent to any text content in p. It also saves the trouble of reading the p tag.

The below Javascript snippet can be used with you original HTML without changes.

But as other comments mentioned, it is recommended that you assign a different id for each p, or no id at all since no need to read these tags in code anyway.

Full example:

const allBtns = document.querySelectorAll('.btn');
const resultSpan = document.querySelector(".selected span")

allBtns.forEach((btn, i) => {
  btn.addEventListener('click', function onClick() {
    btn.style.backgroundColor = 'orange';

    // Customize the output text here
    // It displays in Success screen
    resultSpan.innerText = `You have rated ${i   1}`;
  })
});

function ShowAndHide() {

  let y = document.querySelector('.ratingbox');
  let x = document.querySelector('.thankyou');
  if (x.style.display == 'none') {
    y.style.display = 'none';
    x.style.display = 'block';


  } else {
    x.style.display = 'none';
  }

}
<div >
  <div >
    <img src="images/icon-star.svg" alt="" >
  </div>

  <div >
    <h1>How did we do?</h1>

    <p>Please let us know how we did with your support request. All feedback is appreciated to help us improve our offering! </p>
  </div>

  <div >
    <ul>
      <li><button ><p>1</p></button></li>
      <li><button ><p>2</p></button></li>
      <li><button ><p>3</p></button></li>
      <li><button ><p>4</p></button></li>
      <li><button ><p>5</p></button></li>
    </ul>

    <button  onclick="ShowAndHide()">SUBMIT</button>
  </div>
</div>

<div  style="display: none; ">
  <div >
    <img src="https://via.placeholder.com/50" alt=" " >
    
    <div >
      <span id="rating "></span>
    </div>
    
    <div >
      <h2>Thank you!</h2>
      
      <p id="appreciate ">We appreciate you taking the thime to give a rating.<br> If you ever need more support, don't hesitate to <br> get in touch!
      </p>
    </div>
  </div>
</div>

  • Related