so I'm creating an online shop website and the admin is suppossed to be able to add,edit or remove the products. I've successfully finished coding the first two actions using php, and now I want to make the delete function. I add the products from database to a table using a foreach php loop. I want the admin to be able to delete a product without refreshing the page, however, my ajax function does not work at all(I'm a noob in js btw), and it does not call my php page that I want to use to access database. My javascript is not that good so I'm wondering if it's the way I'm adding the actionlisteners that ruins the code. Here is a simplified version of my code:
Javascript $(document).ready(function(){
let buttons = document.querySelectorAll('.rmvElement');
for (let i=0; i<buttons.length; i ) {
buttons[i].addEventListener('click', clickFunc(i));
}
function clickFunc(i) {
$.ajax({
type:'post',
url:'./backend/adminAccess/deleteItem.php',
dataType: 'json',
data:(id=buttons[i].children[0].id ),
cache: false,
dataType: 'json',
success:function(data){
console.log(data);
}
})
}
});
php
<php>
var_dump("100");
</php>
I have tried changing the code of the ajax function, using it without the "$.ajax" attribute, using "jQuery.ajax", adding a php function and changing the code so that it calls the function instead, and so many other things. I have been working on this code for a few days now, but still havent got results. I'd be forever thankful if you helped me.
Edit:This is the php page I created the buttons:
<?php
require_once './backend/connection.php';
require_once './backend/adminAccess/product.php';
echo "<script src='./public/js/deleteItem.js'> </script>";
$sql="SELECT * FROM products";
$query=mysqli_query($conn,$sql);
$queryarray=mysqli_fetch_assoc($query);
$details='';
?>
<table >
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Product name</th>
<th scope="col">Product type</th>
<th scope="col">Additional info</th>
<th scope="col">Items left</th>
<th scope="col">Price</th>
<th scope="col">Thumbnail</th>
<th scop="col">Edit</th>
<th scop="col">Delete</th>
<!-- fix the scroll bar just in case. -->
</tr>
</thead>
<tbody>
<?php foreach($query as $key=>$value):?>
<tr id="$key">
<td><?php echo $key 1; ?></td>
<td><?php echo $value['product_name']; ?></td>
<td><?php echo $value['product_type']; ?></td>
<?php $details=product::productListItems($conn,$value['product_type_id'],$value['product_type']);?>
<?php if($value['product_type']=='stationery'):?>
<td><?php echo 'type:'.$details['stationery_type']; ?></td>
<?php elseif($value['product_type']=='cosmetics'):?>
<td><?php echo 'type:'.$details['cosmetics_type'].', brand:'.$details['brand_name'].
', color:'.$details['cosmetics_color'].', expire date:'.$details['expire_date']; ?></td>
<?php elseif($value['product_type']=='attire'):?>
<td><?php echo 'type:'.$details['attire_type'].', color:'.$details['attire_color'].', size:'.$details['attire_size']; ?></td>
<?php else:?>
<td><?php echo '_';endif; ?></td>
<td><?php echo $value['items_left']; ?></td>
<td><?php echo $value['price'].'$'; ?></td>
<?php if($value['thumbnail']!=''): ?>
<td><img src="<?php echo substr($value['thumbnail'],6);?>">
<?php else: ?>
<td><img src="./public/thumbnails/temp.jpeg"></td>
<?php endif; ?>
<?php if($value['product_type']=='stationery'):?>
<td><?php echo'<a type="submit" id="'.$value['id'].'" href="?admin=editStationery'.$value['id'].'-'.$details['id'].'">Edit </a></td>'
.'<td ><a id="'.$value['id'].'_'.$details['id'].'" >Delete</a></td>'
?>
<?php elseif($value['product_type']=='cosmetics'):?>
<td><?php echo'<a type="submit" href="?admin=editCosmetics'.$value['id'].'-'.$details['id'].'">Edit </a></td>'
.'<td><a onclick="delete('.$value['id'].','.$details['id'].')">Delete</a></td>'
?>
<?php elseif($value['product_type']=='attire'):?>
<td><?php echo'<a type="submit" href="?admin=editAttire'.$value['id'].'-'.$details['id'].'">Edit </a></td>'
.'<td><a onclick="delete('.$value['id'].','.$details['id'].')">Delete</a></td>'
?>
<?php else:?>
<td><?php echo '_';endif;?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
CodePudding user response:
The method addEventListener() works by adding a function, or an object that implements EventListener, to the list of event listeners for the specified event type on the EventTarget on which it's called.
When you call:
buttons[i].addEventListener('click', clickFunc(i));
clickFunc
is invoked and it is not added as listener.
In order to get the reference to the button you can use this
that is the reference to the button clicked.
$(document).ready(function(){
let buttons = document.querySelectorAll('.rmvElement');
for (let i=0; i<buttons.length; i ) {
buttons[i].addEventListener('click', clickFunc);
}
function clickFunc() {
console.log("clickFunc start");
console.log("data to send: " this.children[0].id);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div ><a id="product_desc" >click me</a></div>
CodePudding user response:
When you use addEventListener
on an element the actual event listener is passed a single argument - the event
. The manner in which you were trying to invoke the function was incorrectly trying to pass in your own variable i
to that function. As with most things there are a couple of ways to solve this - you could use an anonymous function and from within that anonymous function call your clickFunc
ie:
buttons[i].addEventListener('click', function(e){
clickFunc(i)
})
or you could use either the event
to identify the element ( and from that find the id and issue the request ) or a slightly different approach using a conventional function rather than the arrow function
syntax allows you to access this
from within the function and refer to the element that invoked the click.
More info about addEventListener
The following mocked up piece of HTML is intended to act as a pseudo-replica of the HTML depicted in your code above but greatly simplified. The hyperlink
elements that you were using were not correct so I replaced them with button
elements
const clickhandler=function(event){
event.preventDefault();
/*
within the context of this click handler "this" refers to the element
that invoked the click event! The "event" can refer to this same
element via event.target
*/
console.log('this:%o', this)
$.ajax({
type: 'post',
url: './backend/adminAccess/deleteItem.php',
dataType: 'json',
data: { id:this.dataset.id },
cache: false,
dataType: 'json',
success: function(res) {
console.log(res);
},
error: function(err) {
console.warn(err);
}
})
}
document.querySelectorAll('.rmvElement > button').forEach( bttn => bttn.addEventListener('click', clickhandler ) );
.rmvElement .btn {
width: 150px;
padding: 0.5rem;
border: 1px solid black;
border-radius: 0.5rem;
margin: 0.25rem;
display: block;
text-align: center;
cursor: pointer
}
.rmvElement .btn:hover {
background: rgba(100, 0, 0, 0.25);
}
.rmvElement .btn:active {
background: rgba(100, 0, 0, 0.75);
color: white;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--
Rather than the `a` element which was used incorrectly
you can use a simple button
-->
<table >
<tr>
<td >
<button data-id=324>Delete</button>
</td>
</tr>
<tr>
<td >
<button data-id=185>Delete</button>
</td>
</tr>
<tr>
<td >
<button data-id=999>Delete</button>
</td>
</tr>
</table>