I would like to recreate several like button that saves count in a file.txt but that doesn't work :/
<?php
function getClickCount()
{
return (int)file_get_contents("counter.txt");
}
function incrementClickCount()
{
$counter = getClickCount() + 1;
file_put_contents("counter.txt", $counter);
}
?>
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<script type="text/javascript">
var clicks = 0;
function onClick() {
clicks = 1;
document.getElementById("clicks").innerHTML = clicks;
};
</script>
<button type="button" onClick="onClick()" title="Vous aimez la couverture?" class="btn"><img id="heart" src="https://trello-attachments.s3.amazonaws.com/568304b85fa72dcb958a1edf/584acfc48b82595af77f2030/6257bf1efec79d5baf22309f8f327ce5/favorite.png" /></button>
<p><a id="clicks"><?php echo getClickCount(); ?></a></p>
DEMO HERE
Thanks in advance for your help, I am looking since days on the web to find it but I don't...
Alexander
counter.php
<?php
function getClickCount() {
return (int)file_get_contents("counter.txt");
}
function incrementClickCount() {
$counter = getClickCount() + 1;
file_put_contents("counter.txt", $counter);
}
if(!empty($_POST)) {
if($_POST['click'] == 'true') {
incrementClickCount();
echo getClickCount();
} else {
echo getClickCount();
}
}
?>
counter.txt
0
index.php
<html>
<head>
<title>Click Counter</title>
</head>
<body>
<button type="button" onClick="onClick()" title="Vous aimez la couverture?" class="btn"><img id="heart" src="https://trello-attachments.s3.amazonaws.com/568304b85fa72dcb958a1edf/584acfc48b82595af77f2030/6257bf1efec79d5baf22309f8f327ce5/favorite.png" /></button>
<p><a id="clicks"></a></p>
<script>
function onClick() {
loadClicks(true);
}
function loadClicks(isClicked) {
var click = isClicked === true ? true : false;
$.ajax({
url: 'counter.php',
type: 'POST',
data: {
'click': click
},
success: function(response) {
$('#clicks').text(response);
}
});
}
loadClicks(false);
</script>
</body>
</html>
Code Explanation
Whenever you click the button, there is an ajax request sent asynchronously in the background to counter.php. This PHP file receives request and process accordingly.
Here in the code, we send a single data to the PHP file in the ajax POST request which is a boolean data that is set based on the condition like if the button is clicked.
In PHP file, you will check a condition if the request is happened by button click or else other. If it is by button, you will increment the click and send the click counter value in response else you will only send the value.
You will notice I've called loadClicks function with the parameter true in onClick function and false outside the function meaning that I first call the loadClicks(false) as soon as the script is started its execution to load only the clicks value and later when I click the button loadClicks(true) is invoked meaning increment and fetch the value.
You will understand the code when you go through them carefully.
At first glance, I see 3 problems with your script.
1) You are mixing JavaScript and PHP. JavaScript runs on browsers and PHP runs on servers. If you want to exchange data between those parts of your script you need to make a server call from the JS part to the server, e.g. by using AJAX. A simple HTML request in JavaScript to a PHP script will work too.
2) Also your <button> tag needs to be embedded in a <form> should point to a script to be executed (can be the same script).
3) You never seem to call incrementClickCount(), at least not in the part shown here.
Suggestions
The would code everything in PHP and then address the other two points. Or you need to implement some form of client / server communication.
Related
I created a modal form (that pops up upon a link click, i.e trigger()). This is the HTML code:
<div class="modalbg">
<div class="modalPopup">
<form action="samepage.php" class="formContainer" method="post">
<h2>Change Desk Number</h2>
<label for="studentid">
<strong></strong>
</label>
<input type="password" placeholder="Your KEY" name="studentid" required/>
<label id="status" style="color:red;"></label>
<button type="submit" class="btn" onclick="return verify()">Upgrade</button>
<button type="button" class="btn cancel" onclick="closeForm()">Close</button>
</form>
</div>
</div>
The JavaScript that controls this modal is:
function trigger(){
document.getElementById("modalPopup").style.display = "block";
}
function closeForm() {
document.getElementById("modalPopup").style.display = "none";
}
function verify() {
var studentid = document.getElementById("studentid").value;
if (studentid != dbstudentid || !studentid){
document.getElementById("status").innerHTML="Invalid Student ID!";
function trigger(event) { event.preventDefault(); }
return false;
}
else{
document.getElementById("modalPopup").submit();
}
}
Everything works at this point (i.e it pops up whenever I click the link and whenever I knowingly try to enter a wrong studentid, it returns the "Invalid student ID" on the "status" label. (Note: I had already saved the session's student ID in the variable dbstudentid using:
var dbstudentid = <?php echo json_encode($dbstudenid);?>;
My problem however comes from when I try to execute the PHP on the same page.
Whenever I insert the PHP code into the modalbg div or modalPopup div inside it, the entire modal refuses to pop, let alone submit.
This is the PHP code I used (it should be noted that at the beginning of the page, I had already used include(configure-db.php) and session_start() ) :
<?php
if(isset($_POST['studentid'])){
$studentid = $_POST['studentid'];
$desk = 1;
$deskstatus ="";
$select = "UPDATE users SET deskNo = '$desk' WHERE name='$SESSION';
}
if (mysqli_query($MyConn, $select)) {
$deskstatus = "Desk changed successfully!";
} else {
$deskstatus = "Error";
} return $deskstatus;
?>
I have tried everything, the modal just refuses to come every time, let alone successfully make the Desk Update on my Database. to make things worse, whenever I refresh the page, the modal which I set to display:none; by default on CSS suddenly starts showing. But whenever I remove the PHP code, it returns to normal.
Do I need to make the action execute in a separate page? If yes, please how?
Else, how please?
I world highly suggest you think about using AJAX to handle this probolem.
let's clear up things.
you can write var dbstudentid = '<?= $dbstudenid ?>'; instead of var dbstudentid = <?php echo json_encode($dbstudenid);?>; this will give you freedom of JS native datatype.
you need to send this form request through ajax and recive output there.
Change the php code else part to like this
else { $deskstatus = "Error: " . mysqli_error($MyConn); }
Now when there is a actual problem on code you will know what was the problem. and it will not break you interface.
4. Create seperate file that handle this form request.
5. Here is code snippet of plaing JS AJAX implementation
let post = JSON.stringify(postObj)
const url = "https://jsonplaceholder.typicode.com/posts"
let xhr = new XMLHttpRequest()
xhr.open('POST', url, true)
xhr.setRequestHeader('Content-type', 'application/json; charset=UTF-8')
xhr.send(post);
xhr.onload = function () {
if(xhr.status === 201) {
console.log("Post successfully created!");
let AlertDiv = document.querySelector('#alert');
AlertDiv.innerHTML = xhr.response;
}
}
I am new to this, so far i was just using html form, click the submit button, the page was refreshing and the data was sented to the server (mySQL). But i learned Ajax (AJAX is a developer's dream) they are saying cause you can:
Read data from a web server - after the page has loaded
Update a web page without reloading the page
Send data to a web server - in the background
So i did a simple example. Let's say that i have set the sqlConnection.php
let input = document.getElementById("inputField");
document.getElementById("submitBtn").addEventListener("click", function (){
if(input.value == ""){
alert("empty field");
}else {
$(document).ready(function (){
$.ajax({
url: 'insert.php',
method: 'POST',
dataType: 'text',
data: { comment: input.value },
success: function (){
input.value = "";
}
});
});
}
});
function selectQuestions(){
let data = "true";
$("#comments").load("select.php");
}
setInterval(selectQuestions, 3000);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax text</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous">
</head>
<body>
<div class="container py-3">
<input id="inputField" type="text" class="form-control text-left" aria-label="">
<div class="py-2 my-1">
<button id="submitBtn" value="addNew" class="btn btn-success">Submit</button>
</div>
</div>
<div class="container" id="comments">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="main.js"></script>
</body>
</html>
select.php has this:
$sql = "SELECT * FROM data";
$result = $conn->query($sql);
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
echo "<p>{$row['question']}</p>";
}
} else {
echo "No comments";
}
So my Question: Is this correct in order to see new results that came from the server ? I call the setInterval method every 3 seconds as you can see. Is this bad for the server ? For example if i upload this project to a server and 10 users are using it.. am i exhausting the server - consuming more space ?
Assuming your code is in main.js, you don't need the $(document).ready(), since at the bottom of the <body>, your code will only run after everything is ready anyway. Not to mention it's in the wrong place.
At first I thought you were using .load() wrong, since its a shorthand for the event handler .on('load'). But it turns out in jquery 3.0 they've added an ajax method also called .load(). This is dumb and going to cause alot of confusion, but I digress, use $.get() or $.getJson to get things from a server.
Hitting the server with an interval isn't necessarily bad, it's called polling and it's how the internet did full duplex communication for many years. The problem comes when you poll too often or want to update too much data or have too many users all polling at once. How much is too much all depends on the machine your server is running on. Websockets is definitely a better option, but quite a bit more complex to configure.
I took the liberty to re-write some things, since if you're using jquery, might as well use jquery.
let $input = $('#inputField');
$('#submitBtn').on('click', function(e) {
e.preventDefault(); //assuming this is in a <form>, default action is to reload the page
if ($input.val()) {
$.post('insert.php', { comment: $input.val() })
.done(function() {
$input.val('');
})
.fail(function(error) {
//error handling code
});
} else {
alert("empty field"); //alerts are annoying and thread blocking,
} //maybe use a different method to communicate with the user.
});
setInterval(function() {
$.get('select.php')
.done(function(select) {
//whatever you want to do with the response from this
})
.fail(function(error) {
//error handeling code
});
}, 3000);
On the php side, maybe just clean things up a bit so that it's more readable. You can use the ->fetch_all(MYSQLI_ASSOC) method instead of a while loop to get an associated array for the result. Then just array_map() and implode() that to build you html response.
<?php
$conn = new mysqli("configs and what not");
$statement = $conn->query("SELECT * FROM data");
$result = $statement->fetch_all(MYSQLI_ASSOC);
if (count($result) > 0) {
echo implode("", array_map(fn($row) => "<p>{$row["question"]}</p>", $result));
} else {
echo "No comments";
}
$conn->close();
I have two php pages. page.php and loader.php. Loader.php pulls data from mysql to fill a progress bar and page.php contains a function to refresh loader.php every second. It works but it's rather ugly because you can see the css animation resetting every second.
I would prefer having the loading bar html in page.php along with all the other html for my page but A) how do I get the vars from loader.php into page.php and B) how do I update the div (or any object) on page.php without refreshing the page?
I looked into AJAX which seems like it can do what I want but I'm new to AJAX and programming in general. I'm already proud it is (somewhat) working to begin with.
page.php
<script>
var myTimer = null;
//executes a script that fills mysql with data
function fileExec() {
$.ajax({
url:"fileexec.php",
type: "post"
});
startRefresh();
}
//Shows progress bar
function refreshData() {
$('#container').load('loader.php');
}
function stopRefresh() {
clearInterval(myTimer);
}
function startRefresh() {
myTimer = setInterval(refreshData, 1000);
}
</script>
loader.php
<?php
//Code not shown sets up connection to mysql to pull progress
$progress1 = $row['progress'];
$script1 = $row['script'];
//Stop refresh after shell script has finished
if ($script1 == "stop") {
echo "<script>";
echo "stopRefresh();";
echo "</script>";
}
?>
//Update progress bar with variable
<html>
<body>
<div class="progress-bar-wrapper">
<div class="progress-bar">
<div id="myBar" class="progress-bar-fill in-progress" style="height:10px;width:<?php echo $progress1; ?>%"></div>
</div>
</div>
</body>
</html>
Update it using js:
$.post("loader.php", {
function: "getProgress"
}, function(data) {
progress = JSON.parse(data);
//use progress to change your bar with js
});
And in the php:
switch ($_POST['function']) {
case 'getProgress':
getProgress();
break;
}
function getProgress() {
//get the progress state
echo json_encode($progress);
}
I'm building a photography portfolio. Some of my images have nudity, so I want to hide those by default until the user clicks a "Toggle Worksafe Mode" button.
I can do it with a standard form post (and sessions), but that causes "confirm form resubmission" errors when the user backs or reloads. I'm trying to figure out an AJAX post instead to avoid that.
UPDATE: This is the working code. Please note that this does NOT work with the "slim" jQuery distro; that's one of the main reasons I was having trouble.
Image Index Page:
<?php
session_start();
if (!isset($_SESSION['Worksafe_Mode'] {
$_SESSION['Worksafe_Mode'] = 1;
}
?>
<!-- other page content -->
<script src="scripts/jquery-3.2.1.min.js"></script>
<!-- other page content -->
<button type="button" id="Worksafe_Button" name="Worksafe_Button">
Toggle Worksafe Mode
</button>
<script>
$('#Worksafe_Button').click(function() {
$.post("worksafe_mode_toggle.php")
.done(function(data) {
window.location.href = window.location.href;
});
});
</script>
<!-- other page content -->
<?php
$Connection = Connect();
$query = mysqli_query($Connection, 'SELECT uri, name, nsfw FROM images ORDER BY uri');
while($row = mysqli_fetch_assoc($image)) {
if ($_SESSION['Worksafe_Mode'] == 1 && $row['nsfw'] == 1) {
echo 'If you are over 18, toggle Worksafe Mode to view this image';
}
else {
echo '<img alt="'.$row['title'].'" src="../'.$row['uri'].'/s.jpg" srcset="../'.$row['uri'].'/m.jpg 2x">';
}
}
?>
worksafe_mode_script:
session_start();
if (isset($_SESSION['Worksafe_Mode'])) {
if ($_SESSION['Worksafe_Mode'] == 1) {
$_SESSION['Worksafe_Mode'] = 0;
}
else {
$_SESSION['Worksafe_Mode'] = 1;
}
}
I think ajax is a good approach in your case.
I might do something like display a page of SFW images as the default, along with the toggle button.
When they click the button it triggers an ajax request to the back-end that sets/un-sets the session value in toggleWorksafe.php. Finally it triggers a page refresh.
During the page refresh the PHP code checks whether the session variable is set and shows either the filtered or unfiltered set of images, and changes the button's text to match.
To implement:
Include jQuery in the <head> section (jQuery simplifies the ajax call):
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
</head>
<body>
<?php
session_start();
if (!isset($_SESSION['Worksafe_Mode'])) {
$_SESSION['Worksafe_Mode'] = 'yes';
}
?>
<button id="workSafe" type="button" name="Worksafe_Toggle_Button">
<?php
if ($_SESSION['Worksafe_Mode'] == 'no') {
echo 'Hide NSFW images';
}
else {
echo 'Include NSFW images';
}
?>
</button>
<!-- display safe images by default -->
<?php
if ($_SESSION['Worksafe_Mode'] == 'no') {
echo '<br/><br/>Showing NSFW images';
}
else {
echo '<br/><br/>Showing safe images only';
}
?>
<!-- any other page content here -->
<script>
$('#workSafe').click(function() {
// ajax request to page toggling session value
$.post("/toggleWorksafe.php")
.done(function(data) {
window.location.href = window.location.href; // trigger a page refresh
});
});
</script>
</body>
</html>
toggleWorksafe.php:
<?php
session_start();
if (isset($_SESSION['Worksafe_Mode'])) {
if ($_SESSION['Worksafe_Mode'] == 'yes') {
$_SESSION['Worksafe_Mode'] = 'no';
}
else {
$_SESSION['Worksafe_Mode'] = 'yes';
}
}
else {
$_SESSION['Worksafe_Mode'] = 'yes';
}
?>
there are a couple of ways to do this and it related to how you hide or load you images.
1. simple method
if you don't care about the user's age, and just need to toggle, then you can do it with just a js variable, a cookie, and two version of link. with this, you don't hide images, but loads them. the filtering is done in the server, where you can use database query or a simple folder separation. for example:
var nsfw = read_cookie('nsfw', false); // not an actual js function, search for how to read cookie in js --- read cookie value, default to false
function loadImage(nsfw){
if (nsfw){
$.get('nsfw-image-list-url', function(resp){
// the url should return a json with list of image urls
var list = resp; // jQuery automatically parse json with the right MIME
list.forEach(function(val){
// insert image to page
$('#container').append('<img src="' + val + '/>');
});
});
} else {
$.get('sfw-image-list-url', function(resp){
// the url should return a json with list of image urls
var list = resp; // jQuery automatically parse json with the right MIME
list.forEach(function(val){
// insert image to page
$('#container').append('<img src="' + val + '/>');
});
});
}
}
and in you button click event:
nsfw = !nsfw;
// clear the image first if needed
$('#container').empty();
loadImage(nsfw);
2. another simple method, but not as simple as the #1
you can also do it with only one link that returns a list of images with the type of it, such as nsfw or other things.
note: this method still uses cookie
for example the returned list is like this:
[
{"url": "some-image-1.jpg", "nsfw": "true"},
{"url": "some-image-2.jpg", "nsfw": "false"},
{"url": "some-image-3.jpg", "nsfw": "true"},
{"url": "some-image-4.jpg", "nsfw": "false"},
{"url": "some-image-5.jpg", "nsfw": "false"},
{"url": "some-image-6.jpg", "nsfw": "true"}
]
then you just render it when the conditions are met.
function renderImage(nsfw){
$.get('image-list-url', function(resp){
list.forEach(function(val, key){
if (nsfw || !val.nsfw){
$('#container').append('<img src="' + val.url + '/>');
}
});
});
}
and many other methods that are too long to explain, such as using Angular, React, or Vue
still uses cookie for between reloads or backs, and does not regard user's age.
as for the session based approach, you only need that if you need to verify your users age
that is if you have a membership functionality with DOB (date of birth) data in your site, if so, you can use #KScandrett 's answer
Confirm form resubmission happens because you do not perform a redirect after a successful form submission.
Take a look at this wiki page to see how to do it right. https://en.wikipedia.org/wiki/Post/Redirect/Get
This question already has answers here:
What is the difference between client-side and server-side programming?
(3 answers)
Closed 9 years ago.
I hope to run a php code inside a javascript code too and I do like that :
<?php function categoryChecking(){
return false;
}?>
....
function openPlayer(songname, folder)
{
if(<?php echo categoryChecking() ?> == true)
{
if (folder != '')
{
folderURL = "/"+folder;
}else
{
folderURL = '';
}
var url = "/users/player/"+songname+folderURL;
window.open(url,'mywin','left=20,top=20,width=800,height=440');
}else{
alerte('you should click on a subcategory first');
}
}
....
<a href='javascript:void();' onClick="openPlayer('<?php echo $pendingSong['id']; ?>','')">
finally I get this error instead the alert message "you should click on a subcategory first"
ReferenceError: openPlayer is not defined
openPlayer('265','')
You're reduced your test case too far to see for sure what the problem is, but given the error message you are receiving, your immediate problem has nothing to do with PHP.
You haven't defined openPlayer in scope for the onclick attribute where you call it. Presumably, the earlier JS code is either not inside a script element at all or is wrapped inside a function which will scope it and prevent it from being a global.
Update: #h2ooooooo points out, in a comment, that your PHP is generating the JS:
if( == true)
Check your browser's error console. You need to deal with the first error messages first since they can have knock on effects. In this case the parse error in the script will cause the function to not be defined.
Once you resolve that, however, it looks like you will encounter problems with trying to write bi-directional code where some is client side and some is server side.
You cannot run PHP code from JavaScript, because PHP is a server-side language (which runs on the server) and JavaScript is a client-side language (which runs in your browser).
You need to use AJAX to send a HTTP request to the PHP page, and then your PHP page should give a response. The easiest way to send a HTTP request using AJAX, is using the jQuery ajax() method.
Create a PHP file ajax.php, and put this code in it:
<?php
$value = false; // perform category check
echo $value ? 'true' : 'false';
?>
Then, at your JavaScript code, you should first add a reference to jQuery:
<script type="text/javascript" src="jquery.js"></script>
Then, use this AJAX code to get the value of the bool:
<script type="text/javascript">
$.ajax('ajax.php')
.done(function(data) {
var boolValue = data == 'true'; // converts the string to a bool
})
.fail(function() {
// failed
});
</script>
So, your code should look like this:
function openPlayer(songname, folder) {
$.ajax('ajax.php')
.done(function (data) {
var boolValue = data == 'true'; // converts the string to a bool
if (boolValue) {
if (folder != '') {
folderURL = "/" + folder;
} else {
folderURL = '';
}
var url = "/users/player/" + songname + folderURL;
window.open(url, 'mywin', 'left=20,top=20,width=800,height=440');
} else {
alert('you should click on a subcategory first');
}
})
.fail(function () {
// failed
});
}