How can i create an animated Real Time Leaderboard Table? - javascript

I am trying to create a simple leader-board table that updates in real-time (or close enough) However I want it to be animated. I have been able to create an updating table that updates every second using a simple AJAX script that loads another PHP page. This all works fine and displays the table as it should, but I have no idea how to make it animate up/down if another play has a higher score than them.
What I have done:
leaderboard.html
<html>
<script src="https://code.jquery.com/jquery-latest.js"></script>
<script>
$(document).ready(function() {
$("#Refresh").load("leaderboardupdate.php");
var refreshId = setInterval(function() {
$("#Refresh").load('leaderboardupdate.php');
}, 1000);
$.ajaxSetup({ cache: false });
});
</script>
</html>
leaderboardupdate.php
<?php
$sql = "SELECT Name, Kills FROM Table ORDER BY Kills DESC LIMIT 5";
$result = $conn->query($sql);
echo '<div id="container">';
while($row = $result->fetch_assoc()) {
<div class="row">
<div class="name">'. $row["Name"] .'</div>
<div class="score">' .$row["Kills"]. '</div>
</div>';
}
echo '</div>';
?>
Like I said, this successfully creates a table and updates the data (In order of Kills from the SQL query) as it should, however I am wanting to make a row animate if they have overtaken another player in terms of Kills.
Closest thing I can find as an example:
https://codepen.io/bsngr/pen/WbLEvp
I have looked into Socket.IO, which although allows me to have real-time data, I don't think it will allow me to animate the row up/down, and that is the issue I face.

You are right sockets.io won't let you because it is not associated with animation in any way, however they will let you animate by letting your ap know "When to animate". Last time I checked sockets.io was meant for node.js not sure if they have support for PHP or if PHP has started supporting WebSockets.
WebSockets basically establish a connection between your client and server. They work on publish, subscribe model. So your server will open a connection and your client will subscribe to it. Once the connection between server and client is established your server will be able publish changes and client will be able to listen to them. Rough implementation will look something like this. First you will need to open a channel in your client so server and client can communicate through it.
<script>
var connection = sockets.open(`user-${userID}`) // will open a channel for some user
// once the connection is established you can listen to events
connection.on('update', function(data) {
//perfect place to animate stuff and update data
})
Then in your backend
<?php
$results = $conn->UpdateSomething(); // the place in your code where actions happen;
$socketConnection.trigger($channel, 'update', $results) // this will trigger update event on a $channel with data $results
?>
You can also use ServiceWorkers, LongPolling and ShortPolling to listen to real time changes and modify your DOM on events triggered by server
Steps To Animate
In order to the actual animation you can follow steps below
1 - Find the dom element containing the new leader, you can easily do it by getElementById and giving unique id to each item in board.
2 - Get the previous leader which will ideally be still on top of your leaderboard
3 - Once done, follow this example Swapping two HTML elements visually and on the DOM, and animate it all?. In this example clickedDiv is your new leader and prev is your old leader.

Animate.css is a useful Library I use for animations. Hope you find it useful.
Also, Try to use socket instead of ajax for real-time data.

Related

Sort and separate names from a database

Could anybody point me in the right direction?
I have a database with a handful of messages. Each message has a username also..
I wish to use the names of the messages in a drop down menu so that the user can click a user and view the messages from the user.
THE PROBLEM: the drop down list shows every user of every message and i don-not know how to separate the users so that if there is 7 messages from ROB only 1 ROB will be shown in the drop down list..
I hope I am making sense here.
So if anyone could help me here, I would be grateful.
What sort of query should I be using the separate every user from the database so I can show them in the drop-down menu, as individual users...
Instead of the same user being shown for as many messages as the user wrote.
Below is the current query..
<div class='userbox'>
<header class='ubheader'>Contacts</header>
<section class='ubmain'>
";
$db = new PDO("mysql:host=localhost;dbname=messages", 'root', ''); // 1. set database with this instead of conect - or change conect to this
$query="SELECT * FROM `messagedatabase` WHERE `listID`='$listID' ORDER BY messagedate DESC";
$stat=$db->prepare($query);
$stat->execute();
$Mcount = $stat->rowCount();
$messagecount=$Mcount;
while($row = $stat->fetch()){
$messageaccountname=$row['messageaccountname'];
if ($messageaccountname != $useraccountname){
echo"<div class='ubnames' onclick='selectmessage(\"{$messageaccountname}\")'>{$messageaccountname}</div>";
}
}
echo "
</section>
</div>
";
Any help would be appreciated.
Many thanks.
The simple solution would be to add a DISTINCT clause to your query, such as:
SELECT DISTINCT messageaccountname FROM ....
Beyond that, it sounds like the database isn't normalized. Ideally, you'd have your accounts in a separate table that would be related to your messagedatabase table. But database design is a different discussion beyond the scope of this post.

How to update a table without changing the onscreen data displayed

I need to display a simple list of hundreds of items which are on a MySQL table, review the list onscreen and click on a link beside each unwanted item to delete it from the table. This is an internal management procedure; no outside user is involved. I do not need the item to disappear from the list immediately; I will refresh the list periodically so items deleted from the table are no longer listed. I do not need any message to confirm that the item has been deleted. The important thing is that I don't want to lose sight of the list each time I delete an item and have to click on a "go back" button to return to the list.
The table uses MySQL. All my coding to date has been in PHP. So I am using php to display the list of items, on a non-html screen. This is the code for each item:
echo $item." <a href='item_delete.php?id=".$item."'>Delete item</a><br />";
This is the code for item_delete.php:
<?php
require ('connect.php'); // To define connection $con
$id = $_POST['id'];
mysqli_query($con, "DELETE FROM `items_table` WHERE `id` = $id");
?>
The item is deleted correctly but a blank screen is (understandably) displayed.
I have done a lot of searching but most people needing help want to do more advanced things and - because I have so far managed to avoid learning JavaScript, jQuery and AJAX - I can't even work out which of those technologies I need to update a table without changing the screen.
I get the impression that each PHP script always takes "focus" with it, so maybe I need a little JavaScript script to do this ?
If so:
- can I just change item_delete.php to item_delete.js or do I have to define the non-html list as an html one ?
- what js code is needed in item_delete.js ?
I have read about using: header("location:javascript://history.go(-1)");
or: header('Location: ' . $_SERVER['HTTP_REFERER']);
but they don't go back to the onscreen list.
I don't think I want the js script to perform a virtual "go back" because the list is originally produced by using (about 20) $_POST parameters, so I still seem to have to refresh it each time.
So I'd like a solution to remain with the list - rather than leave it and return to it. Thanks.
It would make a lot of sense to do the deletion asynchronously using javascript. However, the simplest and messiest way to achieve what you want, is to add target="_blank" to the links, (which will leave you with a open blank tab for each delete request you do).
echo $item." <a href='item_delete.php?id=".$item."' target='_blank'>Delete item</a><br />";
Or you can solve it by adding checkboxes in front of every item, check the items you want to delete and submit them as form parameters to the delete script.
If you want to delete to row in the onscreen table after the actual PHP code has run you can use the following implementation:
The HTML structure for the link requires a unique class name, such as:
echo 'Delete item'
Note the item id is stored inside a HTML5 data attribute. I have also added an onclick event handler which returns false to avoid the link refreshing the page.
The javascript used to delete the item use the JQuery AJAX method and binds to the specified class, which is: item-delete. The implementation requires Jquery version >= 1.9.0
(function(){
$('.item-delete').click(function(event) {
var target = $(event.target);
var id = target.data('item-id');
$.ajax({
url: 'item_delete.php',
method: 'POST',
data: {
id: id
},
}).done(function() {
target.remove();
}).error(function(err) {
console.error('Could not delete item with ID: ' + id);
console.error(err);
});
});
}())
The event listener is defined inside a self-executing function, which is automatically executed when the page-load completes and avoids poluting the global namespace.
You can delete the item directly on the same page without moving to another
page by passing the id through a hyperlink and then get it to finally delete
the unwanted item. CHECK THIS OUT, and please let me whether or not is what you
wanted :-)
// connection
mysql_connect("host", "user", "password");
mysql_select_db("your database name");
// select all the items from table.
$selectQuery = mysql_query("SELECT * FROM table_name" );
// use while loop to list all the items...
while( $row = mysql_fetch_array($selectQuery) )
{
// list the items as a hyperlink, passing their id through the URL.
?>
<?php echo "delete " . $row["item_name"]; ?>
<?php
}
// Below is the code to delete the item.
if( isset( $_GET["id"] ) )
{
$itemId = $_GET["id"];
// query to delete item
$deleteQuery = mysql_query("DELETE FROM table_name WHERE id = '$itemId' ");
//-----------THE MOST IMPORTANT PART. >>>
// redirect if delete is successfull.
if( $deleteQuery )
{
// reload the page to get the items minus the deleted one...
// let's say your sript name is delete.php
header("Location:delete.php");
}
}
?>
</code>

Setting the color of an HTML element using an index and Jquery

I am designing a web application for handling various requests to a management team. I have these requests display in tables grouped by the type of request. Initially every request is given a red button since by default requests have not been completed. I am trying to figure out how I can change the color of a specific request's button once it has been marked as completed. Below is my Jquery code:
<script>
<?php
if(isset($_SESSION['index']) and $_SESSION['complete'] == 'internal'){
echo "var index = '{$_SESSION['index']}';";
unset($_SESSION['index']);
unset($_SESSION['complete']);
echo "$( '.complete:eq(index)' ).css('background','green')";
}
elseif(isset($_SESSION['index']) and $_SESSION['complete'] == 'client'){
echo "var index = '{$_SESSION['index']}';";
unset($_SESSION['index']);
unset($_SESSION['complete']);
echo "$( '.client_comp:eq(index)' ).css('background','green')";
}
?>
</script>
By pressing a button you are sent to a page that displays all of the relevant request information. This is done by using another bit of jquery code to store the index of that class of button in a PHP session variable and then using that index to determine which request to load from the database. This page has a complete button that returns to the page with the tables and passes the index and the type of request that was completed back to that page. What my above code is attempting to do is set the color of that specific button using it's type and index. At this point in time everything works as expected except for the color change. I have searched and not been able to find a problem like this. Any help would be greatly appreciated.
I don't understand why you need js variable.
Can you try this.
<script>
<?php
if(isset($_SESSION['index']) && $_SESSION['complete'] == 'internal'){
echo "$( '.complete:eq(".$_SESSION['index'].")' ).css('background','green')";
}
elseif(isset($_SESSION['index']) && $_SESSION['complete'] == 'client'){
echo "$( '.client_comp:eq(".$_SESSION['index'].")' ).css('background','green')";
}
unset($_SESSION['index'],$_SESSION['complete']);
?>
</script>

Creating dynamic forms based on the values selected

I'd like to create a HTML form as follows:
<form action="<?php print($action); ?>" method="post">
<label for="possibilities">Possibilites</label>
<select name="possibility" id="possibility">
<?php foreach ($possibilites as $possibility): ?>
<option value="<?php print($possibility['id']); ?>"><?php
print($possibility['name']); ?></option>
<?php endforeach; ?>
</select>
<rest>The rest of the form</rest>
</form>
When the user selects a certain value from the options menu,
the rest of the form will be generated (instead of <rest>The rest of the form</rest>)
This page accepts a lot of PHP variables that will be used in the rest of the form.
How would you generate the rest of the form based on the value selected from the options?
The rest of the form will accept lots of PHP variables in various input elements generated dynamically. The user should have the possibility to switch between various rests (<rest> ... </rest> until he submits the completed form. The code should not open security holes.
Which approach would you choose and why? (Javascript with loading partial HTML files? Building various DOM trees (with PHP variables in it) for the <rest>...</rest>s or some approach from PHP code)?
create an additional div or any other html element where form needs to be displayed
<div class="formGenerated"></div>
Then in javascript
change event helps to know when any of the option is selected
$(document).ready(function() {
$('#possibility').on('change', function() {
var selectedVal = $('#possibility').val();//value of the option selected
$.ajax({
url:'multipleForms.php',
type:'POST',
dataType:'json',
data:{name:selectedVal},
success:function(resp){
$('.formGenerated').html(resp);
}
});
});
});
// multipleForms.php
<?php
$name = $_POST['name'];
if($name == 'x'){
$x = 'your form goes here';
echo json_encode($x);
}
//similarly for other conditions
?>
Hope this might help you.
With jquery tho following code would be an option:
$(document).ready(function() {
$('#selectId').on('change', function() {
$('#restDivId').load('partialHtmlPage.php?value=' + $('#selectId').val());
});
});
Building various DOM trees is the faster choice. And there is no better or more secure choice actually, both are the same if we're talking security...
Use document fragment and dom manipulation to dynamically update your markup. It is fast enough and completely client side. In respect to the use of jQuery, I would rather be framework agnostic at first unless you need some specific options provided by said frameworks.
Doc:
http://www.w3.org/TR/DOM-Level-3-Core/core.html
http://www.quirksmode.org/dom/intro.html
http://jsperf.com/jquery-dom-fragment-vs-createdocumentfragment/2
To me it would really depend on a few things:
How many additional form elements are you going to need to display?
Do you need record the steps in filling out the form on the server side in some manner?
Do you need to evaluate the data submitted in the form along with data only available on the server in order to determine what next form components to show?
If you only have a few different form options and addining in the DOM as hidden elements on page download does not add what you deem to be unacceptable incremental page download times, you may strongly consider a javascript only solution to hide/show form elements based on your desired logic. If you answered yes to either of other items, and assuming you want to do all this without a page reload, then you would need to use AJAX methodology.

PHP multiple records insert

I am attempting to reword my issue.
I have a datatable that can return thousands of records, each with multiple columns. There is a checkbox in the first column that, once the user checks it, they then click a button, and the CONTAINER_NUMBER that is associated with the row is sent to a modal window to be used in a form.
Here is the code for the checkbox:
echo "<tr><td><input type=\"checkbox\" id=\"{$Row[CONTAINER_NUMBER]}\" name=\"checkMr[]\" /></td>";
This is the javascript that retrieves the CONTAINER_NUMBER and sends it to the modal window:
<script type="text/javascript">
$(function()
{
$('a').click(function()
{
var selectedID = [];
$(':checkbox[name="checkMr[]"]:checked').each(function()
{
selectedID.push($(this).attr('id'))
});
$(".modal-body .containerNumber").val( selectedID );
});
});
</script>
This is the section of the modal window that displays the CONTAINER_NUMBER:
<div class="modal-body">
<form action="" method="POST" id="serviceModalForm" name="serviceModalForm">
<input type="text" name="containerNumber" id="containerNumber" class="containerNumber">
Here is the section of PHP that takes the id="containerNumber" and converts it to a PHP variable. After that, there is an INSERT statement that inserts the containerNumber into a database table:
<?php
$container = $_POST['containerNumber'];
if(isset($_POST['submit'])){
$container = mysql_real_escapse_string(stripslashes($container));
$sql = "INSERT INTO myTable (container_num) VALUES ('$container')";
if(mysql_query($sql)){
echo "Insert complete";
}
else {
echo "Insert was not completed";
}
?>
This code is fine. It works good. It does what it's supposed to do...for when the user checks ONE checkbox. It DOES NOT work when the user checks multiple checkboxes.
Basically, from what I've been researching is that I need to separate the records from the variable $container, as there can be multiple containers in that variable, which is why the query does not work when there are more than one container numbers selected.
I need to be able to separate the container numbers and store them in an array or something. The query will read each record separately and generate multiple INSERT statements for each record.
I've tried several times to create an array and get the sql statement to recognize it, but have been unsuccessful. I'm not sure if I'm placing the array in the right place. I'm not sure if this has to be done in the javascript before the container gets sent to the modal window.
I know I need to utilize a FOREACH loop to go through the array, but like I said, I'm not sure where the array needs to go in my code.
Please help. I know I need to learn PDO or MYSQLI. I will be sure to utilize PDO or MYSQLI on my next application. Until then, please help me with this issue.
Thank you, and sorry for so much wording.
Your containerNumber will be posted as a converted string from a js array. Something like id1, id2, id3[...]
In your php code, convert the $container back to an array ($containerArray = explode(",", $container)) and construct the sql dynamically to add all the rows in a single query so that the statment becomes something like
INSERT INTO myTable (container_num) VALUES ('$containerArray[0]'), ('$containerArray[1]')[...]

Categories

Resources