Make elements in a list clickable (PHP) - php

I'm currently developing a simple web page that enables the user to: upload an image and a corresponding caption to a DB, let the user view the images and delete them.
I have already accomplished the first two with the following code:
<?php
#include_once("connection.php");
$db = new mysqli("192.168.2.2", "root", "", "proyectoti");
if ($db->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
echo "Información de servidor: ";
echo $db->host_info . "\n";
// Initialize message variable
$msg = "";
// If upload button is clicked ...
if (isset($_POST['upload'])) {
// Get image name
$image = addslashes(file_get_contents($_FILES['image']['tmp_name'])); #$_FILES['image']['name'];
// Get text
$image_text = mysqli_real_escape_string($db, $_POST['image_text']);
$sql = "INSERT INTO images (image, image_text) VALUES ('{$image}', '{$image_text}')";
// execute query
mysqli_query($db, $sql);
}
$result = mysqli_query($db, "SELECT * FROM images");
?>
<!DOCTYPE html>
<html>
<head>
<title>Proyecto TI | Sube imágenes</title>
<style type="text/css">
#content{
width: 50%;
margin: 20px auto;
border: 1px solid #cbcbcb;
}
form{
width: 50%;
margin: 20px auto;
}
form div{
margin-top: 5px;
}
#img_div{
width: 80%;
padding: 5px;
margin: 15px auto;
border: 1px solid #cbcbcb;
}
#img_div:after{
content: "";
display: block;
clear: both;
}
img{
float: left;
margin: 5px;
width: 300px;
height: 140px;
}
</style>
</head>
<body>
<h1>Proyecto TI | <a> Interfaz </a></h1>
<div id="content">
<?php
while ($row = mysqli_fetch_array($result)) {
echo "<div id='img_div'>";
#echo "<img src='images/".$row['image']."' >";
echo '<img src="data:image/jpeg;base64,'.base64_encode( $row['image'] ).'"/>';
echo "<p>".$row['image_text']."</p>";
echo "</div>";
}
?>
<form method="POST" action="index.php" enctype="multipart/form-data">
<input type="hidden" name="size" value="1000000">
<div>
<input type="file" name="image">
</div>
<div>
<textarea
id="text"
cols="40"
rows="4"
name="image_text"
placeholder="Di algo de esta imagen ^^"></textarea>
</div>
<div>
<button type="submit" name="upload">Publicar</button>
</div>
</form>
</div>
</body>
</html>
It looks like this:
Now, the only part I'm missing is being able to delete an image (basically I only echo each image), how would you suggest for me to accomplish this, to make each item clickable and let's say, pop up a dialog or button to perform an action (delete from DB).
I really don't know much about PHP or CSS/HTML, any help would be much appreciated, Thank you!

Within this loop:
<?php
while ($row = mysqli_fetch_array($result)) {
echo "<div id='img_div'>";
#echo "<img src='images/".$row['image']."' >";
echo '<img src="data:image/jpeg;base64,'.base64_encode( $row['image'] ).'"/>';
echo "<p>".$row['image_text']."</p>";
echo "</div>";
}
?>
Personally I would add an element to click on - like an 'x' or whatever - with a unique data attribute:
https://www.abeautifulsite.net/working-with-html5-data-attributes
You have to add the unique id of the image obviously, so you can let SQL know which row to delete... Like this:
echo "<div class='delete-image' data-id='" . $row['id'] . "'>x</div>';
Then I would link this class to an AJAX call to make an asynchronous request to the server and delete the image without reloading the page. It's not very hard.
An easier solution would be to create a new form in the loop, so you create multiple forms per image, add a hidden field with the image id in the form and make a submit button with the valeu 'delete' or simply 'x'.
The same way you created the check:
if (isset($_POST['upload'])) { ... }
You can create something like this:
if (isset($_POST['delete-image'])) { ... }
You will be carrying the image id value like a normal form input. And you can do whatever you want with it.
I would HIGHLY suggest you to look into how to work with jquery and ajax calls though.

Opening a dialogue and ask the user before he deletes an item will require that you either go another page for deletion or use javascript for this.
In both cases, you should somehow set an identifier for your image in your html-code.
I would suggest you give every image an id
'<img ... id="'.$yourImageId.'">'
or a data-attribute
'<img ... data-identifier="'.$yourImageId.'" >'
with that identifier.
First variant:
...
echo '<a href="/path/to/delete/view/page.php?image=yourImageId">'
echo '<img ... id="'.$yourImageId.'"/>'
echo '</a>'
...
and on this delete-view-page, you just have a form that triggers your delete-code
<form action="/path/to/delete/view/page.php" method="POST">
<input type="hidden" name="id" value="<?php echo $yourImageId ?>">
</form>
<!-- after this, react with $_POST['id'] --> to the id sent to the server side and delete the image in your database -->
The other way is not server side rendered.
You should give your Elements some class like "my-clickable-image".After that, you have a script on your page, that looks something like the following
<script>
/* get your images with querySelectorAll, the . stands for class and after that your name */
var clickables = document.querySelectorAll(".my-clickable-image");
clickables.foreach(function(image){
// say that for each image, when clicked the generated function is called image.addEventListener('click',generateShowDialogueFunc(image.getAttr("id")));
});
// generate a function(!) that reacts to an image being clicked
function generateShowDialogueFunc(imageIdentifier){
// return a function that adds a Pop Up to the page
// the Pop Up has approximately the code of the first options second page
// except that now, it must create and remove elements in javascript
return function createPopUp(){
removePopUp();
var popup = document.createElement("div");
popup.setAttribute("id","deletePopUp");
var deleteForm = document.createElement("form");
deleteForm.setAttr("action","/path/to/file/that/deletes/given/query.php?id="+imageIdentifier);
var deleteContents = '<p> Do you want to delete this image? </p>'
+ '<button type="submit"> yes </button>'
+ '<button onclick="removePopUp()"> no </button>'
deleteForm.innerHTML = deleteContents;
document.body.appendChild()
}
}
// remove the Pop Up that can be used to delete an image from the page
function removePopUp(){
var existingPopUp = document.getElementById("deletePopUp");
if(existingPopUp) document.body.removeChild(existingPopUp);
}
</script>
<!-- just add some styling to make the popup show on top of the page -->
<style>
#deletePopUp{
width: 50vw;
height: 50vh;
position: absolute;
z-index: 1;
padding: 1em;
}
</style>
In this case, you just call the server to delete the image, not to show the delete form.
I would suggest the second one but stack overflow is not made for opinion based answers.
Regarding simple security:
It looks like your users could give titles or texts to images.
try what happens if a user gives a title like <bold>some title</title>
and guess what would happen if the title is <script>window.location.href="google.com"</script>
(XSS * hint hint *)
Regarding code structure:
If you want to do something like web development more often, think about separating your database accessing code, and your logic code from your php page template code, this is called 3 tier architecture and standard for bigger projects but i guess this is really just a first, short prototype or test.

Related

POST array of checkbox values

I'm making a website for my uni course so it's somewhat basic in a few places, but my current aim is to create an array of values based on checkboxes. This will become a basic basket/shopping cart so that the user can list the item's they want to take to the checkout.
I'm having trouble posting the values from my checkboxes though. I can only post one at a time, but what I intend to do is select multiple images at once and then add them in one go.
This is spread out over a few pages now and it's quite dynamic. Here are the relevant sections of code that I'm working with:
PhotographerAccount
(displays the gallery based on the photographer you are viewing)
<div class="container">
<!--Form to select items to put in "basket"-->
<form action="basket.php" method="POST">
<!--Gallery-->
<div style="margin-bottom:50; margin-top:50; height:600px; border:3px solid #adadad; border-radius: 10px; overflow-y: auto; overflow-x: hidden; background-color: #e0e0e0">
<?php include "personalGallery.php" ?>
</div>
<button type="submit" class="btn btn-block btn-info btn-lg">Add selected to basket (<small id="y">0</small>)</button>
</form>
</div>
personalGallery
(creates the gallery and the checkboxes)
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
$photoID = $row['uploadID'];
$photoNm = $row['photoName'];
//Photo styling
echo "<div class='col-sm-3 text-center' style='background-color:#e5e5e5; margin-bottom: 20px; border-width: 0 2 0 2; border-style: solid; border-color: #e0e0e0'>";
//Checkbox for form and Photo name as a label
echo "<div class='checkbox'>";
echo "<label><input onclick='updateCount()' class='z' type='checkbox' name='selection[]' value='".$photoID."'><strong>".$photoNm."</strong></label>";
echo "</div>";
//Photo
echo "<img src='photographersarea/PhotoUploads/".$photoID."' alt='".$photoNm."' style='height:200px;max-width: 100%'>";
//Close Styling
echo "</div>";
}
} else {
echo "0 results";
}
From here the form should be posting the data to basket.php, but when I test the array using print_r($_POST['selection'] or even print_r($_POST) I only see value. From the things I've read this should have made an array that I can work with.
Any ideas how I can post the data as an array?
Thanks!
(Will update post and make note of updates if needed)
UPDATES
- Fixed typo
use var_dump you will see keys as well or you can get key from array_keys()
Sorry to have wasted your time, turns out the code was fine, but the host was having some kind of problem!
Code above works fine now. Lets hope this doesn't happen again when I come to hand in the assignment!

How to return PHP within PHP - AJAX

Beginner to PHP, so I am pretty sure this is a stupid question...but, was hoping someone can help me out.
I have a html/php form, which basically dynamically pulls in values from a DB for a dropdown.
//HTML/PHP (original page)
<div style="position: relative; float: left; width:236px; margin-right: 20px;">
<div id="variablebox" style="position: relative; float: left; width:215px; border: solid #0096D6; border-width: 1px; padding: 10px;">
<H2>Step 2: Select Variable Type</H2>
<form id="var" enctype="multipart/form-data">
<span style="float: left; margin-top:8px;">
<label class="fieldlabel"><span>Variable Type:</span></label></br>
<select id="variabletype" name="variabletype" class="selectfieldshadow">
<option value="">Select</option>
<?php
$list=mysqli_query($con, 'SELECT * FROM valuelist');
while($row_list=mysqli_fetch_array($list)){
?>
<option value="<?php echo $row_list['valuelistid']; ?>">
<?php echo $row_list['valuename']; ?>
</option>
<?php
}
?>
</select>
</span>
When this form is submitted, it basically submits to PHP file via AJAX and then return the same form to the screen within the same DIV.
//PHP Page
echo "<H2>Step 2: Select Variable Type</H2>";
echo "<form id='var' enctype='multipart/form-data'>";
echo "<span style='float: left; margin-top:8px;'>";
echo "<label class='fieldlabel'><span>Variable Type:</span></label></br>";
echo "<select id='variabletype' name='variabletype' class='selectfieldshadow'>";
echo "<option value=''>Select</option>";
echo "<?php";
echo "$list=mysqli_query($con, 'SELECT * FROM valuelist');";
echo "while($row_list=mysqli_fetch_array($list)){";
echo "?>";
echo "<option value="<?php echo $row_list['valuelistid']; ?>">";
echo "<?php echo $row_list['valuename']; ?>";
echo "</select>";
echo "</span>";
echo "<span style='position: relative; float: left; display: inline-block; margin-top: 7px; font: 12px Lucida Grande,Helvetica,Arial,Verdana,sans-serif; padding-right: 60px;'>";
echo "<p>Add Value Control Screenshot:</p>";
echo "<input id='controlimage' type='file' name='controlimage'>";
echo "</span>";
I keep getting errors with my output...T_Variable this and Exception that...my question is, am I going about doing this correctly? I mean, looking at my PHP file that will return content back to the original page, do I have to echo php tags so they work on the original page when returned? ie. echo "<?php" etc..
Any assistance would be much appreciated!
echo is used to output content. As it's currently written, you're just trying to display the PHP code. To execute it, you'll have to restructure your code as follows:
<!-- some HTML code -->
<?php
// display stuff
?>
<!-- continue with HTML -->
Well first of all, PHP is all rendered server-side. So that means returning PHP in an AJAX response doesn't make sense. It won't render on the client side.
Second of all, those echos look crazy too. There are several different ways to output large text like that. Personally, I like to just close the PHP tag and write it. So your second file could look like this instead:
// end all PHP for now
?>
<H2>Step 2: Select Variable Type</H2>
<form id='var' enctype='multipart/form-data'>
<span style='float: left; margin-top:8px;'>
...
<input id='controlimage' type='file' name='controlimage'>
</span>
<?php
// continue writing PHP here
Send PHP is a nonsens cause PHP is a Server side language (run on server and not on the client, the browser).
Why don't you run your PHP code in this script and return the result. (Just display it)
But, please, make us proud of our favorite language and its beginners:
Use mysqli_fetch_assoc() instead of mysqli_fetch_array()
Use only one echo to do a multiline display, PHP natively supports it.
Indent your code, you will really like how it's more readable.
Use jQuery, its AJAX methods and autocomplete widget. Somebody did the job for you. ;-)

Turn MySQL results into link then redirecting to next page with POST

I am trying to turn my database results (users) into clickable links that will then display more information on the select user. Right now I am using $_GET, but the userID will be displayed in the address bar. Is there a way I can POST it instead?
Currently, I have:
//fetch and display the results in table
while ($row = mysqli_fetch_array($result, MYSQL_ASSOC)){
$name = $row["name"];
$id = $row["id"];
//prepare user for GET statement
echo ' <div>'.$row['name'].'</div> ';}
this displays: www.mylink.php?=id"12345"
I don't want to display the ID. So is the best approach to correct this this? Thanks
You have to create a form and a script to post your data. Something like this:
<?php
while ($row = mysqli_fetch_array($result, MYSQL_ASSOC)){
$name = $row["name"];
$id = $row["id"];
//prepare user for GET statement
echo "<div><a href=\"#\" onclick='javascript:postIt(".htmlspecialchars($row['id']).");'>".$row['name']."</a></div> ";
}
?>
<script>
function postIt(value){
document.forms[0].id.value = value;
document.forms[0].submit();
}
</script>
<form name="blah" action="mylink.php" method="post">
<input type="hidden" name="id">
</form>
You could replace all your hyperlinks with little forms:
<form action='mylink.php' method=post>
<input type=hidden value='$id'>
<input class='post_link' type=submit value='$name'>
</form>
CSS would help you to restyle buttons like links:
.post_link {
background-color: transparent;
border: none;
border-bottom: solid 1px blue;
color: blue;
display: inline;
height: ...;
etc
}
Open new tab will not work again, and you will see nothing is status bar on hover.

Assign unique ID to div as created and then reference with jquery

I am brand new to php and a beginner with jQuery. I have a php page that is populated with data from a mySQL table. What I am trying to achieve is for the h3 that contains "View Job" to have a unique id assigned to it, as well as the div that prints out the job description. Then, I would like to reference these with jQuery so that if someone clicks View Job, only the description for that job will show. I hope this makes sense.
I tried this with classes and of course all the job descriptions revealed themselves when any View Job was clicked.
I tried the solution here, but this ended up with 36 "View Job" links on my page, and I need to assign the unique ID to the h3 and div as they are created.
I am open to suggestions for another way to achieve what I'm looking for - basically to hide/collapse each description as the user clicks on View Job for each job.
here is my code:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<style type="text/css">
.job-post{border-bottom: 1px solid red; padding: 0; margin: 10px 0;}
h3, p{padding: 0; margin:0;}
.view-job{cursor: pointer;}
</style>
<script type="text/javascript">
$(document).ready(function() {
$("div#job-details").css("display" , "none");
$("h3#view-job").click(function() {
$("div#job-details").css("display" , "block");
});
});
</script>
<?php
// Connects to your Database
mysql_connect("xx", "xx", "xx") or die(mysql_error());
mysql_select_db("lcwebsignups") or die(mysql_error());
$data = mysql_query("SELECT * FROM openjobs")
or die(mysql_error());
?>
<div id="job-container">
<?php
Print "";
while($info = mysql_fetch_array( $data ))
{
Print "<div class='job-post'>";
Print "<h3>Position / Location:</h3> <p>".$info['jobtitle'] . ", ".$info['joblocation'] . "</p>";
Print "<h3 id='view-job'>View Job:</h3> <div id='job-details'>".$info['jobdesc'] . " </div>";
Print "</div>";
}
?>
</div><!--//END job-container-->
Assign the classNames instead of id's
Then use the this context to select your div which will only search for the one in the context and not all the divs
$("h3.view-job").on('click',function() {
$(this).next("div.job-details").css("display" , "block");
});
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<style type="text/css">
.job-details{display:none;}
.job-post{border-bottom: 1px solid red; padding: 0; margin: 10px 0;}
h3, p{padding: 0; margin:0;}
.view-job{cursor: pointer;}
</style>
<script type="text/javascript">
$(document).ready(function() {
// Please hide this class on CSS
// $("div.job-details").css("display" , "none");
$("h3.view-job").click(function() {
// you ned to use this keyword
// it is very important when you use javascript or jquery
// this keyword only pick element on which you click
$(this).parent().find(".job-details").show();
});
});
</script>
<?php
// Connects to your Database
mysql_connect("xx", "xx", "xx") or die(mysql_error());
mysql_select_db("lcwebsignups") or die(mysql_error());
$data = mysql_query("SELECT * FROM openjobs")
or die(mysql_error());
?>
<div id="job-container">
<?php
// First of all Please use echo instead of Print
echo "";
while($info = mysql_fetch_array( $data ))
{
echo "<div class='job-post'>";
echo "<h3>Position / Location:</h3> <p>".$info['jobtitle'] . ", ".$info['joblocation'] . "</p>";
// you can't use id multiple time in a same page so instead of id use Class
// if you want to use id then you have to generate uniq id
// check below I generate id --> I don't know your database field that's why I used jobId
echo "<h3 class='view-job' id='job".$info['jobId']."'>View Job:</h3> <div class='job-details'>".$info['jobdesc'] . " </div>";
echo "</div>";
}
?>
</div><!--//END job-container-->
This should do what you want (tested okay). Just replace your mysql login info and the example should work.
I completed your job-details div (it was missing the data from php), but what you were really looking for is the jQuery code.
When an <h3> tag whose id begins with the characters view-job is clicked, the jQuery click event handler will:
re-hide all divs whose id starts with the chars job-details
display the next div in the DOM tree
CODE:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<style type="text/css">
.job-post{border-bottom: 1px solid red; padding: 0; margin: 10px 0;}
h3, p{padding: 0; margin:0;}
.view-job{cursor: pointer;}
</style>
<script type="text/javascript">
$(document).ready(function() {
$("div[id^='job-details']").css("display" , "none");
$('h3[id^="view-job"]').click(function() {
$("div[id^='job-details']").hide(500);
$(this).next('div').show(500);
});
});
</script>
<?php
// Connects to your Database
mysql_connect("xx", "xx", "xx") or die(mysql_error());
mysql_select_db("lcwebsignups") or die(mysql_error());
$data = mysql_query("SELECT * FROM openjobs") or die(mysql_error());
$data = mysql_query("SELECT * FROM openjobs") or die(mysql_error());
?>
<div id="job-container">
<?php
echo "<br>";
while($info = mysql_fetch_assoc( $data )) {
echo "<div class='job-post'>";
echo "<h3>Position / Location:</h3> <p>".$info['jobtitle'] . ", ".$info['joblocation'] . "</p>";
echo "<h3>View Job:</h3> <div id='job-details'>".$info['jobdetails']."</div>";
echo "</div>";
}
?>
</div><!--//END job-container-->

Ajax, PHP, MySQL retrieve data

i'm trying to auto retrieve data from mysql server in specific DIV without manual refresh the web page.
My PHP code is:
function lastCodes(){
include('mysql.php');
include('config.php');
echo "<div id='content_data'>";
$get = mysql_query("SELECT * FROM scripts ORDER by date_added DESC");
if(mysql_num_rows($get)>0){
while($row = mysql_fetch_assoc($get)){
$get2 = mysql_query("SELECT * FROM accounts WHERE username = '$row[s_owner]'");
while($red = mysql_fetch_assoc($get2)){
echo "<table>
<tr>
<td width='22px'>";
if(!empty($red['avatar'])){
echo "<center>
<img src='$red[avatar]' style='width: 52px; height: 52px; margin-left: -30px; border: 2px solid #fff;' title='$row[s_owner]'/>
</center>
</td>";
} else {
echo "<td width='22px'>
<center>
<img src='/theme/$tema/icons/empty_avatar.png' style='width: 52px; height: 52px;' title='$row[s_owner]'/>
</center>
</td>";
}
echo "<td>
<a style='font-family: IndexName; color: #000; font-size: 14px; margin-left: 5px;'><b>$row[s_owner]</b> написа <a title='$row[s_name], Категория: $row[s_category].' href='#' style='text-decoration: none;'>нов код</a> <a style='font-family: IndexName; color: #000; font-size: 14px; margin-right: 10px;'>в $row[date_added]</a>
</td>
</tr>
</table>";
}
}
}
echo "</div>";
}
What should be in my case the jquery/ajax code if I want to retrieve this information in DIV called "content_data" in interval of 5 seconds? Thanks a lot!
You could place the contents of your lastCodes() function inside an otherwise empty PHP file, let's call it lastCodes.php.
And then use the load function from JQuery on the page where you want to retrieve the data
<div id="divTarget"></div>
<script type="text/javascript">
$("#divTarget").load("lastCodes.php");
</script>
But keep in mind that this way of coding can get messy real fast. I would recommend you to try any of the many great template systems available. It's not necessary for clean code but without one you will need some discipline keeping logic out of your view code.
And when you feel comfortable with one of those you could go even further and try a template system on the frontend using Javascript, for example Handlebars. With one of those you will be able to write clean code and send your data using JSON which will lower the size of the HTTP response and at the same time make the data more usable for other scenarios than simply rendering it as HTML.
Edit: To update the data every 5 seconds:
<script type="text/javascript">
window.setInterval(function() {
$("#divTarget").load("lastCodes.php");
}, 5000);
</script>
You just have to use the setInterval() function to load the contents of the page every 5 seconds(5000 milliseconds)
</div>
<script src="jquery.js"></script>
<script>
setInterval(function(){
$('#container').load('page.php');
}, 5000);
</script>
I can see that you have a function so you might as well call it. If that doesn't work then try to put your code outside of the function.
lastCodes();
Be sure that its actually changing its contents and that the page that you're calling actually works, you can test it by accessing the page itself and see if it has any output.

Categories