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>
CodePudding user response:
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)
})
}))