The question is that how do i check if a link has been clicked?
+
+
(another document)
<?php
session_start();
$_SESSION['car'] = $_SESSION['car'] + 1;
$_SESSION['boat'] = $_SESSION['boat'] + 1;
header("Location: betalning.php");
?>
The first a tag add a car to the cart and the second a tag add a boat to the cart. How do i detect which one of the a tag that has been clicked, and if i now click on any of the a tags both a car and a boat will be added to the cart.
You can add GET parameters to the links:
Add car
And then in your PHP document:
if($_GET['add'] == 'car'){
$_SESSION['car'] += 1;
}
// etc...
This is basically the easiest way to pass data from one page to another using a link.
The concept that you should use. is Ajax.
Every click and others things with the browser only happens on the client ( browser ).
Then when you do click. The browser has send request to server.
The server, get values that you send from browser and it proccess.
Some simple may be:
// Html
<a id="linkone" href="laggtill.php">+</a>
<a id="linktwo" href="laggtill.php">+</a>
//Javascript
// Use jquery
$("#linkone").on("click", function(){
//function that send request to server
$.post('someurl.php', {})
.success(function(res){
console.log(res);
// If you stay here, the procces should be ended
})
// if you return false, the click dont redirect other window
// if you return true, the click redirect other window
return false;
});
// php file for first link
<?php
//capture values
// But only is a clic, then there is not values
session_start();
$_SESSION['car'] = $_SESSION['car'] + 1;
// If you want some simple, one file only works for one link
// For the other link, you should create other file same to this.
header("Location: betalning.php"); // With ajax dont use this line,
?>
Related
I've got a basic like button concept on my site that visits url.tld?action=love and adds +1 to the link's database column.
It's a hassle redirecting to another page all the time though. Is it possible to click the button, and send a request to the URL without actually redirecting to a new URL? Also maybe refresh the button afterwards only so that the count updates?
For a general idea of what my download button is this is in the header:
<?php require_once('phpcount.php'); ?>
<p class="hidden"><?php
$time = time();
for($i = 0; $i < 1; $i++)
{
PHPCount::AddHit("$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]", "127.0.0.1");
}
echo (time() - $time);
/*echo "PAGE1 NON: " . PHPCount::GetHits("page1") . "\nPAGE1 UNIQUE: " . PHPCount::GetHits("page1", true);
echo "\n\n" . PHPCount::GetHits("page2");
$ntot = PHPCount::GetTotalHits();
$utot = PHPcount::GetTotalHits(true);
echo "###$ntot!!!!$utot";*/?></p>
And this is an example of my "love" button.
Love <span class="count">'. PHPCount::GetHits("$package_get?action=love", true).'</span>
The reason I used this method is because people create pages, and I wanted the like button to work out of the box. When their page is first visited it adds their url to the database, and begins tallying unique hits.
This is basically adding a new link column called downloadlink?action=love, and tallying unique clicks.
use the following code. assgin id="btn_my_love" to that button and add this code to you page
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
//assign url to a variable
var my_url = <?php echo "https://alt.epicmc.us/download.php?link='.strip_tags($package_get).'?action=love"; ?>;
$(function(){
$("#btn_my_love").click(function(){
$.ajax({
url:my_url,
type:'GET',
success:function(data){
//comment the following result after testing
alert("Page visited");
},
error: function (request, status, error) {
alert(request.responseText);
}
});
//prevent button default action that is redirecting
return false;
});
});
</script>
Yes, it is possible. I am assuming you know what ajax is and how to use it, if not I am not going to give you the code because some simple reading on ajax as suggested by #Black0ut will show you how. But the basic steps are as follows:
Send ajax request to a PHP script that will update +1 vote to the database
In the PHP script, add +1 to the database and return some data to the ajax, maybe the new number of votes
Parse the return data in your JavaScript and update the button accordingly
QUESTION: What is the proper way to use .get() in conjunction with .one() (or .live()) so that an external php file is appended only once?
MOST RECENT EDIT:
solution
<script>
$(document).ready(function(){
$('.tree li a').one("click", function() {
var currentAnchor = $('.tree li a').attr('href');
if(!currentAnchor){
var query = "page=1";
}
else
{
var splits = currentAnchor.substring(1).split('&');
//Get the section
var page = splits[0];
delete splits[0];
var query = "page=" + page;
alert ("page=" + page);
}
//Send the petition
$("#loading").show();
$.get("callbacks.php",query, function(data){
$("#content").append(data);
$("#loading").hide();
});
return false;
});
});
</script>
More Specifically:
I'm using Javascript and PHP to load some external PHP pages as sections in my main template.
I'm using a switch and append() so the included files keep appending. I need every file to be able to be appended ONLY ONCE. Here is the scenario as I'd like it to happen
1) downloads link is clicked
2) downloads.php appears
3) errors link is clicked
4) errors.php appears below downloads.php
5) downloads link is clicked again
6) page just scrolls up to top of downloads.php
I need the same functionality as the example on the documentation page of .one() where every div can be clicked only once.
I also looked at Using .one() with .live() jQuery and I especially liked the approach used in the accepted answer.
Iried using boolean flag as suggested below but all it did was limit my consecutive clicks on the same link to one. So if I click one link 1 multiple times it'll show page 1.php only once but if I click on link 1, then link 2, then link 1 again it will display page 1.php, then append page 2.php and append another page 1.php.
I'm starting to think that the setInterval is wrong and I may use .one() for the whole checkAnchor() function and bind it to the <a> tags. I tried this but it's not working either :(((
core.js - using .one()
var currentAnchor = null;
//$(document).ready(checkAnchor);
//Function which chek if there are anchor changes, if there are, sends the ajax petition checkAnchor
$("a").one("click", function (){
//Check if it has changes
if(currentAnchor != document.location.hash){
currentAnchor = document.location.hash;
//if there is not anchor, the loads the default section
if(!currentAnchor){
query = "page=1";
}
else
{
//Creates the string callback. This converts the url URL/#main&id=2 in URL/?section=main&id=2
var splits = currentAnchor.substring(1).split('&');
//Get the section
var page = splits[0];
delete splits[0];
var query = "page=" + page;
}
alert ("hello");
//Send the petition
$("#loading").show();
$.get("callbacks.php",query, function(data){
$("#content").append(data);
$("#loading").hide();
});
}
});
The other thing I liked as an approach is adding the names of the pages to an array and then checking that array to make sure the page wasn't displayed yet. I managed to fill up an array with the page names using .push() but I hit a dead end when looking up for a value in it. If you have an idea how that's supposed to look like that'd be very helpful as well.
core.js
///On load page
var contentLoaded;
$().ready(function(){
contentLoaded = false;
setInterval("checkAnchor()", 300);
alert (contentLoaded);
});
var currentAnchor = null;
//Function which chek if there are anchor changes, if there are, sends the ajax petition
function checkAnchor(){
//Check if it has changes
if(currentAnchor != document.location.hash){
currentAnchor = document.location.hash;
//if there is not anchor, the loads the default section
if(!currentAnchor){
query = "page=1";
}
else
{
//Creates the string callback. This converts the url URL/#main&id=2 in URL/?section=main&id=2
var splits = currentAnchor.substring(1).split('&');
//Get the section
var page = splits[0];
delete splits[0];
var query = "page=" + page;
}
alert ("hello");
//Send the petition
$("#loading").show();
alert (contentLoaded);
if (!contentLoaded){
$.get("callbacks.php",query, function(data){
$("#content").append(data);
$("#loading").hide();
});
alert (contentLoaded);
}
contentLoaded = true;
}
}
here is my
callbacks.php
<?php
//Captures the petition and load the suitable section
switch($_GET['page']){
case "4100errors" :
include 'template/4100errors.php';
break;
case "4100downloads" :
include 'template/4100downloads.php';
break;
}
?>
And my main file
4100.php
<?php
include 'template/header.php';
include 'template/4100menu.php';
include 'template/log.php';
include 'template/links.php';
include 'template/4100breadcrumbs.php';
?>
<div class="left-widget">
<div style="display:none; position:absolute; top:-9999; z-index:-100;">
</div>
<div id="side-nav-bar" class="Mwidget">
<h3>Contents</h3>
<ul class="tree">
<li><a href="#4100downloads" class="links" >Downloads</a> </li>
<li>Error Troubleshooting</li>
</ul>
</div>
</div>
<div id="content" style="margin-top:100px; margin-left:300px;">
<?
switch ($_GET['page'])
{
case "4100downloads": include 'template/4100downloads.php'; break;
case "4100errors": include 'template/4100errors.php'; break;
}
?>
</div>
</body>
</html>
4100dowloads.php
Downloads test page
4100error.php
Errors test page
Also you can look at the test page here http://period3designs.com/phptest/1/4100.php
"What is the proper way to use .get() in conjunction with .one() (or .live()) so that an external php file is appended only once?"
.one() and live() really have little to do with $.get. They're only for event handling.
If you intend to run the code every 50ms as you are, but want to replace the current content, then use .html() instead of .append().
$("#content").html(data);
This will overwrite the old content.
I assume you're aware of this, but just to be sure, your code is running at an interval because of this...
$().ready(function(){
setInterval("checkAnchor()", 50); // better--> setInterval(checkAnchor, 50);
});
If you only want it once on document load, then do this...
$(document).ready(checkAnchor);
Just use a boolean flag to determine if you loaded the data yet or not. Set it to false on page load, and just after the call to $.get set it to true. Then, wrap your $.get with an if (!contentLoaded) { $.get ... }.
That way you will execute the $.get only once.
BTW: $.one is used to bind an event to an element, that will execute only once and then unbind it self from it.
The attached picture shows the results page of the search engine that I'm building. For each return result, the user may click on the result (i.e. "Food Science") and it will expand out accordion-style to reveal information about that particular result.
I want to log each time the user clicks on a result (for learning/intelligence purposes) and store it in a database table that I have created which stores the session ID, the query, the position of the result, and the order in which the user clicked the item.
Using JQuery, I already have a function that will pull the title of the result that was clicked, and I have it set where I want to log the click, but I don't know how to do it since JQuery is client side and PHP is server side.
How can I use the JQuery to trigger a PHP function so that I can query the database to insert the click logs into my table?
Below is the JQuery function.
$(document).ready(function() {
$('.accordionButton').click(function(e) {
if($(this).next().is(':hidden') == true) {
$(this).addClass('on');
$(this).next().slideDown('normal');
$(this).next().slideDown(test_accordion);
// SEND CLICK ACTION TO LOG INTO THE DATABASE
alert($(this).find('h3:last').text()); // displays the title of the result that was just clicked
}
else {
$(this).removeClass('on');
$(this).next().slideUp('normal');
$(this).next().slideUp(test_accordion);
}
});
}
You can do something like this (untested):
Define a javascript variable to track the order of the clicks, outside your click function:
var order = 0;
Add this into your click function, at the bottom:
order++;
var sessionID = $("input[name='sessionID']").val(); // assuming you have sessionID as the value of a hidden input
var query = $("#query").text(); // if 'query' is the id of your searchbox
var pos = $(this).index() + 1; // might have to modify this to get correct index
$.post("logClick.php", {sessionID:sessionID, query:query, pos:pos, order:order});
In your php script called "logClick.php" (in the same directory):
<?php
// GET AJAX POSTED DATA
$str_sessionID = empty($_POST["sessionID"]) ? '' ; $_POST["sessionID"];
$str_query = empty($_POST["query"]) ? '' ; $_POST["query"];
$int_pos = empty($_POST["pos"]) ? 1 ; (int)$_POST["pos"];
$int_order = empty($_POST["order"]) ? 1 ; (int)$_POST["order"];
// CONNECT TO DATABASE
if ($str_sessionID && $str_query) {
require_once "dbconnect.php"; // include the commands used to connect to your database. Should define a variable $con as the mysql connection
// INSERT INTO MYSQL DATABASE TABLE CALLED 'click_logs'
$sql_query = "INSERT INTO click_logs (sessionID, query, pos, order) VALUES ('$str_sessionID', '$str_query', $int_pos, $int_order)";
$res = mysql_query($sql_query, $con);
if (!$res) die('Could not connect: ' . mysql_error());
else echo "Click was logged.";
}
else echo "No data found to log!";
?>
You can add a callback function as a third parameter for the $.post() ajax method if you want to see if errors occured in the script:
$.post("logClick.php", {sessionID:sessionID, query:query, pos:pos, order:order},
function(result) {
$('#result').html(result); // display script output into a div with id='result'
// or just alert(result);
})
);
EDIT: If you need the value of the order variable to persist between page loads because you paginated your results, then you can pas the value of this variable between pages using either GET or POST. You can then save the value in a hidden input and easily read it with jQuery. (Or you could also use cookies).
Example (put this in every results page):
<?php
$order = empty($_POST["order"]) ? $_POST["order"] : "0";
$html="<form id='form_session' action='' name='form_session' method='POST'>
<input type='hidden' name='order' value='$order'>
</form>\n";
echo $html;
?>
In your jQuery, just change var order = 0; to
var order = $("input[name='order']").val();
Then, when a user clicks on a page link, prevent the default link action, set the order value and the form action, and then submit the form using javascript/jQuery:
$("a.next_page").click(function(event) {
event.preventDefault();
var url = $(this).attr("href");
$("input[name='order']").val(order);
$("#form_session").attr('action', url).submit();
});
All the 'next' and 'previous' pagination links must be given the same class (namely 'next_page' (in this example).
EDIT: If your pagination is as follows:
<div class='pagination'>
<ul><li><a href='page1.url'>1</a></li>
<li><a href='page2.url'>2</a></li>
</ul>
</div>
then just change this:
$("div.pagination a").click(function(event) {
etc.
This one is pretty easy, you need a PHP-Script to handle AJAX requests which are sent from your Search page.
In your search page you'll need to add an .ajax to create an AJAX request to your Script.
Everything you need to know about AJAX can be found here: http://api.jquery.com/jQuery.ajax/
In your PHP-Script you'll handle the Database action, use GET or POST data to give the script an ID over Ajax.
Use Ajax. Write a simple php-script that writes clickes to the database. I don't know how you log the clicks in the database exactly, but you can send the clicked item unique identifier to a php script with ajax, for example via POST variables.
A little example, on click:
$.post(
'count_click.php',
{ id: "someid" },
function(data) {
// data = everything the php-script prints out
});
Php:
if (isset($_POST['id'])) {
// add a click in the database with this id
}
Send a request to a PHP page using jQuery AJAX. See here for more info (it is really simple):
http://api.jquery.com/jQuery.ajax/
In this particular case, as you do not need to return anything, it may be better to just use the POST or GET methods in jQuery:
http://api.jquery.com/jQuery.post/
http://api.jquery.com/jQuery.get/
Something like:
$.ajax({
type: "POST",
url: "some.php",
data: "name=John&location=Boston"
success: function(data){
alert('done');
});
how i can i change the content of a page without refreshing.I know we need to use hidden frames for this but all the tutorials i have come across teach this only for HTML files what if the content is returned from a PHP file how do i do it in such a case? what should the php file echo or return?
You will have to use Ajax for that, have a look at this tutorial:
AJAX Tutorial
If you use a hidden frame, the content won't be displayed (hence "hidden"), I think you just mean to use an iframe. But this doesn't fit your description of "without refreshing", since you have to refresh the frame.
When loading the PHP file inside the frame, your PHP file just needs to generate HTML the same way you would generate a normal page. It's the same whether the PHP file is loaded inside a frame or not.
I use this method for a lot of my websites and so does Google. If you want to get data from a PHP file and then dynamically update the page you need to "import" the PHP file somehow without the entire page being redirected, or using iframes (which works too but is a lot messier). The way you do this is to import the file as a "javascript" file.
The following code demonstrates a form called "testform" and a text input called "userpost".
When you submit the form, it will import a file, and then update div "outputText" with whatever you entered... and wait for it... all without the page being redirected at all or refreshed!
I have included a lot of extra functions to show how you can access all of your functions on the same DOM unlike if you use frames where you have to use "top.object" or what not
index.html
<html>
<head>
// Get objects by their id. We will use this in the PHP imported file
Get = function(id) {
return (!id) ? null : (typeof id == "object") ? id :
(document.getElementById) ? document.getElementById(id) :
(document.all) ? document.all[id] :
(document.layers) ? document.layers[id] : null;
}
// Formats a string so it does not break in a URL
String.prototype.formatForURL = function() {
var str = escape(this.replace(/ /gi, "%20"));
str = str.replace(/\&/gi, "%26").replace(/\=/gi, "%3D");
str = str.replace(/\//gi, "%2F")
return str;
}
String.prototype.contains = function(str) {
return (!str) ? false : (this.indexOf(str) > -1);
}
Object.prototype.killself = function() {
this.offsetParent.removeChild(this);
}
// Import the script
ImportScript = function(js) {
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("language", "JavaScript");
script.setAttribute("charset", "utf-8");
// we add the is tag so can delete the "js" file as soon as it executes
script.setAttribute("id", "import_" + head.children.length);
script.setAttribute("src", js + (js.contains("?") ? "" : "?") + "&is=" + head.children.length);
head.appendChild(script);
}
// Get and send value to php file
sendInfo = function() {
var file = "js/myFile.php?userpost=";
file += document.testform.userpost.value.formatForURL();
ImportScript(file);
}
</head>
<body>
<div>
<form name=testform onsubmit="sendInfo(); return false">
<input type=TEXT name=userpost />
<input type=SUBMIT value=Go />
</form>
</div>
<div id=ouputText>
This text will be replaced by what you type
and submit into the form above
</div>
</body>
<html>
js/myFile.php
<?php
// Here you can now use functions like mysql_connect() etc. even exec()
// ANYTHING! Save them into variables and output them as text which goes
// Straight into the javascript! e.g. :
// $con = mysql_connect("localhost", "username", "password");
// if($con) {
// ... code to retrieve data and save into $variable
// }
// print "alert(\"$variable\");"; // this alerts the value in variable
if(isset($_GET['userpost'])) {
$userpost = $_GET['userpost'];
?>
Get("outputText").innerHTML = "<?=$userpost; ?>";
<?php
}
?>
// Clear text area
document.testform.userpost.setAttribute("value", "");
// Remove the file from header after info is changed
Get("import_<?=$_GET['is']; ?>").killself();
If I had typed in "Hello World" into text input "userpost" then
div "outputText" would be filled with the words "Hello World"
deleting what was previously there, and the text input will be cleared
Hidden frames is one design pattern that is a part of the overall AJAX design pattern. This is an extreme high-level overview, but this is essentially how it works:
Javascript in your HTML page makes a request to your PHP script by using an XMLHTTPRequest object, or a hidden frame or iframe. This is usually done asynchronously, so you can continue to work with your HTML page while the request is being made.
The data is returned to your Javascript. At this point, you can then manipulate the page, and update data on the page using various DOM methods.
I'm creating a online training 'powerpoint' like series of pages. It will be pretty straight forward and have the pages set out as such:
page1.php
page2.php
page3.php
...
page20.php
I'll be going old school and use an iframe to hide the address bar as people shouldn't be able to catch onto the naming convention and skip ahead. (Its not too serious, so I want to keep it simple).
What I want to do is based on the current page that they are on, say for example page5.php create links to page4.php and page6.html. Obviously without having to code each page manually.
It would be ideal if ths were a javascript function as I dont want the address to show up in the browsers info bar but I'm open to php tricks as well.
Any ideas how to do this?
Use window.location. You can put it in a function like so:
<script type='javascript'>
function goto(url) { window.location=url; }
</script>
<a href='#' onclick='goto("page3.php"); return false;'>Previous</a>
<a href='#' onclick='goto("page5.php"); return false;'>Next</a>
You could also go so far as to use a session variable to hide it, that way you could just do something like this (I hope my PHP skills are still good):
<?php
// At Beginning of first script
start_session();
$MAX_PAGE = 20; // Set this to the highest page number
if(!isset($_SESSION['curpage'])) {
$_SESSION['curpage'] = 1;
} else {
// __EDIT: Added page max and mins.
if($_GET['go'] == 'prev' && $_SESSION['curpage'] > 1) {
$_SESSION['curpage']--;
} else if($_GET['go'] == 'next' && $_SESSION['curpage'] < $MAX_PAGE) {
$_SESSION['curpage']++;
}
}
?>
And then put this in the page where you need it.
<?php
include("page$_SESSION[curpage].php");
if($_SESSION['curpage'] > 1) {
echo "<a href='page.php?go=prev' rel='prev'>Previous</a>";
}
if($_SESSION['curpage'] < $MAX_PAGE) {
echo "<a href='page.php?go=next' rel='next'>Next</a>";
}
?>
Note that Web Crawlers won't be able to do much with this though, when it returns a different page each time.
A little expansion on Pikrass's function, to deal with first/last scenarios:
function goto(url) { window.location=url; }
var curPage = parseInt(location.href.replace(/page([0-9]+)\.php/, ''))
if (curPage <= 1) {
// First page, no 'back' link
document.write('Back');
} else {
var backPage = curPage-1;
document.write("Back");
}
if (curPage >= 9) { // Replace with highest page number
// Last page, no 'next' link
document.write('Next');
} else {
var nextPage = curPage+1;
document.write("Back");
}
URLs are not hidden if you view the source of the page, but they don't show up in the browser's status bar when hovering over the link, as requested.
Edit Updating RegEx with Pikrass' more specific one, to deal with other digits elsewhere in the URL. Thanks Pikrass!
var actuPage = parseInt(location.href.replace(/[^0-9]/, ''))+1;
location.href = 'page'+actuPage+'.php';
That should work if you have no other number in your URLs. If you do, you'll have to change the pattern for replace.
The code is for the next page, change the +1 to -1 for the previous one.
Here is MidnightLightning's version with a better RegExp to get the current page, which works even if you have other numbers in your URLs.
function goto(url) { window.location=url; }
var regPage = /page([0-9]+)\.php/;
var match = regPage.exec(location.href);
var curPage = parseInt(match[1]);
if (curPage <= 1) {
// First page, no 'back' link
document.write('Back');
} else {
var backPage = curPage-1;
document.write("Back");
}
if (curPage >= 9) { // Replace with highest page number
// Last page, no 'next' link
document.write('Next');
} else {
var nextPage = curPage+1;
document.write("Back");
}
I love when an answer is built by several guys. :)
If you can, prefer a PHP code, as suggested. It's much more "clean".
Sounds like you want to use query string variables, so page.php?page=1, page.php?page=2, page.php?page=3 and so on
Why dont you use ajax instead of an iframe?
Well, doesnt matter, you tagged the question jquery so i think you can find usefull using another link attribute to 'tell' js where to redirect.
I mean:
$.(document).ready(funciton(){
//i use the live method becose.. you know, maybe in the future
//you will go with ajax ;)
//live method is avbaiable in jquery 1.3!
$("a.navigation").live('click', function(){
window.location = $(this).attr("rel");
});
});
This let your html markup free from many onclick functions in the <a> tags.
So, your markup will then look something like:
Go to page 1
Go to page 2
<!-- .. and so on.. -->
Or, if you still wanna hide real urls, you can do:
Go to page 1
Go to page 2
<!-- .. and so on.. -->
with this js (maybe not embedded into the page source?)
$.(document).ready(funciton(){
$("a.navigation").live('click', function(){
window.location = 'page' + $(this).attr("rel") + '.php';
});
});
But you'll never be able to completely hide the page urls, if youre planning to use js links.
You could hide them using php, and an hashed strings twin, but i dont know if it worth the game.
Other suggested a regexp way to calculate the pages number and pages links; I will go printing the links via PHP: will let you control the global behavior much better (we dont know how many pages you have, and if theyre numbers is database-related, even the information you gave us would make me think that you have all the page[x].php fisically on your server)