2

I have a table of results retrieved from a MYSQl database with each TR having a unique ID and Class. When clicking on the TD in a row, the script toggles through various colors depending on the order status, and then writes on each toggle back to the DB using AJAX. The problem I am having is that the color changes the last table row td and not the current clicked row td. I am a noob to JS and Jquery and have read that the problem may be "hoisting" which has had me confused for a few days now. Any help is greatly appreciated.

<td id="<?php echo $row[ 'order_id' ]; ?>" class="<?php echo $row[ 'order_id' ]; ?> white"
    onclick="changeBackground(this.id)"><?php echo $row[ 'order_id' ]; ?></td>

<script>
  function getSelected() {
    return document.getElementsByClassName(<?php echo $row[ 'order_id' ]; ?>);
  }

  function changeBackground(id) {
    var all = getSelected();
    var x = id
    alert(x);
    for (var i = 0; i < all.length; i++) {
      var color = all[i].classList;
      
      if (color.contains("white")) {
        all[i].classList.add("red");
        all[i].classList.remove("white");
        $.ajax({
          type: "POST",
          url: 'update_color.php',
          data: {color: 2},
          success: function (data) {
            console.log(data);
          },
        });
        
      } else if (color.contains("red")) {
        all[i].classList.add("green");
        all[i].classList.remove("red");
        $.ajax({
          type: "POST",
          url: 'update_color.php',
          data: {color: 3},
          success: function (data) {
            console.log(data);
          },
        });

      } else if (color.contains("green")) {
        all[i].classList.add("pink");
        all[i].classList.remove("green");
        $.ajax({
          type: "POST",
          url: 'update_color.php',
          data: {color: 4},
          success: function (data) {
            console.log(data);
          },
        });
        
      } else if (color.contains("pink")) {
        all[i].classList.add("yellow");
        all[i].classList.remove("pink");
        $.ajax({
          type: "POST",
          url: 'update_color.php',
          data: {color: 5},
          success: function (data) {
            console.log(data);
          },
        });
        
      } else if (color.contains("yellow")) {
        all[i].classList.add("white");
        all[i].classList.remove("yellow");
        $.ajax({
          type: "POST",
          url: 'update_color.php',
          data: {color: 1},
          success: function (data) {
            console.log(data);
          },
        });
      }

    }
  }
</script>
2
  • 1
    Can you give some sample HTML as rendered (ie: look at the source code)? Commented Oct 27, 2021 at 8:18
  • maybe pass the id to getSelected() function when you call it, and if you expect to have more than one class with the same attribute value( all.length ) so there is more than one id with the same attribute value too, ID attribute value must be unique Commented Oct 27, 2021 at 8:40

1 Answer 1

2

If you are able to modify the HTML output slightly I believe the above Javascript can be significantly simplified but I should stress the following is untested. The order_id seems odd within the classes assigned to an element - presumably an integer which is not valid anyway as a class - perhaps if this were assigned as a dataset attribute it would make more sense and can still be referenced in your javascript code if needed. To set the class simply as one of the various colours through which you cycle would help!

So, perhaps changing the HTML like this:

<td data-id="<?php echo $row['order_id'];?>" class="white">
    <?php echo $row['order_id'];?>
</td>

Then the Javascript

const matrix={
    'white':'red',
    'red':'green',
    'green':'pink',
    'pink':'yellow',
    'yellow':'white'
};

document.querySelectorAll('table td').forEach( td=>td.addEventListener('click',function(e){
    let id=this.dataset.id;
    let colour=this.className;
    let keys=Object.values( matrix );
    
    this.classList.remove( colour );
    this.classList.add( matrix[ colour ] );
    
    
    
    let fd=new FormData();
        fd.set('color', keys.indexOf( colour) );
        fd.set('id',id);
        
    fetch( 'update_color.php',{ method:'post',body:fd} )
        .then(r=>r.text())
        .then(text=>{
            console.log(text)
        })
}))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.