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!
Related
I have a page with multiple report cards in separate div tags, each with a unique id. Each report card has a student picture and a school logo there. I also have another page that shows only one report card at a time.
I noticed that when I use html2canvas to convert the page with a single report card, it converts to an image fine, both the logo and student image shows on it but on the page with multiple report cards, when I try using a loop to convert about 8 report cards at once, some of the report cards logo and student picture does not show. They all got converted successfully to an image but the student picture and logo do not show in some. Other information in the report card showed fine.
What can cause this? below is the code I used to convert the page
function doCapture(report_id, loop_num) {
window.scrollTo(0, 0);
$.toast().reset('all');
showToast("<b>Please Wait</b>", "Processing your request...", "info", "#46c35f");
html2canvas(document.getElementById("report_card_page" + loop_num), {scrollY: -window.scrollY}).then(function (canvas) {
var image = canvas.toDataURL("image/jpeg", 0.9);
$.post("../worker/edit-report-card/save-all-capture.php", {"image": image, "report_id" : report_id, "loop_num" : loop_num}, function(data){
$.toast().reset('all');
if(data.includes(" :: ") == true){
var toast_array = data.split(" :: ");
if(toast_array[2].trim() != "success") showToast(toast_array[0], toast_array[1], toast_array[2], toast_array[3]);
else { var total_loop_num = <?php echo $loop_stud_num ?>; if(loop_num == total_loop_num) alert("Publish Completed"); }
//else { var total_loop_num = <?php echo $loop_stud_num ?>; if(loop_num == total_loop_num) showToast(toast_array[0], toast_array[1], toast_array[2], toast_array[3]); }
}
else{
alert(data);
}
});
});
}
and the code to run the loop
$(".convert-multiple-result").click(function(){
var loop_num = <?php echo $loop_stud_num ?>;
for(let g = 1; g <= loop_num; g++){
var report_id = $(".report_card_id" + g).attr("id");
doCapture(report_id, g);
}
});
Each report card goes to a php file that saves the image in a folder. The only issue is that when i try to run the html2canvas in a loop, it does not show the student image or report card in some report cards. I forgot to mention that the report card content is a bit long.
Thanks.
I was using <img src="worker/open-image?name=<?php echo $school_image ?>&f=l" alt="logo"> to open the the image in the browser, the location of the image is in the open-image.php file. For some unknown reason, it was causing some images not to show sometimes and show some other time. I fixed it by using the location of the image directly in the img tag. e.g
<img src="../../logos/<?php echo $school_image ?>" alt="logo">
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');
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/
I googled abit and found a script, to reload a division.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
setInterval("$('#downshow').load('message.php');", 5000);
</script>
here downshow is my division where contents need to be refreshed. its like chat app, and messages between me and my friend needs to continoulsy reload.
My division downshow is something like below...
$getmessages= mysql_query("SELECT * FROM pvt_messages WHERE (user_from='$active_username' && user_to='$username') || (user_from='$username' && user_to='$active_username') ORDER BY id ASC ") or die(mysql_error());
while ($row = mysql_fetch_assoc($getmessages ))
{
$body = $row['msg_body'];
$date_send = $row['date'];
$opened = $row['opened'];
$whosent= $row['user_from'];
$whoreceived= $row['user_to'];
$seen=$row['opened'];
/////////////////////////////////////////////////////
$get_user_info = mysql_query("SELECT * FROM users WHERE (username='$whosent')");
////////////////////////////////////////////////////
$get_info = mysql_fetch_assoc($get_user_info);
$profilepic_info = $get_info['profile_pic'];
if ($profilepic_info == "") {
$profilepic_info = "./images/default_pic.jpg";
}
else
{
$profilepic_info = "./userdata/profile_pics/".$profilepic_info;
}
echo "
<div style='float: left;padding-top:5px; padding-left:20px;'>
<img src='$profilepic_info' height='50' width='40'>
</div>
<div style='margin-left:50px;padding-top:5px;'>
<a href='$whosent' style='color:black'> $whosent</a> $body
</div></br>
<div style=' margin-left:30px;'>
<font size='2px'>sent on: $date_send</font>
<br />
</div>
<hr />
";
}
I would have kept the content of this division in some other page i.e. message.php and then include it just as
<div id='downshow' style='bottom:0px;'class='see_message'>
<?php include("message.php"); ?>
</div>
But if i do this, there will be lots of problem like, session_start() issues, variable $active_username ll be obtained easily by $active_username=$_SESSION['username'] bt couldnt obtain varibale $username in message.php.
so instead of including the division content as "message.php". i want that code to be in main php file itself.
so want to as instead of
setInterval("$('#downshow').load('message.php');", 5000);
how can i use
setInterval("$('#downshow').load('????????????');", 5000);
load the division itself?????????????
Thankyou in advance :)
Try this..
setInterval(function(){ $('#downshow').load('message.php');
}, 5000);
This is not the best way to do this
You should look at AJAX and create a template for the HTML.
This way you can send information to the server (such as requesting items since a particular time, or from a particular 'room') and only send back the important data (send it back as JSON) and populate your template.
This will reduce traffic and load on your server and will reduce latency in your application as you are only sending back the important data - not the HTML to go with it!
Additionally use classes for each of the items instead of inline styles as it will make your code easier to maintain.
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?