Remove array of items from session shopping cart - php

I have an array of items kept in session cart. It gets populated in a table. each row has an index and a button to remove this particular item(items array) from $_SESSION['cart']..
This is the code I have at the moment:
$i = 0;
foreach($_SESSION['cart'] as $item)
{
//Populate items in a table ?>
<tr>
<td><center><?php echo $i; ?></center></td>
<td><center><?php echo $item['item'];?></center></td>
<td><center><?php echo '£'. $item['unitprice'];?></center></td>
<td><center><?php echo $item['quantity'];?></center></td>
<td><center><?php echo '£'.($item['unitprice'] * $item['quantity']) ?></center></td>
<td><input type="submit" value="Remove" Onclick = unset($_SESSION['cart'][$i]); ></td>
</tr>
<?php
$total += ($item['unitprice'] * $item['quantity']);
$i++;
}
All I want to do is to remove one single row of data (each row contains index, item, item price, total(if there are more than one item) and remove button) from session cart. Thanks in advance..

The unset is correct, but PHP is executed on the servers side. So because this is a client action, you'll need to use JavaScript to pick up the action. (you could also use an old fasion form as well). I prefer to use jQuery since it allready has the built in ajax support and makes it easy. Basically, just call a function from the onClick that passes the "ID" of the element you want to delete. Then that function will make an AJAX call to another script that will take that ID and remove the element. When that script returns a success, have JavaScript delete (or hide) the element. This way the user never leaves or refreshes the page, and the script can do some extra cleanup (like database updates, session updates, validate request, etc.)
i = 0;
foreach($_SESSION['cart'] as $item)
{
//Populate items in a table ?>
<tr>
<td><center><?php echo $i; ?></center></td>
<td><center><?php echo $item['item'];?></center></td>
<td><center><?php echo '£'. $item['unitprice'];?></center></td>
<td><center><?php echo $item['quantity'];?></center></td>
<td><center><?php echo '£'.($item['unitprice'] * $item['quantity']) ?></center></td>
<td><input type="submit" value="Remove" onClick="RemoveItem(<?= $i ?>)" ></td>
</tr>
<?php
$total += ($item['unitprice'] * $item['quantity']);
$i++;
}
Here I've changed the onClick section to use a javascript call instead. You'll notice I used the <?= tag instead of a full <?php echo. This is because as of php5 you can use the shorthand <?= to echo an expression.
In your script section you can do something like this. I use POST since it's more secure.
function RemoveItem(id) {
$.post('script-to-remove.php',
{ ItemID: id },
function(data) {
if(data==='success') {
//Remove item from DOM
} else alert("There was an error!"); //If you want error handling
}
);
}
For removing items from the dom, its a bit trickier with tables since none of the cool effects will really work, such as fadeOut, slideUp, animate, etc. I would look into reformatting it with divs.
As for the php script it calls, its as simple as calling the unset. You can develop it more, so as to possibly check the validity of the request, but for now, I'm just going to do the unset.
<?php
$ItemID = isset($_POST['ItemID'])?intval($_POST['ItemID']):-1;
if($ItemID<0) die("Invalid ID"); //Change this if you want
if(isset($_SESSION['cart'][$ItemID])) unset($_SESSION['cart'][$ItemID]);
echo 'success';
?>
Basically in this, I first check that the right parameter came in, make sure it's an integer and save it, otherwise I default it to -1. Then if the Item ID is under 0 (so definatly wrong) I tell the script to output the message and quit. Finally I check that there is a value for that ID or index as it really is, and unset it. If it makes it to the end, output the success.

Related

Getting id from a textarea in a while loop in PHP for updating in mysql

I have a table where is one week displayed (each row is one day).
I get the rows from a while loop from my database. The rows are displayed in bootstrap accordions.
There is a textarea in every accordion row where the user can input (update) some text.
I want to update this text into my database. It should update the text depending on the day id.
<form method="POST" action="">
<table class="table table-hover" style="border-collapse:collapse;">
<thead>
<tr>
<th>Weekday</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<?php
// Select Statement (for shortening not included into this Stack question)//
while($row = $statement->fetch()) {
$thedate = $row['Date'];
$weekday=strftime("%A", strtotime($thedate));
$date=date('d-m-Y', strtotime($thedate));
echo "<tr data-toggle='collapse' data-target=#".$row['Date']." class='clickable collapse-row collapsed'>";
echo "<td >".$weekday."</td>";
echo "<td>".$date."</td>";
echo" <td style='color:black; font-size:20px;'><i class='fas fa-angle-down'></i></td>";
echo "</tr>";
echo "<tr><div class='accordian-body collapse' id=".$row['Date'].">
<td colspan='1' class='hiddenRow'><textarea name=".$row['id']." rows='5' cols='80'>".$row['Text']." </textarea></td>
//the $row['id'] should give every textarea a unique dayid from my database
echo"</td>
</div></tr>";
}
if(ISSET($_POST['id'])){
$debug=$_POST['id'];
}
var_dump($debug); // var_dump for debugging. See text below
?>
</tbody>
</table>
<button type="submit" name="Speichern" class="btn btn-lg btn-primary btn-block">Speichern</button>
</form>
Before writing the Sql Update Statement I wanted to debug to find possible bugs.
If i debug this with var_dump I get the error message "Undefined variable $debug" and I dont know why. The variable shouldnt be empty because in the textareas is always text.
Im new to PHP and coding at all so probably Im making a dump mistake.
EDIT: If I put the var_dump inside the if condition i get nothing as return.
I tried it also with the var_dump in the if block but then i get nothing as return.
That’s because you do not have any form field that is actually named id. You put name=".$row['id']." on your textarea, and that is likely a numeric value. And you probably don’t know which one that will be, on the receiving end.
Plus, since you are creating multiple such fields in a loop, PHP will overwrite all values for this parameter with the last one. You need to use a naming scheme that includes square brackets to avoid that, something like name="foo[]" - then $_POST['foo'] will become an array that you can loop over.
And since you will still need your record ID to associate with the data, you can put that into the brackets, name="foo[123]" – then this 123 will become the key of that array element, for this specific textarea.
If you loop over that using the extended foreach syntax, then you have easy access to the ID, and the value entered by the user:
foreach( $_POST['foo'] as $id => $value ) { … }

CakePHP: Create array of checkboxes and update field based on whether it's set

I'm not sure if what I'm asking for is possible, but here's the scenario:
I have a foreach() loop that returns some values in HTML format:
<?php foreach($stuff as $s) { ?>
<tr>
<td><?php echo $s['Model']['data']; ?> </td>
</tr>
<?php } ?>
What I need to do is put a checkbox next to each $s['Model']['data'], preferably with $s['Model']['data'] as the label, and be able to set a value in a table based on whether the box is checked. So, my edit.ctp would look like this:
<?php foreach($stuff as $s) { ?>
<tr>
<td><?php echo $this->Form->input('flag', array('type'=>'checkbox, 'default'=>'', label=>' $s['Model']['data']', 'value'=>1 )); ?> </td>
</tr>
<?php } ?>
I have no trouble displaying the above. My problem is that I don't know how to tell my controller to update the necessary field if the labeled box is checked. Here's my first run at it:
if($this->request->save($this->request->data)) {
foreach($stuff as $s) {
$this->Model->id = $s['Model']['id'];
if(isset($this->request->data['FormName']['flag'])) {
$this->Model->set('flag', 1);
$this->Model->save('flag', true);
}
}
}
No errors at runtime, but nothing happens. The flag field in the Model I need to update remains = 0. I can debug $stuff and see data, so I know it's there. I also know that my edit function is hitting the foreach() loop. What might I be missing? Do I need to assign the checkbox a different value or check for whether it's set some other way?
It seems like you need to identify each checkbox to the current item by modifying the name of each checkbox, otherwise it will just use the value of the last checkbox for all the items.
<?php foreach($stuff as $i => $s) { ?>
<tr>
<td><?php echo $this->Form->input('flag'.$i, array('type'=>'checkbox, 'default'=>'', label=>' $s['Model']['data']', 'value'=>1 )); ?> </td>
</tr>
<?php } ?>
Then in the controller look for that specific flag
if($this->request->save($this->request->data)) {
foreach($stuff as $i => $s) {
$this->Model->id = $s['Model']['id'];
if(isset($this->request->data['FormName']['flag'.$i])) {
$this->Model->set('flag', 1);
$this->Model->save('flag', true);
}
}
}
Which assumes that ht elements in $stuff are always in the same order.

Get the dynamically generated name from the form into the $_POST

I'm currently working on a personal content management system project, but I've run into a problem.
<ul>
<?php
if(!$result) { //Check for result
die("You have no pages &#9785 Why not create one?");
} else {
while ($pages = mysqli_fetch_assoc($result)) { //Loop through results
?>
<li class="triple"><span><?php echo $pages["title"]?></span><span><?php echo $pages["visible"] ?><span /><form action = "editPage.php" method="post"><input type="submit" value="Edit Page" name="<?php $pages["title"];?>" /></form></li> //Create li elements for each result that gets created
<?php
};
};
?>
</ul>
Basically I'm using a query to results from a MySQL table and make a list of pages, the problem I've run into is that on the end form what I want to happen is I want a session variable to be stored saying which page is going to be edited, but I can't use $_POST in the form at the end to get the name because obviously the name is automatically generated from the table. Each person who uses it would have a different name for a page so I can't just get one name e.g. $_POST['homepage'].
If anyone can offer any advice on how to solve my problem or even how to come up with a better solution to store which page will be edited as it goes onto another page (editPage.php) that would be great.
Use $_SESSION[] to store the data for your $page arrays and access it again on editPage.php. You will need to make sure you call start_session(); on both pages though for it to work as expected. Since you're creating multiple forms and don't know which one will be submitted at the time PHP is running you would need to store all the pages in your $_SESSION and then iterate through them to check for the one which was selected in editPage.php:
$_SESSION['pages'] = array();
while ($page = mysqli_fetch_assoc($result)) {
$_SESSION['pages'][] = $page;
echo "<li class=\"triple\">
<span>".$page["title"]."</span>
<span>".$page["visible"]."</span>
<form action=\"editPage.php\" method=\"post\">
<input type=\"hidden\" name=\"pageID\" value=\"".$page['id']."\">
<input type=\"submit\" value=\"Edit Page\">
</form>
</li>";
}
Then in editPage.php
foreach($_SESSION['pages'] as $page){
if($page['id'] == $_POST['pageID']){ $editpage = $page; break; }
}
// do stuff with $editpage data
Another option would be to use serialize($page) and send the array with the form data in a hidden input element.
<input type='hidden' name='data' value='<?php echo serialize($page); ?>'>
Then you can use $editpage = unserialize($_POST['data']); to turn it back into an array in editPage.php.

PHP Unset Specific Session by click

How to unset specific session in my code below:
for($i=0;$i<count($_SESSION['src']);$i++)
{
?>
<tr>
<td><?php echo $_SESSION['name'][$i]; ?></td>
<td><?php echo $_SESSION['price'][$i]; ?></td>
<td>Hapus</td>
</tr>
<?php
}
if($_GET['delPrd']);
{
unset($_SESSION['name']);
unset($_SESSION['price']);
}
Example I have 3 data with each session id. Now I want to unset session by click each delete link.
How can I do that? So I click delete then it will hide the row that I clicked before in <tr>
I came across the same issue when using the unset(), I tried to debug it to see if it would ever unset using a simple while loop.
while(isset($_SESSION['...'])):
unset($_SESSION['...']);
endwhile;
This seems to work for me and actually unset the cache, it's like it needs to know its unset before continuing which makes no logical sense but that's code for you - you spend 50% of your time trying to fix code, the only 50% wondering how the hell it worked.
Hope this helped.
EDIT: You could make this into a reusable object, something like:
class SessionRemovale
{
public function Remove($param)
{
while(isset($_SESSION[$param])) {
unset($_SESSION[$param]);
}
}
}
Then use it like:
$session_controller = new SessionRemovale();
$session_controller->Remove("....");
$session_controller->Remove("....");

Ajax - PHP auto refresh looped data without relooping everything

From the looped data I'd like to auto refresh only the data retrieved from the database, and not the whole layout. Currently I re-loop the complete layout but that seems somewhat clumsy (this table is a simplified example). Some direction or advice is appreciated!
<?
//.. rawdata.php ..//
while($row = mysql_fetch_array($result)) {
//building table by looping
?>
<tr>
<td><? echo $row['uniqueid']; ?></td>
<td><? echo $row['firstname']; ?></td>
<td><? echo $row['surname']; ?></td>
</tr>
<?
}
?>
<!-- index.php -->
<script type="text/javascript">
var auto_refresh = setInterval(function() {
$('#loadRawData').load('rawdata.php');
}, 5000);
</script>
<!--...-->
<div id="loadRawData"></div>
If you only update or add records, you could add a “version” column to your table. Each time you update a row, or insert a new row, you increment the version and add it to the row.
You transmit the version to the client (it's a MAX on the version column). When the client does its “refresh” request, it sends you the version it had last downloaded, and you simply send the rows that verify a condition such as WHERE version > clientVersion.
It will be trickier if rows may be deleted, because in that case you will need to keep track of deleted rows in the table, in order to forward the “delete” operations to the clients. But you can manage them with the same “version” mechanism.

Categories