how to send ajax callback to specific div which are generated by foreach loop

Viewed 88

It is about this situation:

Below is some html (rating stars) which are generated by a foreach loop in php. So i have a lot of divs with class rating. The $file_id is unique and is in every div different!

<div class="rating" data-rating="<?php echo $round;?>">
    <div class="rating-stars">                  
        <a href="#5" class="click-trigger star-5" data-value="star-5" data-id="<?php echo $file_id; ?>" title="Vote 5 stars">&#x2605</a>
        <a href="#4" class="click-trigger star-4" data-value="star-4" data-id="<?php echo $file_id; ?>" title="Vote 4 stars">&#x2605</a>
        <a href="#3" class="click-trigger star-3" data-value="star-3" data-id="<?php echo $file_id; ?>" title="Vote 3 stars">&#x2605</a>
        <a href="#2" class="click-trigger star-2" data-value="star-2" data-id="<?php echo $file_id; ?>" title="Vote 2 stars">&#x2605</a>
        <a href="#1" class="click-trigger star-1" data-value="star-1" data-id="<?php echo $file_id; ?>" title="Vote 1 star">&#x2605</a>
    </div>
    <div class="rating-votes">
        Average: <span id="count-avg"><?php echo $avg;?></span> Votes: <span id="count-total"><?php echo array_sum($count);?></span>
    </div>

</div>

My jquery ajax looks like this:

$('.click-trigger').on('click', function(e) {
    e.preventDefault(); 

    var value = $(this).data('value');
    var file_id = $(this).data('id');

    $.ajax({
        url: 'counter.php',
        type: 'POST',
        data: { 
            value:value,
            file_id:file_id         
            },
        success: function(data){
            $('.rating-votes').html(data);

        }
    });

});

And file counter.php makes this echo as call back:

echo '<div class="text-success">Thanks for voting!</div>';

The problem is: in every div with class .rating-votes appears the echo. But it should appear only in the div which one of the rating stars is clicked.

How can i achieve this?

1 Answers

To fix this you need to use jQuery's DOM traversal methods to retrieve the .rating-votes element related to the start which was clicked. In this case use closest() and next().

Also note that you should DRY up the code by putting the data-id attribute on the single common container to the .click-trigger elements instead of repeating it on every single one. Try this:

<div class="rating" data-rating="<?php echo $round;?>">
  <div class="rating-stars" data-id="<?php echo $file_id; ?>">
    <a href="#5" class="click-trigger star-5" data-value="star-5" title="Vote 5 stars">&#x2605</a>
    <a href="#4" class="click-trigger star-4" data-value="star-4" title="Vote 4 stars">&#x2605</a>
    <a href="#3" class="click-trigger star-3" data-value="star-3" title="Vote 3 stars">&#x2605</a>
    <a href="#2" class="click-trigger star-2" data-value="star-2" title="Vote 2 stars">&#x2605</a>
    <a href="#1" class="click-trigger star-1" data-value="star-1" title="Vote 1 star">&#x2605</a>
  </div>
  <div class="rating-votes">
    Average: <span id="count-avg"><?php echo $avg;?></span> Votes: <span id="count-total"><?php echo array_sum($count);?></span>
  </div>
</div>
$('.click-trigger').on('click', function(e) {
  e.preventDefault();
  let $star = $(this);
  let $container = $star.closest('.rating-stars');

  $.ajax({
    url: 'counter.php',
    type: 'POST',
    data: {
      value: $star.data('value'),
      file_id: $container.data('id')
    },
    success: function(data) {
      $container.next('.rating-votes').html(data);
    }
  });
});
Related