can someone tell me how to create a nice small tooltip like ajax pop-up ?
the situation is like this,
I am pulling the $row->title from the db, and then I presented it as a link like this
<?php foreach($task->result() as $row): ?>
<tr>
<td><a href=#><?php echo $row->title; ?></a></td>
</tr>
<?php endforeach; ?>
when a random user clicks that link, I want it to produce a small pop-up or tooltip like stuff that contains the title's description $row->description , and when user moves mouse from it,it closes. i know its possible, but i just don't know how to do it.
You need jQuery. Add stylesheet into <head></head> and javascript to any place in your page.
Sample style:
<style type="text/css">
.description {
visible: hidden;
position: absolute;
left: 0px;
top: 0px;
/* View */
font-family: Arial,Tahoma,Verdana;
font-size: 8pt;
color: #bbb;
background-color: #444;
padding: 5px 7px;
border: 1px solid #222;
}
</style>
Javascript:
<script type="text/javascript" src="path/to/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Add listener to links
$(".some_class").click(function(e) {
var description = $('<div class="description">'+ $(this).attr("description") +'</div>');
$(this).append(description);
description.css("left", e.pageX-4);
description.css("top", e.pageY-4);
description.animate({ opacity: 'toggle' }, 400, 'linear');
// Remove description, if user moved the mouse cursor out description
description.mouseout(function() {
$(this).remove();
});
return false;
});
});
</script>
Change your code:
<?php foreach($task->result() as $row): ?>
<tr>
<td><?php echo $row->title; ?></td>
</tr>
<?php endforeach; ?>
But the better way is to check out some good jQuery plugin..
Check out this jQuery plugin: http://www.w3avenue.com/2010/01/11/coda-bubble-jquery-plugin/
something like the following?
AJAX to get the description and when you're received the response create the description 'box'
var tipel = document.createElement('div');
tipel.innerHTML = descr;`
add it to the page
var bodyel = document.getElementsByTagName('body').item(0);
bodyel.appendChild(tipel);`
and position it like:
tipel.style.position = "absolute";
tipel.style.top = newfntogetabsolutecoord_top(document.getElementById("mytitleelement"));
tipel.style.left = newfntogetabsolutecoord_left(document.getElementById("mytitleelement"));`
getting absolute coords of an element can be tricky, look for a fn online.
for closing the tip, a suggestion would be placing tipel just under the mouse pointer (you already know it's over the link "mytitleelement", just shift the tip a little in the lines above), and then add an onmouseout event function to tipel that:
tipel.style.display = "none"; //hides or
tipel.parentNode.removeChild(tipel); //removes it from the page
(you might get away with using this instead of tipel in those 2 lines)
Related
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.
I am populating a <DIV id='area'> element using a PHP script and I want to repopulate the same DIV element by calling a PHP function in JavaScript if the user wishes to filter the information:
$("#area").load("update-dashboard.php?id=7263");
It populates the DIV element with the correct information but the CSS styling I'm using to format the information (eg. class="highlight") doesn't get applied for some reason. So what I get reads correctly if I view the underlying HTML but the browser doesn't format it according to the stylesheet.
<style type="text/css">
.Highlight {
background-color: #dcfac9;
cursor: pointer;
}
td.highcell {
padding-top: 8px;
padding-bottom: 8px;
}
</style>
Here's what my table should contain within the DIV section:
<table style='border-collapse: collapse;' border=0 width='100%' id='link-table'>
<tr class='highlight'>
<td class='highcell'>
NK51 SNR55
</td>
<td class='highcell' width=36>
<img src='status_2.png' border=0 width=32 height=32><td class='highcell'>18-Dec-15</td>
<td class='highcell'>NK51 SNR55</td>
<td class='highcell'></td>
<td class='highcell'></td>
</tr>
ADDITIONAL INFO:
I also use this jQuery code to highlight the rows in the Table - maybe it doesn't work with HTML loaded after the page appears - if so can it be reinitialised?
$(function ()
{
$('#link-table td:first-child').hide();
$('#link-table tr').hover(function ()
{
$(this).toggleClass('highlight');
});
$('#link-table tr').click(function ()
{
location.href = $(this).find('td a').attr('href');
});
});
Try changing your css from .Highlight to .highlight. CSS selectors are case-insensitive but the HTML class attributes are not.
i need help saving this, i can swap images but not save them. i am thinking maybe an update button to store the images. or maybe auto save when changes are made. someone mentioned cookies or something. i am not familiar with cookies and would like an easier solution.
actual page will have around 100 images and do need save function for permanently keeping changes.
hoping someone can figure this out, been at this for hours to just get this far
thanks ahead of time for just looking at this
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Swap demo</title>
<style type="text/css">
#GALLERY td {
height: 200px; width: 200px;
text-align: center;
vertical-align: middle;
}
#GALLERY td img, #GALLERY td img.normal {
border: solid white 5px;
}
#GALLERY td img.highlighted {
border: solid red 5px;
}
</style>
</head>
<body>
<table id="GALLERY">
<tr>
<td>
<img src="http://www.clearviewarts.com/thumbnails/Puppy In Basket.jpg" alt="Dogs"/>
</td>
<td>
<img src="http://www.clearviewarts.com/thumbnails/BabyIndy.jpg" alt="Dogs"/>
</td>
<td>
<img src="http://www.clearviewarts.com/thumbnails/HarlequinDane.jpg" alt="Dogs"/>
</td>
</tr>
<tr>
<td>
<img src="http://www.clearviewarts.com/thumbnails/Pug.jpg" alt="Dogs"/>
</td>
<td>
<img src="http://www.clearviewarts.com/thumbnails/Wagner-edit1.jpg" alt="Dogs"/>
</td>
<td>
<img src="http://www.clearviewarts.com/thumbnails/CanusAngelicus.jpg" alt="Dogs"/>
</td>
</tr>
</table>
<script type="text/javascript">
var pix = document.getElementById("GALLERY").getElementsByTagName("img");
for ( var p = 0; p < pix.length; ++p )
{
pix[p].onclick = picclick;
}
var firstImage = null;
function picclick( )
{
// to cancel a swap, click on first image again:
if ( firstImage == this )
{
this.className = "normal";
firstImage = null;
return;
}
// is this first image clicked on?
if ( firstImage == null )
{
// yes
firstImage = this;
this.className = "highlighted";
return; // nothing more to do
}
// aha! second image clicked on, so do swap
firstImage.className = "normal";
var temp = this.src;
this.src = firstImage.src;
firstImage.src = temp;
firstImage = null;
}
</script>
</body>
</html>
This is what I would do (I hope this helps).
Build an array of the image names in JS (on the server).
Render the HTML according to the array (via JS).
If the user does an image swap, alter the array, and re-render.
The rendering shouldn't need to pull any data from the server so won't flicker.
The onclick event should tell the update function which image is being changed.
If you want to save the display order, POST the current array back to the server.
If that sounds too complex, look at these
http://inspiretrends.com/free-jquery-carousel-plugins/
http://webdesigntunes.com/freebies/30-amazing-free-jquery-slider-and-carousel-plugins-of-2013/
Look at http://owenberesford.me.uk/17690427/sample.html
but pls know that:
for "real" code, i generally start with a testcase...
this works on FF and Opera (both Linux), not tested on anything MSIE.
to allow maximum freedom no framework has been used.
everything is run on the client, so you can just view/ save.
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.
i have a big problem , im trying to build a website around the one page template system so hear is how it works..... a user clicks a link: ..... but the problem is i have more then 100 php generated links on one page that is attached to a listener and for some strange reason, every time a link gets clicked, and a user returns back to the main page it doubles the request....
in other words : a user click links.... go to a page ..... and he see's a ton of links.... the user clicks a link..... go to a page. but if a user goes back the ajax call doubles????
ex. 1 post , ... 2 post ..... 4 post.... 8 post ..... 16 post..... 32 post ...... 64 post.....
im trying to debug with chrome, and it shows how many post to the network(HTTP Request) that are made every time one has been called and it shows how many post being made and its doubling
Html Markup :
<script>
// main menu
$('header a').addClass('lvl1Links');
// classifeds
$('#9090 a').addClass('lvl1Links');
//states - citys - cats ads
$('#selectable a').addClass('lvl1Links');
// re-install link management
$(function(){
$('.lvl1Links').click(function(event) {
event.preventDefault();
$('pload').html('<img src="source/image/lbl.gif">');
var page = $(this).attr('id');
var huh = $('input:hidden').val();
var data = 'pop='+huh+'&page='+page;
$.post('source/php/bots/authorize.php',data,function(data){
$('#pager_master_div').html(data).slideDown();
$('pload').html('');
});
});
});
// speacial style on certain input boxes
$('input').addClass('input');
$('#op').removeClass('input');
$('#sp').removeClass('input');
$('button').button();
//$("#BUser_Home_Wrapper a .lvl1Links").removeClass("lvl1Links");
</script><div id="9090"><ol id="selectable"><li class="ui-state-default">
<div class="contr">Alabama</div><div class="citys">Birmingham<br>Montgomery<br>Mobile<br>Huntsville<br>Tuscaloosa<br><li class="ui-state-default">
<div class="contr">Alaska</div><div class="citys">Anchorage<br>Juneau<br>Fairbanks<br>Sitka<br>Ketchikan<br></ol></div><style>
.contr{
}
.citys{
display:none;
position:absolute;
height:110px;
width:100px;
top:30px;
left:-5%;
right:-5%;
z-index:100;
background:#FFF;
border-radius:5px;
border:5px #0099FF solid;
font-size:10px;
}
.cityz{
display:none;
position:absolute;
height:200;
width:100px;
top:-100px;
left:-5%;
right:-5%;
z-index:100;
background:#FFF;
border-radius:5px;
border:5px #0099FF solid;
font-size:10px;
}
.citys a{
font-size:15px;
}
.cityz a{
font-size:15px;
}
#selectable li a{
font-size:14px;
}
#selectable li city a{
}
#selectable {
list-style-type: none; margin: 0; padding: 0;
}
#selectable li {
margin:5px;
position:relative;
border-radius:10px;
padding: 1px;
float:left;
width: 100px;
height: 25px;
text-align: center;
}
</style>
<script>
$('.ui-state-default').mouseenter(function(e) {
$('.citys', this).slideDown(); // added this
}).mouseleave(function(e) {
$('.citys', this).toggle(); // added this
});
// bttom rows
$('.ui-state-default').mouseenter(function(e) {
$('.cityz', this).slideDown(); // added this
}).mouseleave(function(e) {
$('.cityz', this).toggle(); // added this
});
</script>
<results></results><input type="hidden" id="fortknox" name="fortknox" value="c4ca4238a0b923820dcc509a6f75849b"><results></results><input type="hidden" id="fortknox" name="fortknox" value="c4ca4238a0b923820dcc509a6f75849b">
<script>
$('input').addClass('input');
$('button').button();
// click event for all links
$(function(){
$('.lvl1Links').click(function(event) {
event.preventDefault();
$('pload').html('<img src="source/image/lbl.gif">');
var page = $(this).attr('id');
var huh = $('input:hidden').val();
var data = 'pop='+huh+'&page='+page;
$.post('source/php/bots/authorize.php',data,function(data){
$('#pager_master_div').html(data).slideDown();
$('pload').html('');
});
});
});
</script>
php code:
<?
case 'class':
require('functions/cats.php');
classie($p);
break;
function classie($p){
connect();
$state = explode(':',$p[2]);
$total = count($state);
$s = md5('?').'.class.';
$sid = $state[1];
$state = $state[0];
echo "$state";
echo "<ol id=\"selectable\">";
if(isset($p[3])){
$city = explode(':',$p[3]);
$cid = $city[1];
$city = $city[0];
echo " : $city";
$sqlca = mysql_query("SELECT * FROM `cats` WHERE `cityId`= ".$cid." ");
while($rowsy = mysql_fetch_array($sqlca)){
echo " : ".$rowsy['name']."";
}
}
?>
you can solve your problem using unbind click to prevent double clicking and causing
multiple entry. Take a look my revision about your code on JS below:
$(function(){
$('.lvl1Links').bind(''click,function(event) {
event.preventDefault();
$('pload').html('<img src="source/image/lbl.gif">');
var page = $(this).attr('id');
var huh = $('input:hidden').val();
var data = 'pop='+huh+'&page='+page;
$.post('source/php/bots/authorize.php',data,function(data){
$('#pager_master_div').html(data).slideDown();
$('pload').html('');
});
$(this).unbind(event);
});
});