What is the most efficient way to use sidebar menu? - javascript

So if I have to make a sidebar menu like schools websites, in which active clicked link is highlighted after the page loads. It uses individual pages like
<a target="_top" href="default.asp">HTML HOME</a>
<a target="_top" href="html_intro.asp">HTML Introduction</a>
<a target="_top" href="html_editors.asp">HTML Editors</a>
<a target="_top" href="html_basic.asp">HTML Basic</a>
<a target="_top" href="html_elements.asp">HTML Elements</a>
But the one I built on my own is created with PHP so what happens in that one is the title or name of menu item is changed to lowercase and saved in database in same row called class which is used for active link highlighting. So what happens when sidebar link is clicked is only content of summary div's content
(which is right to the sidebar) is changed while sidebar and navigation bar stays same. So it stays on the same page and retrieves data from database and puts in summary div.
<body class='noPadding'>
<div class='bigNav'> <!-- top navbar -->
<img src="images/logo2.png"/>
</div>
<?php
if(isset($_GET['subject'])){
$subject=$_GET['subject'];
?>
<div class='container'>
<div class='leftLayout' style='padding-top:70px;background-color:#EBEBEB'>
<ul class="fullFit">
<?php
$query="SELECT * FROM `study` WHERE `subject`='$subject'";
$run=mysqli_query($conn,$query);
while($row=mysqli_fetch_array($run)){
$topic=$row['topic'];
$class=$row['class']; ?>
<li class="<?php echo $class?>">
<a href='<?php echo $sitename ?>/web.php?subject=<?php echo $subject?>&topic=<?php echo $class?>'>
<?php echo $topic?>
</a>
</li>
<?php } ?>
</ul>
</div>
<?php
if(isset($_GET['topic'])) {
$active_id=$_GET['topic'];
$topic=$_GET['topic'];
$query="SELECT summary FROM `study` WHERE `class`='$active_id'";
$run=mysqli_query($conn,$query);
$row=mysqli_fetch_array($run);
$summary=$row[0];
?>
<div class='summary'> <?php echo $summary ?> </div>
<?php } ?>
</div>
<script>
$(document).ready(function(){
$(".<?php echo $active_id ?>").addClass("current");
});
</script>
<?php } ?>
</body>
And also if I have to make individual pages instead like many websites including W3Schools does, do I have to create a new file each time and include navigation bar and sidebar(which are supposed to stay same on every link) in each file?
How do they manage it?

I hope this is not too much of a departure from your current structure.
I don't intend to lead you down a rabbit hole.
That being said, it sounds like you could code everything into a single PHP file. Note that this is just one of many methods, highly dependent the scope of your project and individual coding style.
Databases
subject
`id`
`name`
topic
`id`
`subject_id`
`name`
`summary`
PHP
<?php
// define database functions
function getAllSubjects($conn) {
$sql="SELECT * FROM `subject` WHERE 1;";
$q=$conn->query($sql);
return $q;
}
function getSubject($conn,$subject_id=false) {
$r=false;
if (is_numeric($subject_id)) {
$sql = "SELECT * FROM `subject` WHERE `id`=?;";
$q = $conn->prepare($sql);
$q->bind_param('i',$subject_id);
$q->execute();
$r=$q->fetch_assoc();
}
return $r;
}
function getSubjectTopics($conn,$subject_id=false) {
$q=false;
if (is_numeric($subject_id)) {
$sql = "SELECT * FROM `topic` WHERE `subject_id`=?;";
$q = $conn->prepare($sql);
$q->bind_param('i',$subject_id);
$q->execute();
}
return $q;
}
function getTopic($conn,$topic_id=false) {
$r=false;
if (is_numeric($topic_id)) {
$sql = "SELECT * FROM `topic` WHERE `id`=?;";
$q = $conn->prepare($sql);
$q->bind_param('i',$topic_id);
$q->execute();
$r=$q->fetch_assoc();
}
return $r;
}
// get URL parameters
$subject_id = !empty($_GET['s']) && is_numeric($_GET['s'])
? $_GET['s']
: false;
$topic_id = !empty($_GET['t']) && is_numeric($_GET['t'])
? $_GET['t']
: false;
// fetch all subjects from database
$subjectsQ=getAllSubjects($conn);
// fetch current subject
$thisSubject = $subject_id
? getSubject($conn,$subject_id)
: false;
// fetch current subject topics
$thisSubjectTopicsQ = !empty($thisSubject)
? getSubjectTopics($conn,$subject_id)
: false;
// fetch current topic
$thisTopic = $topic_id
? getTopic($conn,$topic_id)
: false;
// display subject navigation
while($subject = $subjectsQ->fetch_assoc()){
// determine if this subject is selected
$sel = !empty($thisSubject) && $thisSubject['id']==$subject['id']
? true
: false;
// define the URL
$url = '?s='.$subject['id'];
// display nav item for this subject
echo '<a href="' . $url . '"'
. ($sel?' class="sel"' : '')
. '>' . $subject['name']
. '</a>';
}
// if there are subject topics to display...
if ($thisSubjectTopicsQ && $thisSubjectTopicsQ->num_rows > 0) {
// loop through this subject's topics
while($topic=$thisSubjectTopicsQ->fetch_assoc()){
// determine if this topic is selected
$sel = !empty($thisTopic) && $thisTopic['id']==$topic['id']
? true
: false;
// define the URL
$url = '?s='.$thisSubject['id'].'&t='.$topic['id'];
// display nav item for this topic
// (alternate way to display the link)
?><a href="<?=$url?>"<?=$sel?' class="selected"':''?>><?php
echo $topic['name'];
?></a><?php
}
}
// if there is a topic to display
if (!empty($thisTopic)) {
// display topic summary
echo $thisTopic['summary'];
}
That's a basic example. Granted, it doesn't include any of the HTML structure.
It's also possible to join the two tables so that you don't need to do so much fetching. For example, fetching a topic could also return its subject:
$sql="SELECT s.`id` AS `subject_id,
s.`name` AS `subject_name`,
t.`id` AS `topic_id,
t.`name` AS `topic_name`,
t.`summary` AS `topic_summary`
FROM `topic` t
LEFT JOIN `subject` s ON (s.`id`=t.`subject_id`)
WHERE t.`id`=?";

Related

Change of div in the same page without refresh

In one of my pages, I have an <a> tag. When I click it, I am passing the variable as a GET parameter and retrieving it in the same page and displaying the details.
The code to get the parameters:
if(isset($_GET['CatId']))
{
$CatId= $_GET['CatId'];
}
else $CatId=0;
if(isset($_GET['MainProductId']))
{
$MainProductId= $_GET['MainProductId'];
$FilterAllProductQuery ="WHERE Product.MainProductId = '$MainProductId'";
$FilterProductQuery = "AND Product.MainProductId = '$MainProductId'";
}
else
{
$MainProductId=0;
$FilterAllProductQuery="";
$FilterProductQuery="";
}
The <a> tag:
<a href='Products.php?CatId=<?php echo $CatId;?>&MainProductId=<?php echo $id;?>' ><?php echo $row["MainProdName"] ?></a>
The details to be displayed:
if($CatId == 0)
{$sql = "SELECT *,Product.Id AS ProdId, Product.Name as ProdName FROM Product $FilterAllProductQuery ";}
else
{$sql = "SELECT * ,Product.Id AS ProdId, Product.Name as ProdName FROM Product INNER JOIN MainProduct ON MainProduct.Id = Product.MainProductId
INNER JOIN Category ON Category.Id = MainProduct.CategoryId WHERE Category.Id = '$CatId' $FilterProductQuery ";}
$result1 = $dbcon->query($sql);
if ($result1->num_rows > 0) {
while ($row = $result1->fetch_assoc()) {
$id = $row["ProdId"];
// $image=$row["ImagePath1"];
$qty = $row["Quantity"];
?>
<li class="col-lg-4">
<div class="product-box">
<span class="sale_tag"></span>
<div class="row">
<img src='themes/images/<?php echo $row["ImagePath1"]; ?>' height='200' width='250'> </a></div></div></li>
Now the code is working fine, but what's happening is that when I click the <a> tag, as I am passing the get parameters, the page is refreshing. As all the code are on the same page, I don't want the page to be refreshed. For that, I need to use Ajax request. How can I do that?
I would make an onclick() event on the a tag like so:
<?php echo '<a c_id="'.$CatId.'" MainProductId="'.$id.'" onclick="sendProduct()">'.$row["MainProdName"].'</a>';
Afterwards i would in a .js file write a simple function called sendProduct() and inside i would do an ajax request to a page named ex: insertproduct.php, get the information back and Insertproduct.php would process the data and you could use .html() or .append() to assign the data to the div showing the data with a normal id.
The c_id, MainProductId are custom attributes you could recieve in the .js file as $("#youraTag").attr("c_id");
There's a really good guide here on basic ajax: https://www.youtube.com/watch?v=_XBeGcczFJo&list=PLQj6bHfDUS-b5EXUbHVQ21N_2Vli39w0k&index=3&t=1023s
First you have to remove the href of the link and give it an id.
<a id='link'>
<?php echo $row["MainProdName"] ?>
</a>
Then you put this jQuery into your page. Note, you need to have a div in which you are going to put in all your obtained results. I reffered to this div in the code as #mydiv.
$("#link").click(function(){
$("#mydiv").load("Products.php?CatId=<?php echo $CatId;?>&MainProductId=<?php echo $id;?>");
});

Search box for website

I have tried this code and this is working only for one page when i am in basintap page but i want to know how to search anything when i am in another page?
<?php
$query = $_GET['query'];
$min_length = 2;
if(strlen($query) >= $min_length){
$sql ="Select * from basintap where keywords like '%keywords%'";
$run_query = mysqli_query($con,$sql);
if(mysqli_num_rows($run_query) > 0){
while($row = mysqli_fetch_array($run_query)){
$id = $row['id'];
$cat = $row['cat'];
$brand = $row['brand'];
$name = $row['name'];
$image = $row['image'];
echo "<div class='col-md-4'>
<div class='panel panel-info'>
<div class='panel-heading'>$name</div>
<div class='panel-body'>
<img src='basintap/$image' style='width:160px; height:250px;'/>
</div>
</div>
</div> ";
}
}
?>
If you have a separate table per page, then you are going to have to restructure your database in order to solve your problem using a home grown solution. Keep all pages in one table, distinguished by a separate field and/or index.
Alternatively if it's too much hassle, just plug Algolia into your site.
You should probably change your "basintap" string from your query with the table name you'd like to search into.
$sql ="Select * from [place-table-name-here] where keywords like '%keywords%'";

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

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!

Creating a clickable list from DB and returning relevant DB field data in a web page element

I'm trying to get records from the database using a client side (Javascript) clickable list. The problem is that I want the clickable links to be sourced from the data in the database in the first place (MySQL).
I'm having problems passing the data to create the clickable list. I've tried various ideas and hit stumbling blocks to do with client side and server side programming (and briefly looked into JQuery but it appears difficult to do). I've been attempting this with HTML, PHP, Javascript, JQuery (briefly) and MySQL.
So I need to SELECT post_id, post_title FROM posts and make post_title clickable in the list but using the associated post_id to find the relevant data in the DB and post this via innerHTML into another element. Any ideas?
index.php <- List
<html>
<head>
<script src="jquery.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<?php
$sql = 'SELECT post_id AS "id", post_title AS "title" FROM posts';
$posts = $mysqli->query($sql);
?>
<ul id="post_list">
<?php
foreach ($posts as $post) {
?>
<li><a href="#" data-id="<?php echo $post['id'] ?>"><?php
echo $post['title']
?></a></li>
<?php
}
?>
</ul>
<div id="post_content"></div>
</body>
</html>
script.js <- Interactivity (requires jquery)
$(document).ready(function() {
$('#post_list').on('click', 'li a', function() {
$('#post_content').load('get_post.php?id=' + $(this).data('id'));
});
});
get_post.php <- Selected post
<?php
if (!empty($_GET['id'])) {
$sql = 'SELECT * FROM posts WHERE post_id = '.$_GET['id'].'';
$res = $mysqli->query($sql);
if (($post = $res->fetch_assoc())) {
?>
<h1><?php echo $post['post_title'] ?></h1>
<p><?php echo $post['post_body'] ?></p>
<div class="pull-right"><?php echo $post['post_author'] ?></div>
<?php
} else {
header("HTTP/1.0 404 Not Found");
die();
}
}
?>
Maybe I've not understand correctly, but this can solve your problem :
You need at least 2 files (3 if you separate the Js Code)
Index.php :
$arrayItems = array()//The array containing your datas from the database
echo '<div id="listItems">';
for($i = 0; $i < count($arrayItems); $i++){
echo '<div class="item" idFromDB="'.$arrayItems[$i]['post_id'].'">'.$arrayItems[$i]['post_title'].'</div>';
}
echo '</div>';
echo '<div id="containerDetailsItem"></div>';
javascript.js : (which is more Jquery)
$(document).ready(function() {
$('.item').live('click', function(){
$('#containerDetailsItem').load('myAjax.php?idItem='+$(this).attr('idFromDB'));
});
});
and the ajax File (myAjax.php) :
if(isset($_GET['idItem']) && $_GET['idItem'] != ''){
$idItem = (int)$_GET['idItem'];
//Get the infos from the database with the ID given
echo 'datas from BDD';
}
And I think that will do what you need. This is simple PHP with Jquery and Ajax.
PS : There is just minified code. You'll need to include Jquery (from google maybe) and to make the link between index.php and Javascript.js

Changing PHP function to Javascript/AJAX validation

I want to use AJAX/Javascript with PHP to carry out this following function and not have it all done by PHP itself. I have created a function which deletes an item from the MySQL database. It gives a validation to the user if they want to remove it by selecting Yes or No.
However, how would i change this so that it does the same function but the validation appears as a popupbox, and when Yes or OK is pressed it deletes the item from the database and reloads the page to show it has been removed.
I have provided the PHP code which relates to this function, but i want to specifically change this to using AJAX/Javascript as well in accordance with PHP.
<?php
// Delete Item Question to Admin, and Delete Product if they choose
if (isset($_GET['deleteid'])) {
echo 'Do you really want to delete product with ID of ' . $_GET['deleteid'] . '? Yes | No';
exit();
}
if (isset($_GET['yesdelete'])) {
// remove item from system and delete its picture
// delete from database
$id_to_delete = $_GET['yesdelete'];
$sql = mysqli_query($link,"DELETE FROM products WHERE id='$id_to_delete' LIMIT 1") or die (mysql_error());
// unlink the image from server
// Remove The Pic -------------------------------------------
$pictodelete = ("../inventory_images/$id_to_delete.jpg");
if (file_exists($pictodelete)) {
unlink($pictodelete);
}
header("location: inventory_list.php");
exit();
}
?>
<?php
// This block grabs the whole list for viewing
$product_list = "";
$sql = mysqli_query($link,"SELECT * FROM products ORDER BY date_added DESC");
$productCount = mysqli_num_rows($sql); // count the output amount
if ($productCount > 0) {
while($row = mysqli_fetch_array($sql)){
$id = $row["id"];
$product_name = $row["product_name"];
$price = $row["price"];
$stock = $row["stock"];
$date_added = strftime("%b %d, %Y", strtotime($row["date_added"]));
$product_list .= "Product ID: $id - <strong>$product_name</strong> - £$price - Stock: $stock - <em>Added $date_added</em> <a href='inventory_edit.php?pid=$id'>edit</a> • <a href='inventory_list.php?deleteid=$id'>delete</a><br />";
}
} else {
$product_list = "You have no products listed in your store yet";
}
?>
Your JS-File
$(document).ready(function() {
$('.delete').click(function() {
event.preventDefault();
var deleteId = $(this).parent().attr('id').val();
$.get('path/to/you/phpfile', {deleteId: deleteid}, function(data) {
var confirm = confirm(data);
if (confirm==true) {
$.get('path/to/you/phpfile', {yesdelete: 1});
}
});
});
});
In your PHP-File you have to remove header('Location: ...') and the block which grabs the list, wrap it in a function or etract it to another php file to call it with the a simliar ajax-command I used above. And you have to change th $product_list in the while-loop.
Product ID: <div id="$id">$id - <strong>$product_name</strong> - £$price - Stock: $stock - <em>Added $date_added</em> <a href='inventory_edit.php?pid=$id'>edit</a> • <div class="delete">Delete</div></div><br />
jQuery get the id-value of his parent-div. It´s actually not the best way, but something like this should work.

Categories