Display PHP array as animation? - javascript

I have a php array which I displaying with a while loop and it gets the data from a sql database, at the moment everything in the array appears instantly, but would it be possible to get them to display with a half second delay? Would i have to use Javascript?

You can put a <div> around your array, like this:
<div id="myElementID" style="display:none;">
MY ARRAY
</div>
and it will not be visible. With Javascript you can make it visible after, for instance, a 1000 milliseconds, with:
function showElement(id)
// make hidden element visible
{
document.getElementById(id).style.display = "";
}
window.setTimeout("showElement('myElementID')",1000);
No other libraries are needed for this.
If you need to do multiple rows you can wrap a <div> around each row, or use the <tr> tag if your're using tables, like this:
<div id="myRow1" style="display:none;">
ROW 1
</div>
<div id="myRow2" style="display:none;">
ROW 2
</div>
<div id="myRow3" style="display:none;">
ROW 2
</div>
.......
<div id="myRowN" style="display:none;">
ROW N
</div>
And in your script:
for (i = 1; i <= N; i++) {
window.setTimeout("showElement('myRow"+i+"')",500);
}
You would still need the showElement() function.

If you want to do this in your PHP you can call a javascript function with a timeout. Make sure you included the jQuery libary first en defined the method to call. It will be something like the code below. You can change the $delay variable for more or less delay between the different elements.
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script>
function makeVisible(id, delay)
{
setTimeout(function(){
$('#'+id).fadeIn();
}, delay);
}
</script>
<?php
$delay = 500;
$array = array(1,2,3,4,5);
$counter = 0;
foreach($array as $value)
{
$uniqueId = 'aClassName'.$counter;
echo '<div style="display:none;" id="'.$uniqueId.'">'.$value.'</div>';
echo '<script>makeVisible("'.$uniqueId.'", '.($counter++*$delay).')</script>';
}
?>

Yes you need javaScript. Just use jQuery. Use CSS to hide the content container before the page loads and show the content (fadeIn()) after the desired time interval using setTimeout().
Here's a fiddle : http://jsfiddle.net/tnzqv4fx/

Related

Change a button's class using js when php is displaying the buttons in a while loop

`<?php
$i = 0;
$testcount = 0;
while($testcount < 8) {
if($i == 0) {
?>
<input id="info" type="hidden" value="hi">
<?php
} else if ($ == 1) {
?>
<input id="info" type="hidden" value="test">
<?php
}
?>
<button onclick="test()" class="btnT">Hello</button>
<?php
$testcount++;
}
?>
<style>
.test1 {
background-color: cyan;
color: black;
}
</style>
<script type="text/javascript">
function test () {
$(".btnT").addClass("test1");
}
</script>`
Ignore the if statement, I have not yet implemented it to the js
I am displaying buttons using php while loop without any text nor class. A class is determined using an if statement using php where they will hold a hidden input value which will then be pushed to javascript which will then add a class depending on the value of the hidden input, I am then trying to remove and add another class to only one individual button displayed in the while loop. I either get the first button to get the change, or it changes all of the buttons, and not the individual button that I clicked. Please help, Thank you!
My biggest question is how to make each button inside the while loop to have the event occur individually, instead of all of them. I know that it is because I have the code to add a class to the button class, I tried replacing the button class with an id, but that way, only the first button will get the new class added and not the rest of the buttons. Hopefully there is a solution for each button to act separately
When you create your while loop you can append the $testcount to the end of an ID for the button, this way each button will have its own unique ID, but still have a 'template' name that you can use in javascript.
<?php
$i = 0;
$testcount = 0;
while($testcount < 8) {
echo '<button id="btn'.$testcount.'" onclick="test('.$testcount.')" class="btnT">Hello</button>';
$testcount++;
}
?>
Afterwards you should get 7 buttons with ID's btn1, btn2, btn3, btn4... etc
Then in Javascript you can run a function based off each button like this:
function test(x) {
var myButton = document.getElementById('btn' + x);
myButton.classList.add("test1");
// Any more JS logic you have
}
When you click, for example, button #2, the ID of that button should be 'btn2'. The onclick of the button will send the number '2' as an argument to the JS function. The variable myButton will get the element by the ID of the btn + the number you gave it to create a string like 'btn2', then based off that you now know which button was pressed, and you are able to run actions based off that. Using your example you added the class 'test1' to that button.

waiting animation while fetching data in PHP

I have a gif with a loading animation.
in my code I use mysqli_query() to fetch data from a server.
Because, the table is very large it takes time until I see the results.
I am trying to show a "loading" animation while the PHP function is fetching data.
This is my PHP code,
if (isset($_GET['variable'])) {
$_SESSION['variable'] = $_GET['variable'];
$results = mysqli_query($mysqli,"select q1.variable, t3.label, q1.numvalue, description, num_cases from (select variable, numvalue, count(variable) as num_cases from nhws.num_all_{$_SESSION['country']} where variable = '{$_SESSION['variable']}' group by variable, numvalue) q1 inner join (select * from nhws.luvalues where source = '{$_SESSION['country']}' and variable = '{$_SESSION['variable']}') t2 on q1.numvalue=t2.numvalue inner join (select * from nhws.luvariables where source = '{$_SESSION['country']}' and variable = '{$_SESSION['variable']}') t3 on q1.variable=t3.variable;");
echo "<h5>Counts</h5>";
echo '<div id="container" ><img src="ajax-loader.gif" alt="Searching" /></div>';
if ($results->num_rows > 0) {
echo "<table><tr><th>Variable</th><th>label</th><th>Numvalue</th><th>Description</th><th>Num Cases</th></tr>";
// output data of each row
while($row = $results->fetch_assoc()) {
echo "<tr><td>" . $row["variable"]. "</td><td>" . $row["label"]. "</td><td>" . $row["numvalue"]. "</td><td>" . $row["description"]. "</td><td>" . $row["num_cases"]. "</td></tr>";
}
echo "</table>";
} else {echo "0 results";}
}
I am assuming that the function mysqli_query() is the one that takes time because, in my browser it says in the bottom right "waiting for (IP address of the server)"
I tried several methods with AJAX but it did not work while the website was waiting for the server. It did work when the website was waiting for itself and not for a query.
This is my script,
<script>
function makeLoadingGifDisappear() {
document.getElementById('myLoadingGif').style.display = 'none';
}
</script>
And this my HTML code which I replaced before my PHP code,
<img src="ajax-loader.gif" id="myLoadingGif">
Any suggestions?
Thanks!
Try putting a check in a while loop which will check (mysqli_num_rows($result)==0) which means that if table has returned any data back. But, use an if statement inside loop so that you don't put loader everytime loop runs. Once you get back the data the loop going to quit and you can proceed with data.
:D
Place the animated image tag in a div positioned with CSS to cover the portion of the screen you wish to cover and make sure it is the first thing loaded into the page body:
<div class="animated">
<img src="ajax-loader.gif" id="myLoadingGif">
</div>
You can now hide the animated div when the page finishes loading by adding the following just before the closing body tag (shown for reference):
<script type="text/javascript">
window.onload = function() {
document.getElementsByClassName('animated').style.display = 'none';
};
</script>
</body
So, what I did to solve this problem is to hide the GIF with <img src="ajax-loader.gif" id="myLoadingGif" style= "display: none;">
And where the user needs to pick and send the variable to make the query run I added onchange='showDiv()'
Which activates the function below,
function showDiv(){
document.getElementById('myLoadingGif').style.display = "block";
}
And after the query finishes to run the GIF automatically switched to display: none; which is perfect!

Jquery 'find' not working with data tag

I'm struggling to get the Jquery 'find' to work in the following code. I've stripped it down to the very basics. In short, what I'm trying to achieve is, I have two lists containing the same names. When the name is clicked on the top list, I want a more detailed box to toggle open below. Then when either is clicked again, the lower box will toggle closed again.
I assume something is wrong in the Jquery with the 'find'. The other part, which collects the ID works fine when the ID is sent to an alert.
I've looked through other answers and that find section is from another answer but it doesn't work in this example, so presumably I'm doing something wrong on some other level.
Bear in mind that just finding the div or paragraph element won't work for my full code. I've just put them in those tags for this example. I basically need to find (in this example), the para inside the correct div (obviously there's only one div here but loads in my full code).
<html>
<body>
<?php
for ($x=0; $x<10; $x++) {
echo "<p class = 'player_name' data-playerid = $x>Player $x</p>";
}
echo "<div class = 'individual_player_reports'>";
for ($x=0; $x<10; $x++) {
echo "<p class = 'player_name' data-playerid = $x>Player $x</p>";
}
echo "</div>";
?>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$('.player_name').on('click',
function() {
var id = $(this).data().playerid;
$('.individual_player_reports').find("[playerid='" + id + "']").toggle();
});
</script>
</body>
playerid !== data-playerid
Data attributes are just like any other attributes. Use the full name of the attribute when using the attribute equals selector.
$('.player_name').on('click',function() {
var id = $(this).data().playerid;
$('.individual_player_reports').find("[data-playerid='" + id + "']").toggle();
});
$('.player_name').on('click',function() {
var id = $(this).data().playerid;
$('.individual_player_reports').find("[data-playerid='" + id + "']").toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p class="player_name" data-playerid='1'>1</p>
<p class="player_name" data-playerid='2'>2</p>
<p class="player_name" data-playerid='3'>3</p>
<div class="individual_player_reports">
<p data-playerid='1' style="display: none;">1</p>
<p data-playerid='2' style="display: none;">2</p>
<p data-playerid='3' style="display: none;">3</p>
</div>
As #T.J. Crowder suggests, you don't need to use .data() in this case, it would be more efficient to skip .data and just get the attribute value directly to avoid initializing the data cache unless you are using .data()'s features elsewhere too.
var id = $(this).attr('data-playerid');

javascript display and hide div element

I am new to Javascript, and I currently have an article that is being fetched from database, the article has two rows. title & content there are about 100 of these in my database. Now the objective is to list all the titles first, and when a user clicks on a title, to make the the relevant content appear underneath it. I can do this however this way.
<?php
//mysql query here...
foreach($result as $row) { ?>
<div id='title'> <?= $row['title'] ?> </div>
<div id='<?= $row['id'] ?>' style='display:none'
onclick=showContent(<?= $row['id'] ?>) > <?= $row['content'] ?>
</div>
<?php } ?>
The javascript to hide the show the content is this:
<script type='text/javascript'>
function showContent(id){
document.getElementById(id).style.display='inline';
}
</script>
The showContent() function hides the div based on the id passed through the paramenter.
But, the only problem is that, I need other previously displayed divs to truntate when a new one opens.
Meaning, the content should be visible only once, then when you click on another title, the previously opened content should disappear and only the new content should appear.
I hope that made sense. as I am lacking the grammar to explain it all. I tried to give small example here, which for some reason does not seem to work at all, but does in my localhost http://jsfiddle.net/YL6aH/
EDITED:
My full PHP loop, together will all the js/html
<?php
$articlesForPreview = $createQuery
->query("SELECT * FROM timeline");
$fetchAll = $articlesForPreview->fetchAll(PDO::FETCH_ASSOC);
foreach($fetchAll as $row) {?>
<div id='timeline_container'>
<span class='timeline_date'> <?= $row['time'] ?></span>
<span class='timeline_title'> <a href='#' onclick=timeline(<?= $row['id'] ?>)><?= $row['title'] ?></a></span>
<p id='<?= $row['id'] ?>' style='display:none;'> <?= $row['event'] ?></a></span>
</div>
<?php }?>
</aside>
</section>
<script type='text/javascript'>
function timeline(id){
document.getElementById(id).style.display='inline';
}
</script>
<footer id='footer_container'>
You can simply remember the last item that is visible:
var active;
function showContent(id){
if (active) active.style.display = 'none'; // hide previously visible element
active = document.getElementById(id); // keep track of the element you are about to show
active.style.display='inline'; // show the new element
}
Keep in mind that this solution starts with no items visible and after that only allows one item to be visible at a time.
You should try this :
function showContent(id){
$('.active').hide().removeClass('active');
$('#'+id).show().addClass('active');
}
I see also that you will have multiple elements with id=title, you must change it to make every elem unique.
You can go through all elements with an onclick of "showContent", hide them all, afterwards you can just show the one you want.
function showContent(id){
var allElements = document.getElementsByTagName('*');
for ( var i = 0; i<allElements.length; i++ ) {
if ( (allElements[i].onclick + "").indexOf("showContent") >= 0) {
allElements[i].style.display = "none";
}
}
document.getElementById(id).style.display='inline';
}
I'm pretty new to javascript and jquery myself, but one of the things we just did in the class I'm taking was the accordion display, where you attach event handlers in the document.ready for the click events for the header objects, and their div children elements, and it was done by swapping the css classes on the click events... are you using css? in our version, anytime we clicked on a plus, it would expand the display to display the divs below, and clicking the minus pic it would close them... ours did it for all of them, but you should be able to code that even to "close" all of those displays, and then open/display only the divs that are children for the item clicked... is that what you're looking for?

creating html with perl

<header>
<script type="text/javascript">
function hideit()
{
var x1 = document.getElementsByTagName("ol").item(0);
var x = document.getElementsByTagName("ol");
for (var i = 0; i < x.length; i++)
x[i].style.display="none";
}
function showit()
{
var x1 = document.getElementsByTagName("ol").item(0);
var x=document.getElementsByTagName("ol");
for (var i = 0; i < x.length; i++)
x[i].style.display="";
}
</script><header>
<body>
foreach $key (keys %{$stats_data{$out}}) {
print $indexfd ("<input onclick=\"showit()\" type=\"button\" id=\"<?perl echo $key; ?>\" value=\"showit\"><br><input onclick=\"hideit()\" type=\"button\" id=\"<?perl echo $key; ?>\" value=\"hideit\"><br><b><ol id=$key>$stats_data{$out}{$key}<ol id=$key> </b><br>");
}</body>
I am creating an html document with perl. I wrote an event mouseover and mouseout to happen for every perl variable (over a loop). But looks like the event controls all the variables at the same time. How do I write the event only once but enable it to individually be applied for each item: this is what I have currently
but this html when displayed, does not let me control the event separately for each $key.
Even though the buttons do get created for each $key, clicking on one, controls the $stats_data{$out}{$key} of all.
I even tried passing the id to the show/hide script, but no luck.
Your code looks like you are trying to mix Perl with HTML in a way you would use PHP. This does not work in Perl.
I tried fixing your Perl code first. This will print to your filehandle (which I omitted), but will not not give you the working JavaScript code. I did not change that since I did not understand what you want to do. More on that later.
use strict;
use warnings;
# open of $indexfd filehandle goes here..
# print head of HTML page
print $indexfd <<HTML
<html>
<header>
<script type="text/javascript">
function hideit() {
var x1 = document.getElementsByTagName("ol").item(0);
var x = document.getElementsByTagName("ol");
for (var i = 0; i < x.length; i++)
x[i].style.display="none";
}
function showit() {
var x1 = document.getElementsByTagName("ol").item(0);
var x=document.getElementsByTagName("ol");
for (var i = 0; i < x.length; i++)
x[i].style.display="";
}
</script>
</header>
<body>
HTML
;
# If I see this correctly, %stats_data looks like this:
my %stats_data = (
'out1' => {
'key1' => 'val1',
'key2' => 'val2',
},
'out2' => {
'key1' => 'val1',
'key2' => 'val2',
},
);
my $out = 'out1'; # you need the $out from somewhere
# print buttons for each data thingy - you'll want to sort them probably
foreach my $key (sort keys %{$stats_data{$out}}) {
print $indexfd
qq~<input onclick="showit()" type="button" id="$key" value="showit"><br />~,
qq~<input onclick="hideit()" type="button" id="$key" value="hideit"><br/>~,
# Because $stats_data{$out} is a hash ref you need the -> operator here
qq~<ol id="$key"><li><b>$stats_data{$out}->{$key}</b></li></ol><br/>~;
}
print $indexfd qq~<p>more html...</p></body></html>~;
So there are a few things worth mentioning.
print $indexfd ("<input onclick=\"showit()\" type=\"button\" id=\"<?perl echo $key; ?>\" value=\"showit\"><br><input onclick=\"hideit()\" type=\"button\" id=\"<?perl echo $key; ?>\" value=\"hideit\"><br><b><ol id=$key>$stats_data{$out}{$key}<ol id=$key> </b><br>");
In this rather long line of code you used <?perl echo $key; ?> which looks like php and doesn't work. You also used <ol id=$key> which works because you used double-quotes "...". Perl substitutes the variables inside the "-delimited string for their values. You don't need that php-like stuff. In order to save yourself the effort of escaping all the double quotes in the HTML code you can use the qq-Operator. See perlop for more infos.
I explained about the %stats_data data structure in my comments.
For printing the large chunk of HTML, I used HERE docs.
Let's talk about your JavaScript now.
Even though the buttons do get created for each $key, clicking on one, controls the $stats_data{$out}{$key} of all.
This is because of the way you designed your hideit() and showit() functions. I'm not really ceratin what you want to achieve. If you look at my %stats_data you'll see that there are several keys in 'out1'. That lets the foreach-loop print a set of buttons for each of those keys. The buttons both have the same key as their id, as does the ol. That is not correct. An id-attribute has to be unique.
Furthermore, there were some basic issues in your html which I took the liberty to fix as well. If you open an <ol id="foo"> container, you need to close it like </ol>. Since <ol> is a block-level element, you shouldn't put the inline element <b> outside it, but rather inside the ol's <li> elements (which I omitted). It would be better yet to just assign css ``style="font-weight: bold" to the li items or better yet give them classes.
I'll take one last guess at what you were trying to do with the JavaScript. If you have several paragraphs of text and you want to hide them with buttons, you could do that like my untested code here.
Javascript:
function toggle(id) {
if (document.getElementById(id).style.display == 'block' ) {
document.getElementById(id).style.display = 'none';
} else {
document.getElementById(id).style.display = 'block';
}
}
HTML:
<div>
<input type="button" name="toggle1" id="toggle1" onclick="toggle('p1')" />
<p id="p1">Lorem ipsum dolor set ... foo a lot of text 1.</p>
<input type="button" name="toggle2" id="toggle2" onclick="toggle('p2')" />
<p id="p2">Lorem ipsum dolor set ... foo a lot of text 2.</p>
</div>
In this case, the function checks whether the paragraph is shown or not. The display-value needs to be set to 'none' or 'block', because the p-element is a block-level element.
Please try to post more specific information about the data you use with your script if you need any more help.
EDIT:
In the following code I changed the JS functions to both take an id (the key) as a parameter. They only show or hide the lists associated with this key. I changed the button's ids so they're not the same. I also added a div around each pair of buttons and list to make it clearer what belongs where.
use strict;
use warnings;
# open of $indexfd filehandle goes here..
my $indexfd;
# print head of HTML page
print $indexfd <<HTML
<html>
<header>
<script type="text/javascript">
function hideit(key) {
document.getElementById(key).style.display = "none";
}
function showit(key) {
document.getElementById(key).style.display = "";
}
</script>
</header>
<body>
HTML
;
# If I see this correctly, %stats_data looks like this:
my %stats_data = (
'out1' => {
'key1' => 'val1',
'key2' => 'val2',
},
'out2' => {
'key1' => 'val1',
'key2' => 'val2',
},
);
my $out = 'out1'; # you need the $out from somewhere
foreach my $key (sort keys %{$stats_data{$out}}) {
print $indexfd
qq~<div id="div_$key">\n~, # Add a div around the $key-elements
qq~<input onclick="showit('$key')" type="button" id="btn_show_$key" value="showit">\n~,
qq~<input onclick="hideit('$key')" type="button" id="btn_show_$key" value="hideit"><br/>\n~,
qq~<ol id="$key"><li><b>$stats_data{$out}->{$key}</b></li></ol>\n~,
qq~</div>\n~;
}
print $indexfd qq~<p>more html...</p></body></html>~;
It looks like you want one of Perl's templating modules, such as Template Toolkit. It allows you to embed Perl snippets inside larger documents then process them such that the Perl parts fill in whatever you need.
Here's an example from one of my websites. It uses wrapper files to include the top and bottom portions, and reads an XML file to get the data to fill in the middle:
[%
title = "The Perl Review"
xml = "raw/xml/tpr_issues.xml"
sidebar = 1
%]
[% PROCESS top %]
<table class="content-table">
<tr>
<td colspan class="2">
<h2>Next issue: April 15</h2>
[% PERL %]
use XML::Twig;
my $twig = XML::Twig->new;
$twig->parsefile( $stash->get( 'xml' ) );
my $root = $twig->root;
my $latest_issue = $root->first_child( 'release' );
my( $volume, $issue, $year, $season ) =
map { eval {$latest_issue->first_child( $_ )->text } }
qw( volume issue year season );
my $articles = $latest_issue->first_child( 'articles' );
print <<"TEMPLATE";
<A class="cover-link" href="/Subscribers/ThePerlReview-v${volume}i${issue}.pdf"><img
class="cover-image-medium" height="396" width="306"
src="/Images/covers/v${volume}i${issue}-cover-medium.png" /></a>
</td>
<td class="article-cell">
<h2 id="issue-header">Issue $volume.$issue, $season $year</h2>
TEMPLATE
foreach my $article ( $articles->children( ) )
{
my #children = map { $_->tag } $article->children;
my %hash =
map {
$article->first_child( $_ )->tag,
$article->first_child( $_ )->text
}
map { $_->tag } $article->children;
print qq|\t<p class="article-title"><span class="article-title">$hash{title}</span>|;
print qq| (sample)| if $hash{sample_page};
print "<br />\n";
print qq|\t\t<span class="article-author">$hash{author}</span></p>\n|;
}
[% END %]
[% PROCESS issue_note %]
</td>
</tr>
</table>
[% PROCESS footer %]

Categories

Resources