0

Background

I am using PHP to created a list of voting sections. Each section is the same except for a unique number, which increases by 1 each time the PHP loops.

I use the PHP variable $n as a counter, and place that in the id attributes in several places in each section.

Current PHP/HTML:

echo "<div id='votesection'>";
echo "<h3 id='rating " . $n . "' style='display:block;'>" . 
echo "<h3 id='ratingup " . $n . "' style='display:none;'>" . $ratingup . "</h3>\r\n";
echo "<h3 id='ratingdown " . $n . "' style='display:none;'>" . $ratingdown . "</h3>\r\n";
echo "<div class='arrow-down' onclick='downvote($n)'></div>\r\n";
echo "<div class='arrow-up' onclick='upvote($n)'></div>";
echo "</div>";

Goal

When a user clicks on an arrow down or arrow up, certain divs are hidden or displayed. Example, when the up arrow in my second section is clicked, my <h3 id='ratingup2'></h3> would change to visible.

Current JS

 function upvote() {
    // Script to hide rating, and rating down and display:block ratingup
    // Will also need to execture php sql query to increment event rating by one for event by one
 }

function downvote(){
    // Same script but to show rating down and decrement rating
 }

Should I pass every rating id to the script or is there an easier way to do this that I'm missing?

Community
  • 1
  • 1
I2obiN
  • 181
  • 3
  • 18
  • 2
    what is $n? is it the id?what do you mean by "adding each id to the script? You shouldn't have spaces in the id eg "rating 34234" you should have "description_id".I m sure you are going to get an error. http://stackoverflow.com/a/79022/2321666 – codegaze Apr 17 '15 at 18:51
  • Correct, sorry formatting error with the space. It should be rating0, rating1, rating2, etc etc. Since each votesection will have a different number, I'd assumed to identify each rating it would be best to give them different ids. – I2obiN Apr 17 '15 at 19:14

3 Answers3

2

Passing the ID is the easiest way to do it with plain Javascript.

function upvote(n) {
    document.getElementById('ratingup ' + n).style.display="block";
    document.getElementById('ratingdown ' + n).style.display="none";
}
function downvote(n) {
    document.getElementById('ratingup ' + n).style.display="none";
    document.getElementById('ratingdown ' + n).style.display="block";
}

A way to do it without passing the ID would be to put classes on the rating DIVs, and pass this instead.

HTML:

echo "<div id='votesection'>";
echo "<h3 id='rating " . $n . "' style='display:block;'>" . 
echo "<h3 class='ratingup' style='display:none;'>" . $ratingup . "</h3>\r\n";
echo "<h3 class='ratingdown' style='display:none;'>" . $ratingdown . "</h3>\r\n";
echo "<div class='arrow-down' onclick='downvote(this)'></div>\r\n";
echo "<div class='arrow-up' onclick='upvote(this)'></div>";

JS:

function upvote(self) {
    var parent = self.parentNode;
    parent.querySelector(".ratingup").style.display = "block";
    parent.querySelector(".ratingdown").style.display = "none";
}
function downvote(self) {
    var parent = self.parentNode;
    parent.querySelector(".ratingup").style.display = "none";
    parent.querySelector(".ratingdown").style.display = "block";
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thank you. Just to clarify, the parentNode would be the votesection? This would change only the selected ratings within that votesection, and not other votesections on the page correct? – I2obiN Apr 17 '15 at 19:12
  • Yes, that's right. `parentNode` is the DOM element that contains this element. Using that as the context to `querySelector` only finds the matching element within that DIV. – Barmar Apr 17 '15 at 19:15
0

You can create only one wrapper with the id votesection_id and then do everything else with js/ajax

    echo "<div id='votesection_" . $n . "'>";
    echo "<h3 id='rating' style='display:block;'>" . 
    echo "<h3 id='ratingup' style='display:none;'>" . $ratingup . "</h3>\r\n";
    echo "<h3 id='ratingdown' style='display:none;'>" . $ratingdown . "</h3>\r\n";
    echo "<div class='arrow-down' onclick='downvote($n)'></div>\r\n";
    echo "<div class='arrow-up' onclick='upvote($n)'></div>";
    echo "</div>";
<script>

    function upvote(id){
      // 1. Go To the server with ajax do your stuff  2. return the current upvotes 3.replace the upvotes h3 text
    }
    function downvote(id){
       // 1. Go To the server with ajax do your stuff  2. return the current downvotes 3.replace the downvotes h3 text
    }

</script>
codegaze
  • 755
  • 7
  • 15
0

As @idioteque says in their comment, spaces in element IDs are not allowed. The best way to get this information into the document is probably with data attributes.

Also, multiple elements with the same id are not allowed, what you probably need in this case are classes. (I'm assuming this chunk of HTML will be repeated multiple times per page.)

Borrowing @Barmar's idea of passing this into the event handler, here's how I'd change the server code:

echo "<div class='votesection' data-rating-id=" . $n . ">";
echo "<h3 class='rating' style='display:block;'>" . 
echo "<h3 class='ratingup' style='display:none;'>" . $ratingup . "</h3>\r\n";
echo "<h3 class='ratingdown' style='display:none;'>" . $ratingdown . "</h3>\r\n";
echo "<div class='arrow-down' onclick='downvote(this)'></div>\r\n";
echo "<div class='arrow-up' onclick='upvote(this)'></div>";
echo "</div>";

And the JS:

function upvote(self) {
    var parent = self.parentNode;
    parent.querySelector(".ratingup").style.display = "block";
    parent.querySelector(".ratingdown").style.display = "none";
    var id = parent.dataset.ratingId;
    // do your AJAX or whatever with id
}
function downvote(self) {
    var parent = self.parentNode;
    parent.querySelector(".ratingup").style.display = "none";
    parent.querySelector(".ratingdown").style.display = "block";
    var id = parent.dataset.ratingId;
    // do your AJAX or whatever with id
}
solarshado
  • 567
  • 5
  • 18