Paginating an array of arrays (no db) without a limit - javascript

I have a 'display all' functionality on my site. Currently there are 7 sub-folders that are iterated through to display categories. (Empty folders are not shown, and more sub-folders may be added).
I don't want to set a limit [of images] per page, i just want to show all of the images for each folder on a different page.
Despite extensive googling and experimenting, the best i could come up with was a number of html pages being displayed, all appended one to the other, on one long page. (ugh!) I've been at it now since last night so i'm a bit fed up.
I have stripped back my displayall.php to it's basic functionality. Here's what it looks like at the moment (with no pagination):
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<link rel='stylesheet' type='text/css' href='css/bootstrap_combined.css'>
<link rel='stylesheet' type='text/css' href='css/style.css'>";
<title>Gallery Display</title>
</head>
<body>
<div id="wrapper">
<header>
<h1>The Ultimate Gallery Compiler</h1>
<div id='menu'><a class='head' href='index.html'>Upload Photo</a> <a class='head' href='gallery.html'>Browse Gallery</a></div>
</header>
<!---end header-->
<div id='content'>
<h2>Gallery: All Images</h2>
<?php
//$pages = isset($_GET['page'])?intval($_GET['page']-1):0; //get page
//$pageno = $_REQUEST['page'];
//compile an associative array
$subfolder= array('Fashion/LifeStyle'=>'1', 'Music/Video'=>'2','Sport/Leisure'=>'3','Electronics/Technology'=>'4','Pets/Animals'=>'5','Health/Beauty'=>'6','Other'=>'7' );
$carray=count($subfolder);
// iterate through the sub directories, and count them
$files = "images/*/*";
$sub=0;
foreach(glob($files) as $file)
{
$sub++; //total number of images
}
foreach ($subfolder as $subf=>$value)
{
$folder = "images/".$value."/";
$link = 'displayall.php?'.$value;
$mykey= $subf;
$counter = 0;
// Open the appropriate subfolder, and display its contents.
if ($dir = opendir($folder)) {
$images = array();
while (false !== ($file = readdir($dir))) {
if ($file != "." && $file != "..") {
$counter++;
$images[] = $file;
}
}
closedir($dir);
}
//don't show empty categories
if ($counter!== 0){
echo "<input type='hidden' id='current_page'/>";
echo "<input type='hidden' id='show_per_page' />";
echo "<h3>Category: ".$mykey."</h3><br>"; //display heading
echo "<h4>There are " .$sub. " photos in the <a href='gallery.html'>Gallery</a> to date</h4>"; //display total overall
echo '<div id="multi">';
foreach($images as $image) {
echo '<span class="gallery"><img src="';
echo $folder.$image;
echo '" alt="" width="200" height="auto" /></span>'; //show images
}
echo '</div>';
//$num= $pages +1;
echo "<br><strong>".$counter. " photos</strong><br>"; //display total per category
echo "<span id='pageNo'>Page Number: ".$value."</span><br>";
echo "Next";
echo "<br><br><hr><br>"; //put space and a line between the categories
};
//$pageno++;
}
?>
<footer>
<p class='foot'>© Copyright 2015-2016 MMA2 Rachel Gallen, Ysabel Pheifer and Rebecca Merrigan.</p>
</footer>
</div>
</body>
</html>
(It can be viewed here)
Any help on the pagination would be appreciated. All the tutorials seem to be either mysql related or dealing with a single array. V frustrating!
(open to php, jquery, javascript or bootstrap solutions!)
Thanks and happy chrimbo
Rachel
edit: former edit removed

Your page is looping through all the subfolders, it looks like an attempt was made to only display subfolder being specified by the querystring parameter page. This can be accomplished with a minor edit to your PHP:
<?php
$pages = isset($_GET['page'])?intval($_GET['page']):1; //get page
//$pageno = $_REQUEST['page'];
//compile an associative array
$subfolder= array('Fashion/LifeStyle'=>'1', 'Music/Video'=>'2','Sport/Leisure'=>'3','Electronics/Technology'=>'4','Pets/Animals'=>'5','Health/Beauty'=>'6','Other'=>'7' );
$carray=count($subfolder);
// iterate through the sub directories, and count them
$files = "images/*/*";
$sub=0;
foreach(glob($files) as $file)
{
$sub++; //total number of images
}
$value = $pages;
$folder = "images/".$value."/";
$link = 'displayall.php?page='.$value + 1;
//$mykey= $subf;
$arrayKeys = array_keys($subfolder);
$mykey = $arrayKeys[$value];
$counter = 0;
// Open the appropriate subfolder, and display its contents.
if ($dir = opendir($folder)) {
$images = array();
while (false !== ($file = readdir($dir))) {
if ($file != "." && $file != "..") {
$counter++;
$images[] = $file;
}
}
closedir($dir);
}
//don't show empty categories
if ($counter!== 0){
echo "<input type='hidden' id='current_page'/>";
echo "<input type='hidden' id='show_per_page' />";
echo "<h3>Category: ".$mykey."</h3><br>"; //display heading
echo "<h4>There are " .$sub. " photos in the <a href='gallery.html'>Gallery</a> to date</h4>"; //display total overall
echo '<div id="multi">';
foreach($images as $image) {
echo '<span class="gallery"><img src="';
echo $folder.$image;
echo '" alt="" width="200" height="auto" /></span>'; //show images
}
echo '</div>';
//$num= $pages +1;
echo "<br><strong>".$counter. " photos</strong><br>"; //display total per category
echo "<span id='pageNo'>Page Number: ".$value."</span><br>";
echo "Next";
echo "<br><br><hr><br>"; //put space and a line between the categories
};
//$pageno++;
?>
Summary of Changes:
I un-commented the $pages variable so it pulls from the query string parameter.
It also looks like you tried to send that query string via the $link variable, but the format was not correct. I updated that to $link = 'displayall.php?page='.$value + 1;
Finally, I removed the for loop and set $value to the current $page parameter so only one subfolder would be shown on a page.
Changes Made After Edit #1
The ternary operation on $pages was setting the value to 0, resulting in the error when looking for /images/0/. Changed to $pages = isset($_GET['page'])?intval($_GET['page']):1;
Added an array to handle the keys from the associative array, since the querystring is using integer values instead of category names.
$arrayKeys = array_keys($subfolder);
$mykey = $arrayKeys[$value];
You might want take a long hard look at passing string values instead of integer values to $page. It'll make for better SEO, better folder names, and removes the need to have an associative array to map the integers to a category name and back again.
Final Notes:
This certainly has room for expansion, you might consider error checking to make sure the value is inbounds and the folder is valid. Previous and next links, and quick navigation to a specific page number might also be useful.
Hope that helps!

Related

PHP Code to Close Unclosed Anchor Tags

I'm working on code that truncates an database entry and puts that onto a webpage, but because of the truncation it will often cut off in the middle of link anchor tag. Usually i can deal with this by adjusting the amount of characters being pulled, but because 5 entries are pulled at a time to be displayed i end up going back and forth at lot finding the percent balance as i can adjust the characters up which fixes one entry, but causes another problem with another entry.
I need to come up with a way to have a php function automatically close these so they don't cause problems and make the page a giant link.
$SQL = "SELECT * FROM Words WHERE Date_Created = DATE('2016-10-06') AND category = 'Article' ORDER BY ID DESC LIMIT 5";
$result = mysql_query($SQL);
while($row = mysql_fetch_array($result))
{
echo '<div class="storylist2">';
echo "<br/>";
echo '<h2>' .stripslashes($row['Title']). '</h2>';
$s = stripslashes($row['Word']);
$s = substr($s, 0,800); //adjust as necessary
$s = substr($s, 0, strrpos($s, "."));
$s .= "...";
echo '<h6>'. $row['Display_Date'].'</h6>';
echo '<h6>'. $row['Author']. '</h6>';
echo closetags("$s");
echo "<br/>";
if($row['url'] != "")
{
echo "<br/>";
echo '<span class="articlelink">(more)';
echo "<br/>";
}
else {
echo "<br/>";
echo '(more)</span>';
echo "<br/>";
}
echo "<br/>";
echo "<br/>";
echo "</div><hr style=\"color: #006699; margin: 10px 20px; \"/>";
I have listed above the code that i currently have for the pulling the entries onto the webpage, I've heard that there is way to make sure the truncation doesn't cut off in the middle of a tag but in all honesty i don't know how to do this. Also in the past few days i have found some PHP that closes tags which is referenced by this echo closetags("$s"); but unfortunately i haven't been able to get to work for the anchor tags. Please help thank you!
You can remove the <a> tags and leave just the anchor text for any string by running it through preg_replace before truncating it:
$no_a_tags = preg_replace('/<a.*?>([^>]*)</a>/i', '$1', $with_a_tags);

Passing variables from JS to PHP

I'm trying to pass a variable from JS to PHP but so far no luck. I've been searching here for solution, but it seems that nothing helps..
Ok, I have php file with pagination:
$pagination .= '<li>'.$i.'</li>';
Paginate_click launches js function:
$(".paginate_click").click(function (e) {
$("#results").prepend('<div class="loading-indication"><img src="ajax-loader.gif" /> Loading...</div>');
var clicked_id = $(this).attr("id").split("-"); //ID of clicked element, split() to get page number.
var page_num = parseInt(clicked_id[0]); //clicked_id[0] holds the page number we need
$('.paginate_click').removeClass('active'); //remove any active class
//post page number and load returned data into result element
//notice (page_num-1), subtract 1 to get actual starting point
$("#results").load("views/fetch_articles.php", {'page':(page_num-1)}, function(){
$(window).scrollTop(0);
});
$.post('views/articles_list.php', {'page':(page_num)});
$(this).addClass('active'); //add active class to currently clicked element (style purpose)
return false; //prevent going to herf link
});
In php file I need information which page of pagination I'm currently on so I want to retrieve page_num value back to my php. I tried this:
$.post('views/articles_list.php', {'page':(page_num)});
And in php:
$page_number = $_POST["page"];
I tried also many other options, but nothing helps. I thought it will be easier :/
As you probably noticed there's another php file (fetch_articles.php) and in this case $_POST["page"]; works. But for articles_list.php I can't use load function.
EDIT: What I want and entire code.
I have simple and nice pagination. The only problem is that it has no option for prev/next and it shows all the buttons. It's a problem when you have a lot of pages. So my idea is to shrink it down and instead of heaving 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,16,17,18,19 and so on I want this:
prev,1,2,3...67,68,next. To do this I need to pass to my php file an information about actual page. With this variable I can calculate everything and organize my pagination with for/if/else statements.
The code.
articles_list.php:
<?php
include("../config/connection.php");
include('../config/css.php');
$results = mysqli_query($dbc_connection,"SELECT COUNT(*) FROM articles");
$get_total_rows = mysqli_fetch_array($results); //total records
//break total records into pages
$pages = ceil($get_total_rows[0]/$item_per_page);
//create pagination
if($pages > 1)
{
$pagination = '';
$pagination .= '<ul class="paginate">';
for($i = 1; $i<=$pages; $i++)
{
$pagination .= '<li>'.$i.'</li>';
}
$pagination .= '<li>'.$page_number.'</li>'; // only to check if variable is passed
$pagination .= '</ul>';
}
?><!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="js/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="js/pagination.js"></script>
</head>
<body>
<?php $page_number = $_POST["page"];
echo $page_number; // only to check if variable is passed ?>
<div id="results"></div>
<?php echo $pagination; ?>
</body>
</html>
pagination.js:
$(document).ready(function() {
$("#results").load("views/fetch_articles.php", {'page':0}, function() {$("#1-page").addClass('active');}); //initial page number to load
$(".paginate_click").click(function (e) {
$("#results").prepend('<div class="loading-indication"><img src="ajax-loader.gif" /> Loading...</div>');
var clicked_id = $(this).attr("id").split("-"); //ID of clicked element, split() to get page number.
var page_num = parseInt(clicked_id[0]); //clicked_id[0] holds the page number we need
$('.paginate_click').removeClass('active'); //remove any active class
//post page number and load returned data into result element
//notice (page_num-1), subtract 1 to get actual starting point
$("#results").load("views/fetch_articles.php", {'page':(page_num-1)}, function(){
$(window).scrollTop(0);
});
$.post('views/articles_list.php', {page:page_num}, function(data){});
$(this).addClass('active'); //add active class to currently clicked element (style purpose)
return false; //prevent going to herf link
});
});
fetch_articles.php:
<?php
include("../config/connection.php"); //include config file
//sanitize post value
$page_number = filter_var($_POST["page"], FILTER_SANITIZE_NUMBER_INT, FILTER_FLAG_STRIP_HIGH);
//validate page number is really numaric
if(!is_numeric($page_number)){die('Invalid page number!');}
//get current starting point of records
$position = ($page_number * $item_per_page);
//Limit our results within a specified range.
$result = mysqli_query($dbc_connection,"SELECT * FROM articles ORDER BY id DESC LIMIT $position, $item_per_page");
//output results from database
while($row = mysqli_fetch_array($result))
{
?>
<h2><?php echo $row['title']; ?></h2>
<p><i><?php echo 'By '.$row['author']; ?></i></p>
<p><?php echo $row['header']; ?></p>
Read<br>
<hr>
<?php
}
?>
Try removing the parenthesis around page_num:
$.post('views/articles_list.php', {'page':page_num});
You didn't said in which one of the requests you can't get the value you're trying to pass. So, I'm guessing it is in the first one:
$("#results").load(...);
The problem here is that you're using the .load() method, which is equivalent to .get(). So, when you try, in the PHP file to get $_POST["page"], it will not be there, because it is actually in the $_GET array.
I may be missing something here, but couldn't you just append a query string to the url manually?
$.post('views/articles_list.php?pn=' + page_num);
Then in your fetch_articles.php you just pull it off with
$page_number = $_GET["pn"];
If that fails you can always use a cookie.
Instead of
$.post('views/articles_list.php', {'page':(page_num)});
try
$.post('views/articles_list.php', {page:page_num}, function(data){
console.log(data);
},'json');
And also double check if 'views/articles_list.php' is the correct path. If you were using Chrome, kindly read the parsing via right click -> inspect elements -> Network.
Addition(After posted your edit code) :-
Please remove the Doctype and HTML and leave something like this.
<?php
include("../config/connection.php");
include('../config/css.php');
$results = mysqli_query($dbc_connection,"SELECT COUNT(*) FROM articles");
$get_total_rows = mysqli_fetch_array($results); //total records
//break total records into pages
$pages = ceil($get_total_rows[0]/$item_per_page);
//create pagination
if($pages > 1)
{
$pagination = '';
$pagination .= '<ul class="paginate">';
for($i = 1; $i<=$pages; $i++)
{
$pagination .= '<li>'.$i.'</li>';
}
$pagination .= '<li>'.$page_number.'</li>'; // only to check if variable is passed
$pagination .= '</ul>';
}
//Assuming you're doing ajax here. so either pagination or page number posting back? if both try below.
$page_number = $_POST["page"];
echo json_encode(array("pagination"=>$pagination,"pageNumber"=>$page_number));
?>
Hope it helps.

Math function while echo from extern text file

This is my form where I send rating information to my textfile.txt.
<form name="Star" id="Star">
<div id="rating-area" class="shadow">
<img src="star-icon.png" id="thumb1" data-value="1" />
<img src="star-icon.png" id="thumb2" data-value="2" />
<img src="star-icon.png" id="thumb3" data-value="3" />
<img src="star-icon.png" id="thumb4" data-value="4" />
<img src="star-icon.png" id="thumb5" data-value="5" />
</div>
</form>
<script>
jQuery('div#rating-area img').click(function(e){
var val = jQuery(this).data('value') ;
console.log(val) ;
jQuery.post('post.php',{ Star : val },function(data,status){
console.log('data:'+data+'/status'+status) ;
}) ;
}) ;
</script>
And this is my php call:
<?php
$file = file("textfile.txt");
$file_content = file_get_contents("textfile.txt");
$file_content_separated_by_dash = explode("-", $file_content);
echo "Number of votes in file: " . count($file_content_separated_by_dash) . "<br>";
$sum = 0;
foreach ($file_content_separated_by_dash as $vote) {
$sum = $sum + $vote;
}
echo "Total: " . $sum;
?>
I don't seems to get the hang of this. When I run the progress to count number of votes in the textfile.txt I do only get the first vote as the total sum. No matter if I reload the page or not. It's still that very first vote that shows up. I've checked the textfile.txt. It updates itself whenever the "star-rating" is "onclick".
As well the "number of votes". To see how many times someone has clicked on it. It stays on 1 through the whole time.
What have I missed?
Im still quite a newbie with php. So if I forget any necassary information please tell me and I will try to update the post with that info.
Your textfile content doesn't match with code.
Numbers in textfile must be separated with - to work the current code..
If you cant modify your Textfile insertion then change the reading code like this
<?php
$file = file("textfile.txt");
$file_content = file_get_contents("textfile.txt");
$file_content_separated_by_dash = str_split($file_content);
echo "Number of votes in file: " . count($file_content_separated_by_dash) . "<br>";
$sum = 0;
foreach ($file_content_separated_by_dash as $vote) {
$sum = $sum + intval($vote);
}
echo "Total: " . $sum;
?>
Can you post your textfile.txt file? Code seems okay, need to check how data is being saved in text file.
Your file doesn't have -, it has only numbers.
so you can Use this code
$numbers = file_get_contents("textfile.txt");
$count = strlen($numbers);
echo 'Total votes'.$count;
for($i = 0; $i < count; $i++) {
echo $numbers[$i] . '<br />';
}

Headlines links wont be created

I'm currently busy with a ticketsystem. A headline will be displayed. When the headline has over 40 characters, the headline will be cut and the '...' will be added. Now, when I try to link the headlines to its messages, it won't create a link. I'm using Ajax to do this without a page refresh, but no links are being created, which means that the full ticket wont be openend. I've tried several things but I cant get it to work. I'm also not that familiar with it :')
This is my piece of JS:
//Show ticket
function showTicket(id) {
$.ajax({url:"readTicket.php?ticket_id=" + id});
}
This is the piece of code supposed to link the headlines:
<?php echo '<a id="showTicketNow" onclick="showTicket('.$stt["ticket_id"].')">' ?>
<?php if(strlen($stt['subject']) > 40) $stt['subject'] = substr($stt['subject'], 0, 40).'...';
echo $stt['subject'] ?>
<?php echo '</a>' ?>
This is my readTicket.php
$user_id = $_SESSION['user_id'];
$ticket_id = mysqli_real_escape_string($mysqli, $_GET['ticket_id']);
$getTicketInfo = mysqli_query($mysqli,"SELECT * FROM tickets WHERE ticket_id = '$ticket_id' AND user_id = '$user_id'");
while ($row=mysqli_fetch_array($getTicketInfo)) {
$subject = $row['subject'];
$message = $row['message'];
}
echo '<div class="showTicket display subject">'.stripslashes($subject).'</div>
<div class="showTicket display message">'.stripslashes($message).'</div>';
Thanks in advance..
Try this, you were missing all of the syntax goodness.
echo'<a id="showTicketNow" onclick="showTicket('.$stt["ticket_id"].')">';
if(strlen($stt['subject']) > 40){
$stt['subject'] = substr($stt['subject'], 0, 40).'...';
}
echo $stt['subject'];
echo '</a>';
You need to specify href attribute of <a> tag, something like this:
<?php echo '<a href="javascript:void(0);" id="showTicketNow" onclick="showTicket('.$stt["ticket_id"].')">' ?>

JavaScript dropdown menu does not work in IE8

I'm using an on change for a drop down menu to display information once a choice is chosen from the dropdown. This works fine in Firefox and Chrome but I have been hoodwinked into having to use ie8 and this on change does not seem to fire. Any help would be much appreciated. Its a mix of php and html the lower part is js which outputs info when chosen.
echo "<p><h2> To View a Route: </h2><br> Pick a routes name from the list and all its information can be viewed below the selection box.</p>";
echo "<p><FORM METHOD=\"post\" ACTION=\"controller.php\">";
echo "<select class=\"toggle-data\" name='selectallrouteinfo'>";
echo "<option value=\"\">Choose a Route </option>";
for ($i = 0; $i < sizeof($list1); $i++) { //going through each element of array and outputting route
if (is_string($list1)) {
echo "<option value=\"\" data-toggle = \"$id1\" >$list1</option>";
} else {
$space = " ";
$id = $list4[$i];
$id1 = "#" . $list4[$i];
echo "<option data-toggle = \"$id1\" value=\"$id\">" . $list1[$i] . $space . $id . "</option>";
$idHolder[$i] = $id; //array for holding ids so that it passing the correct id to my loops below
}
}
echo "</select></form></p>";
for ($k = 0; $k < sizeof($idHolder); $k++) { //my outer loop is going through the ids, fitting correct id to the div and dbm obj
echo "<div id=\"$idHolder[$k]\" style=\"display: none;\">
";
$allRouteInfo = $DBM1->getAllRouteData($idHolder[$k]);
for ($j = 0; $j < sizeof($allRouteInfo); $j++) { // my inner loop is going through each element of array and outpting all route info
if (is_string($allRouteInfo)) {
echo $allRouteInfo; //if theres no info, there is no array, it has returned a string
} else {
echo $allRouteInfo[$j]; //if there is arry, happy days
}
}
echo "</div>";
//below is a js/jquery script for outputting my choice in the select of route info
echo " <script>$('.toggle-data').on('change', function() { //jquery for printing my valuable info on change
var toggle = this.options[this.selectedIndex].getAttribute('data-toggle'),
toggle_class = 'unique_classname';
$('.'+toggle_class+', '+toggle).toggle().removeClass(toggle_class);
$(toggle).addClass(toggle_class);
}); </script>";
echo " </div>";

Categories