AJAX / PHP Reload a part of a page - javascript

I have made a RESTful API in PHP. To do shortly, I can register some information by calling an address like http://api.website.com/addInfos
This request is a POST request. Here my method:
File: api.php
<?php
/* Page api.php */
private function addInfos()
{
// Check if it's a POST request and if all fields are correct
// Insert data in my MySQL database
// TODO: make an automatic refresh for page named infos.php
}
?>
Second file, where the data are displayed from my database:
File: infos.php
<?php
/* Page infos.php */
// Connection to database
// Prepare the request using PDO
// Execute the request
// Display infos in a while loop
?>
My question is: How can I refresh the part of code where the data is displayed just after the function named "AddInfos" of my API is called ?
EDIT 1:
Here is what I can do:
File: index.php
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<title></title>
<script src="js/jquery.js"></script>
</head>
<body>
<div id="infos"></div>
<script>
function displayInfo(r) {
$.post("infos.php",
{ refresh : r},
function(data){
//alert("Data Loaded: " + data);
$("#infos").html(data);
}
);
}
$(document).ready(function() {
displayInfo(1);
$('a.info_link_text').click(function(){
alert($(this).text());
});
});
</script>
</body>
</html>
File: infos.php
<?php
require_once('database.php');
if(isset($_POST['refresh'])){
$selectInfos = getAllInfos();
$selectInfos->execute();
echo "<table>";
echo "<th>User</th>";
echo "<th>Email</th>";
while($row = $selectInfos->fetch(PDO::FETCH_OBJ)){
$fullname = $row->user_fullname;
$email = $row->user_email;
echo "<tr>";
echo "<td>".$fullname."</td>";
echo "<td>".$email."</td>";
echo "</tr>";
}
echo "</table>";
}
?>
When I load index.php, I can get the infos from the page infos.php. But I really don't know how can I do this when the method "addInfos" of my API is called, because I need to make a POST request on infos.php (it's OK) but put the result data on index.php (not ok, I don't know how to do that). Please, could you let me know how to achieve this ?
Thank you so much for your help.
Best regards,
Lapinou.

I think what you need is a library based on WebSocket HTML5. The server can retain and send notifications to all clients connected at the same time. Then in your javascript handler, you can process anything you want.
In PHP, you could try these examples WebSocket HTML5 PHP on Google
The other way would be to send multiple REST queries on a regular basis to the server to update your page, but it seems you want real-time updates only.

Related

How to do a MVC like a SPA (Single page application)?

I'm trying to create a loader, which loads an animation between visits new paths, something like this:
https://koisquad.com/
The problem is I made my project with following logic (MVC Model View Controller) and I need to not reload the page when the path changes.
I have been investigating and realize that need to use javascript using window.history.pushstate
I tried a lot ways but I can not implement propertly.
Layout page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $title; ?></title>
</head>
<body>
<?php
include_once __DIR__ . '/templates/loader.php';
?>
echo $content; //ONE EXAMPLE VIEW (events.php)
<!-- My Javascript -->
<script src="/build/js/main.min.js" defer></script>
</body>
</html>
One example view (/events.php)
<main>
<div> EVENTS CONTENT </div>
</main>
The Controller
class PublicPagesController {
//Main page
public static function index(Router $router) {
//The Backend logic, Database querys for render later in view...
$router->render('views/index', [
'title' => 'Inicio',
]);
}
//Contact page
public static function events(Router $router) {
//The Backend logic, Database querys for render later in view...
$events = Events::all();
$router->render('views/events', [
'title' => 'Contact',
'events' => $events
]);
}
The router:
public function render($view, $data = [])
{
foreach ($data as $key => $value) {
$$key = $value;
}
ob_start();
include_once __DIR__ . "/views/$view.php";
$content = ob_get_clean(); // THAT IS THE CONTENT THAT SHOWS ON LAYOUT PAGE
}
I have the models too, but I think it's irrelevant to the question.
How can I obtain the view and render in the $content without reloading the page? (With JS or Other solutions)
Thank you a lot in advance, sorry if the question is a little dumb I'm trying to improve :(
I tried to use fetch in JS to URLs (Previusly encoded in JSON in php) for try to get the view content and window.history.pushstate but I cant get the view without a reloading.

Pushing updates to a webpage using server-sent events

I would like to post data to my PHP page and then have it update the HTML page. I followed this example of using server-sent events to push updates to a webpage.
Here is what I have right now:
output.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="serverData"></div>
</body>
<script type="text/javascript">
//check for browser support
if(typeof(EventSource)!=="undefined") {
//create an object, passing it the name and location of the server side script
var eSource = new EventSource("send_sse.php");
//detect message receipt
eSource.onmessage = function(event) {
//write the received data to the page
document.getElementById("serverData").innerHTML = event.data;
};
}
else {
document.getElementById("serverData").innerHTML="Whoops! Your browser doesn't receive server-sent events.";
}
</script>
</html>
send_sse.php:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$val = 0;
if (isset($_POST['msg'])){
$val = $_POST['msg'];
}
echo "data: $val\n\n";
ob_flush();
?>
form.html:
<html>
<body>
<form action="send_sse.php" method="post">
Message: <input type="text" name="msg"><br>
<input type="submit">
</form>
</body>
</html>
The problem is that when the form posts the value, it does not update the output.html. It does output "0" and will update whenever I manually change the value of $val and save the file. However, I want the value of $val to be determined outside of the PHP file. What am I doing wrong?
The issue you are having here is that you have missed how SSE conceptually work. Your output.html page is making a GET request to your web server and executing the script send_sse.php and opening up a connection and HOLDING that connection open and waiting for updates.
When you are posting from form.html you are sending a POST request to your web server and executing the script send_sse.php on a completely different thread.
As you have not implemented any shared persistence between these two threads it will make no difference.
So to do what you want to do you will need to have code in send_sse.php that has some form of global persistence (e.g. database) and can detect new data and then flush that down to the browser.
I am not a PHP expert, but I have written an example in Node JS that uses REDIS pub/sub to provide said persistence.
I hope that helps.

php: routine javascript browser does not appear until the end

We felt in a procedure in php to show a process bar while performing a task, but in the Chrome browser does not display the bar until the process ends. In other browsers like Chromium it works perfectly and shows the progress bar. Any suggestions?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>Progress Bar</title>
</head>
<body>
<!-- Progress bar holder -->
<div id="progress" style="width:500px;border:1px solid #ccc;"></div>
<!-- Progress information -->
<div id="information" style="width"></div>
<?php
// Total processes
$total = 10;
// Loop through process
for($i=1; $i<=$total; $i++){
// Calculate the percentation
$percent = intval($i/$total * 100)."%";
// Javascript for updating the progress bar and information
echo '<script language="javascript">
document.getElementById("progress").innerHTML="<div style=\"width:'.$percent.';background-color:#ddd;\"> </div>";
document.getElementById("information").innerHTML="'.$i.' row(s) processed.";
</script>';
// This is for the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
// Send output to browser immediately
flush();
// Sleep one second so we can see the delay
sleep(1);
}
// Tell user that the process is completed
echo '<script language="javascript">document.getElementById("information").innerHTML="Process completed"</script>';
?>
</body>
I'm gonna be one of those annoying people that ask why are you doing something.
Do you actually need to stream the data from the server to the browser ?
Unless you are sending huge amounts of generated data to the user, there is really no need for such measures.
Because you are not using WebSockets, you could save the information about the process into the cookie, so that you do not have to store it anywhere else, and it is related to an individual client, and send an AJAX request to a dedicated page that will return the percentage, or the state of this process.
While the process is going on you just need to call setcookie with the correct values, something like
setcookie($name, $value, $expiration /*<--- does not matter*/);
and in the dedicated page that returns this value
return $_COOKIE[$name]; //<--- $name the same as in setcookie,
//this should probably return JSON
and in the js code you would ( with jquery, cause its easier )
$.get(page, function(data)
{
document.getElementById("progress").innerHTML =
'<div style="width: data;background-color:#ddd;"></div>';
}
Hope this helps.

window.location seems to cancel ajax post request

I am trying to send data to php with ajax and at the same time redirect to that php file but when I redirected to the php file, the ajax didn't seem to send the data. I wanted to achieve something wherein a button is clicked and a data is sent to php using ajax and at the same time redirect to that php file to see the data sent by displaying it. The reason I didn't use something like window.location="ajaxtest.php?data=data" is because I'm gonna be using it in a google map api wherein if I click a button of a place, then I will redirect to the maps page and display the marker of the specific place depending on the id the ajax sent to the php file and the coordinates generated based on that id.
ajaxtest.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3
/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#button").click(function(){
var data = "test";
$.post("ajaxtest.php",{
data: data
},function(data, status){
window.location="ajaxtest.php";
});
});
});
</script>
<button id="button">test</button>
</body>
</html>
ajaxtest.php
<?php
if(isset($_POST['data'])){
echo $_POST['data'];
}
?>
So, that's not how HTTP, AJAX, or PHP work. There isn't any POST data when you do your redirect, because the redirect is a separate request from the AJAX post. What you want is to do an AJAX post and somehow consume the response on your page, without doing a redirect at all.
It doesn't seem like ajax is the way to go here. If you want to redirect to a different page just do window.location.href = 'ajaxtest.php?id='+locationId; and in your ajaxtest.php:
<?php
$id = isset($_GET['id']) ? (int) $_GET['id'] : null;
if ( ! $id) {
die('ID missing');
}
// Show marker
?>

Call php function on click of a button

I am trying to call a php function on click on a button using Javascript. It does not seem to be working fine.
Is there a better way to call php function on click of a button
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function executeShellScript(clicked)
{
var x="<?php ex(); ?>";
alert(x);
return false;
}
</script>
</head>
<body>
<input type="button" id="sample" value="click" onclick="executeShellScript()"/>
<?php
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
function ex(){
echo "Trying to run shell script from the web browser";
echo "<br>";
$contents = file_get_contents('/var/www/shellscriptphp/helloworld.sh');
echo shell_exec($contents);
$result = shell_exec('sh /var/www/shellscriptphp/helloworld.sh');
echo $result;
}
?>
</body>
</html>
You cannot invoke a php function just like the way you have explained above. Because php script executions happen before the source of the webpage is sent to the client browser from the server.
However you can do it via an ajax call in which you invoke a client side side js function onclick of the button and and that function inturn makes an ajax call to a server side page and returns the result back.
example:
Here is a sample code which you may refer. This page makes a POST ajax request to itself and gets the response back. Let me know incase of errors as i havent run it here.
<?php
/** this code handles the post ajax request**/
if(isset($_POST['getAjax'])) {
/* you can do this below settings via your php ini also. no relation with our stuff */
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
/* setting content type as json */
header('Content-Type: application/json');
$result = shell_exec('sh /var/www/shellscriptphp/helloworld.sh');
/* making json string with the result from shell script */
echo json_encode(array("result"=>$result));
/* and we are done and exit */
exit();
}
?>
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.1.js" type="text/javascript"></script>
<script type="text/javascript">
function executeShellScript(clicked)
{
//$_SERVER["REQUEST_URI"] is used to refer to the current page as we have the ajax target as this same page
$.post('<?PHP echo $_SERVER["REQUEST_URI"]; ?>',{"getAjax":true}, function(data) {
alert(data['result']);
return false;
});
}
</script>
</head>
<body>
<input type="button" id="sample" value="click" onclick="executeShellScript()"/>
</body>
</html>

Categories