skip to Main Content

I’m creating a product review comment section with a star rating system but I can’t get the rating to display correctly once the comment is added to the comment section.

This is the code I use to create and add a new review, the function createRating gets each star and adds the class .checked based on the rating introduced by the user. The problem is when I have more than one comment, because the querySelectorAll gets the stars from all of the comments in the page and not the comment just created. How can I select the stars from the comment just created?

function publishReview() {
    const comment = document.createElement('div');
    comment.classList.add('review-comment');
    comment.innerHTML = `
    <div class="review-header">
        <div class="rating">
            <span class="review-star fa fa-star"></span>
            <span class="review-star fa fa-star"></span>
            <span class="review-star fa fa-star"></span>
            <span class="review-star fa fa-star"></span>
            <span class="review-star fa fa-star"></span>
        </div>    
        <p class="review-date">1 abr. 2023</p>
    </div>
    <p class="review-text">${reviewTextInput.value}</p>
    <span>Helpful?<button class="helpful-button">Yes</button> <button class="helpful-button">No</button></span>`;
    
    commentSection.appendChild(comment);
    popupDisplayNone();

    const ratingStars = document.querySelectorAll('.review-star');
    createRating(ratingStars, currentStar);
    
}

If any more information is required, please ask, new to this.

2

Answers


  1. document.querySelectorAll('.review-star') will select all stars from every review comment on the page. Instead, you should limit the scope of your selection to the comment you’ve just created.

    function publishReview() {
        const comment = document.createElement('div');
        comment.classList.add('review-comment');
        comment.innerHTML = `
        <div class="review-header">
            <div class="rating">
                <span class="review-star fa fa-star"></span>
                <span class="review-star fa fa-star"></span>
                <span class="review-star fa fa-star"></span>
                <span class="review-star fa fa-star"></span>
                <span class="review-star fa fa-star"></span>
            </div>    
            <p class="review-date">1 abr. 2023</p>
        </div>
        <p class="review-text">${reviewTextInput.value}</p>
        <span>Helpful?<button class="helpful-button">Yes</button> <button class="helpful-button">No</button></span>`;
        
        commentSection.appendChild(comment);
        popupDisplayNone();
    
        // Only select stars within the newly added comment
        const ratingStars = comment.querySelectorAll('.review-star');
        createRating(ratingStars, currentStar);
    }
    
    Login or Signup to reply.
  2. My first thought would be to add a data-id attribute to the review div (the one with the ‘review-comment’ class). If you have a database that stores reviews, you could use that one, otherwise you can generate one in javascript.

    Adding the data-id attribute can be achieved with the setAttribute API:

    comment.setAttribute("data-id", {{ your review id }});
    

    Then, filter the review stars by changing your query selector like this:

    const ratingStars = document.querySelectorAll(".review-comment[data-id='{{your review id}}'] .review-star");
    

    Edit
    MaikeruDev’s answer is simpler, so that is probably better for now. But if you ever need to access a certain comment again, my answer will offer a more persistent solution.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search