How do you pass a A HREF value from a php function? - php

So with this code we pull in some data from a mysql database with php. Then everything works, except the a href formatting (for bootstrap). This code is really long, so I tried to get the parts that pertain to the problem.
The drop down works great when it isn't part of this function and all the data pulls through like it should. The function somehow throws out the bootstrap class, id, role, etc. in a href.
function menu_element_builder($values) {
$links = '';
foreach($values as $value) {
if(is_array($value['args'])) {
$links .= (!empty($value['href']))?'
/* this a href part doesn't pull through the ID, Role, data-toggle, or class */
<a id="dLabel" role="button" data-toggle="dropdown" class="btn btn-primary" href="'.$value['href'].'">'.$value['name'].'<span class="caret"></span>
</a>
<ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">':'
<li class="dropdown-submenu">
'.$value['name'].'
</li> //it has more than this, keeping it simple
</ul>
return $links;
}
(an array of $link values are listed)
//This is part of case break statements to know which icons to load
$themed_elements = menu_element_builder($link_values);
<html>
<body>
<div class="dropdown">
<?php echo $themed_elements; ?>
</div>
</body>
</html>
old code
function menu_element_builder($values) {
$links = '';
foreach($values as $value) {
if(is_array($value['args'])) {
$links .= (!empty($value['href']))?'<li><a class="dir" href="'.$value['href'].'">'.$value['name'].'</a><ul>':'<li><span class="dir">'.$value['name'].'</span></li></ul>';
<script type="text/javascript">
$(function(){
$(".dir").click(function(){
//this.addclass('ul.dropdown li:hover');
});
});

Related

How do I run my php function through Ajax and loop through the results?

So I am trying to build a simple search function for my website, and I don't want to have to refresh the page to return results. The code that i have here works perfectly, But I don't know how to Implement this using Jquery. I mainly have 2 pages, index.php and library.php
The section from the library.php that handles the search is as follows.
require_once('auth/includes/connect.php');
class MainLib
{
public function search($keyword){
try {
$db = DB();
$query = $db->prepare("SELECT houses.*, users.user_id FROM houses JOIN users ON users.user_id=houses.ownerid WHERE houses.location=:keyword");
$query->bindParam(":keyword", $keyword, PDO::PARAM_STR);
$query->execute();
if ($query->rowCount() > 0) {
return $query->fetchAll(PDO::FETCH_OBJ);
}
} catch (PDOException $e) {
exit($e->getMessage());
}
}
}
And the Section From the index.php that prints the results is as follows
<?php $hdata = new MainLib();
if(isset($_POST[$search])){
$houses = $hdata->search($search); // get user details
foreach($houses as $house){
?>
<div class="single-property-box">
<div class="property-item">
<a class="property-img" href="#"><img src="houses/<?php echo $house->main_image ?>" alt="#">
</a>
<ul class="feature_text">
<?php
if($house->featured=='true'){
?>
<li class="feature_cb"><span> Featured</span></li>
<?php }?>
<li class="feature_or"><span><?php echo $house->gender ?></span></li>
</ul>
<div class="property-author-wrap">
<a href="#" class="property-author">
<img src="dash/auth/users/<?php echo $house->profilepic ?>" alt="...">
<span><?php echo $house->title ?>. <?php echo $house->surname ?></span>
</a>
<ul class="save-btn">
<li data-toggle="tooltip" data-placement="top" title="" data-original-title="Bookmark"><i class="lnr lnr-heart"></i></li>
<li data-toggle="tooltip" data-placement="top" title="" data-original-title="Add to Compare"><i class="fas fa-arrows-alt-h"></i></li>
</ul>
</div>
</div>
<?php }}?>
So How would I accomplish the same result without having to reload the page every time ?
Here's a basic ajax search form setup using jQuery. Note that the search input is in a form with onsubmit="return false" - this is one way to prevent the default form submission which would trigger a page reload.
The button calls a function which gets the value of the search input, makes sure it's not blank, and puts it into an ajax function
The PHP page will receive the search term as $_GET['term'] and do it's thing. In the end, you will output (echo) html from your PHP functions, which the ajax done() callback will put into your search_results div. There are more optimized ways of transferring the data back - maybe a minimal json string that contains just the info you need for results, and your javascript takes it and inflates it into an html template. For large search results, this would be better because it means less data getting transferred and faster results.
function search() {
let term = $('#search_term').val().trim()
if (term == "") return; // nothign to search
$.ajax({
url: "searchFunctionPage.php",
method: 'get',
data: {
term: term
}
}).done(function(html) {
$('#search_results').html(html);
});
// sample data since we dont have the ajax running in the snippet
let html = 'Found 100 results.. <div>result 1</div><div>...</div>';
$('#search_results').html(html);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form onsubmit='return false;'>
<input type='text' placeholder="Type in your search keyphrase" id='search_term' />
<button type='button' onclick='search()'>Search</button>
</form>
<div id='search_results'></div>

Hide Items with Same Name in Loop PHP

I want to only display an item once in my PHP loop. So if there's multiple values which are the same in $item['name'], it should only display it 1 time.
This is my loop:
<?php
while ($item = $stmt->fetch(PDO::FETCH_ASSOC)) {
?>
<li>
<i class="fa fa-archive"></i>
<h5><?php echo $item['name']; ?></h5>
<h3><?php echo $item['displayname']; ?></h3>
Download
<div class="clearfix"></div>
</li>
<?php
}
?>
But I have no idea how I would hide the other items with the same name. I also can't find any info about this on Google (or I'm using the wrong search terms?). Hope someone got a suggestion for me!
$array=array();
foreach ($item['name'] as $i) {
if (!in_array($i, $array)) {
$array[] = $i;
}
}
print_r($array);
<?php
// Produce your prepared statement $stmt here...
// The list of unique item names.
$itemNames = array();
// The list of items to be displayed on screen.
$displayItems = array();
while ($item = $stmt->fetch(PDO::FETCH_ASSOC)) {
$itemName = $item['name'];
if (!in_array($itemName, $itemNames)) { // If item name not already appended to the unique names list.
// Append item name to the unique names list.
$itemNames[] = $itemName;
// Append item to the list of displayable items.
$displayItems[] = $item;
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<!-- Css/Js resources -->
</head>
<body>
<ul id="items">
<?php
foreach ($displayItems as $item) {
$name = $item['name'];
$displayName = $item['displayname'];
$downloadUrl = $item['downloadurl'];
?>
<li>
<i class="fa fa-archive"></i>
<h5>
<?php echo $name; ?>
</h5>
<h3>
<?php echo $displayName; ?>
</h3>
<a href="<?php echo $downloadUrl; ?>" class="btn btn-default pull-right">
Download
</a>
<div class="clearfix"></div>
</li>
<?php
}
?>
</ul>
</body>
</html>
Note:
I always maintain the code responsible for db data access on the upper part of the page. So, for example, if I need to fetch data from db, I save it into arrays. Later, in order to bring that data in html constructs, I work just with them, without having to mix data access commands like
while ($item = $stmt->fetch(PDO::FETCH_ASSOC)) {...}
with html code. Therefore gaining (highly) increased code readability. When you create a lot of files in this way, the advantages will become obvious.
There are also (rare) disadvantages though, like the one arised here: in order to avoid mixing the db codes with the html code, I had to apply an extra array iteration: the one for building the $displayItems array.
Otherwise, if you want to use your approach, then the solution would be:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<!-- Css/Js resources -->
</head>
<body>
<ul id="items">
<?php
// Produce your prepared statement $stmt here...
// The list of unique item names.
$itemNames = array();
while ($item = $stmt->fetch(PDO::FETCH_ASSOC)) {
$name = $item['name'];
if (!in_array($name, $itemNames)) { // If item name not already appended to the unique names list.
// Append item name to the unique names list.
$itemNames[] = $name;
$displayName = $item['displayname'];
$downloadUrl = $item['downloadurl'];
?>
<li>
<i class="fa fa-archive"></i>
<h5>
<?php echo $name; ?>
</h5>
<h3>
<?php echo $displayName; ?>
</h3>
<a href="<?php echo $downloadUrl; ?>" class="btn btn-default pull-right">
Download
</a>
<div class="clearfix"></div>
</li>
<?php
}
}
?>
</ul>
</body>
</html>
Good luck.
Are you trying to do something like this? If I am understanding correctly, I think you are trying to do the same thing I was.
Other people gave you good solutions to solve your issue, but this thing is going to cost you more processing time through your app run-time.
You can use DISTINCT keyword in your sql select query so automatically you will get the name just once.
Chick this tutorial:
https://www.w3schools.com/sql/sql_distinct.asp

How to embed PHP inside a text file to include later?

I have a simple template created through my ClassPage. The class gets called and reads html code from a text file. Inside the navigation I want to echo a PHP variable but all I am getting is the embedded php commented out on the browser's console?
I'm thinking perhaps the file that gets read isn't being processed by the server and that is why the php isn't being processed? Or I'm missing something really simple?
Heres the code:
ClassPage -> getBody which gets the file called "superNav.txt". The string that gets returned is put together with the needed HTML head tags etc then outputted.
private function getBody() {
$text = "";
if ($this->specialUser) {
$text .= file_get_contents("Template/superNav.txt");
} else {
$text .= file_get_contents("Template/userNav.txt");
}
return $text;
}
This is the Text File:
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar"> <span id="glyph" class="glyphicon glyphicon-th-large"></span></button>
<a class="navbar-brand" href="#"><img alt="brand" id="brandLogo" src="Images/logo.png"></a>
<p id="navbarText" class="navbar-text">Webmin</p>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li>Home</li>
<li>Rota</li>
<li>Rota Admin</li>
<li>User Admin</li>
<li>Archive</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><span class="glyphicon glyphicon-user"></span><?php echo $user->getName(); ?></li>
<li><span class="glyphicon glyphicon-log-out"></span> Log Out</li>
</ul>
</div>
</div>
</nav>
This is the line that is giving me an issue:
<li><span class="glyphicon glyphicon-user"></span><?php echo $user->getName(); ?></li>
The php does not get shown to screen, the browsers console shows that the code is commented.
Any help is welcomed. Thanks in advance!
For this first get the content from the .txt file and then do something like this :
$name = $user->getName();
$text = file_get_contents("Template/superNav.txt");
$text = str_replace('USERNAME', $name, $message);
$text$message = str_replace('logo_url', $base_url, $message);
and in your .txt file replace the php value with some Constants.
like this
<li><span class="glyphicon glyphicon-user"></span>USERNAME</li>
So here you can see we have replaced the value of USERNAME with dynamic value. Hope it helps!!!
file_get_contents does not execute php, as you have discovered.
Instead you can use output buffering and include.
You will also need to make sure $user is in scope for the getBody method as include inherets its scope from the calling block.
In this example i have used a made up method to illustrate that:
private function getBody()
{
//create local user variable somehow
$user = $this->getUser();
//start buffer
ob_start();
if ($this->specialUser) {
include "Template/superNav.txt";
} else {
include "Template/userNav.txt";
}
//return contents of buffer as string
return ob_get_clean();
}

Add additional queries to url by link

I have a site that uses query strings to retrieve the data like so:
<div id="menu-sort-dropdown" class="search-filter-item">
<p><?php echo $query_sort_title; ?></p>
<ul class="dropdown-menu">
<li>Newest</li>
<li>Oldest</li>
<li>Alphabetically</li>
</ul>
</div>
<div id="menu-category-dropdown" class="search-filter-item">
<p><?php echo $query_category_title; ?></p>
<ul class="dropdown-menu">
<li>All</li>
<li>Coaching</li>
<li>Conversation</li>
<li>Craft</li>
<li>Creativity</li>
</ul>
</div>
It works great getting the data like:
teachings/?sort=SORT_NAME_ASC
or
teachings/?category=Creativity
but I can do both like:
teachings/?category=Creativity&sort=SORT_NAME_ASC
I can't wrap my head around how to add that. If I just append the strip it will become a mess.
The following code doesn't 'duplicate' the values in the url if you keep clicking the category or sort. It's made to copy/paste and run.
// to check the values
echo '<pre>';
print_r($_GET);
echo '</pre>';
echo '<hr>';
function foo($type, $value){
$args = $_GET;
$args[$type] = $value; // prevent duplication
return http_build_query($args); // returns new query string
}
?>
SORT_DATE_LIT_ASC
<br>
SORT_NAME_ASC
<br>
Coaching
<br>
Conversation
You can also have a code to remove any of those. Add it right after the previous code (also copy/paste). Take a look:
<?php
function bar($type){
$args = $_GET;
unset($args[$type]);
return http_build_query($args); // returns new query string
}
?>
<hr>
Remove SORT
<br>
Remove CATEGORY
As for now your dropdown element do a simple action - go to provided url. If you want to select a few values then your elements should store selected value instead of open url. You can do this with for example this JS code
var menus = [];
function addElement(type, element) {
menus[type] = element;
}
The type above is number index of your menu type. For example 0 can be for sort and 1 for category - this is for ensure that you can select only one value from menu type. Now you can replace your code with something like this
<div id="menu-sort-dropdown" class="search-filter-item">
<p><?php echo $query_sort_title; ?></p>
<ul class="dropdown-menu">
<li>Newest</li>
<li>Oldest</li>
<li>Alphabetically</li>
</ul>
</div>
<div id="menu-category-dropdown" class="search-filter-item">
<p><?php echo $query_category_title; ?></p>
<ul class="dropdown-menu">
<li>All</li>
<li>Coaching</li>
<li>Conversation</li>
<li>Craft</li>
<li>Creativity</li>
</ul>
</div>
To go to the prepared URL you need to add another element like for example a button (or something else with calling openUrl function after mouse click)
<input type="button" onclick="openUrl('?')" value="Go to URL">
And the JS code for openUrl function
function openUrl(prefix) {
var url = prefix + menus.join('&');
document.location.href = url;
}

using jQuery to load php files into a div not working

so I have my main layout as such:
<div class="menu">
<?php include('/menu.php'); ?>
</div>
<div class="main" id="content">
<?php include('/home.php'); ?>
</div>
In the menu.php I have 4 divs set up as such:
<div class="link current">
<a href="#" class="home">
Home
</a>
</div>
<div class="link">
<a href="#" class="about">
About
</a>
</div>
<div class="link">
<a href="#" class="forums">
Forums
</a>
</div>
<div class="link">
<a href="#" class="contact">
Contact
</a>
</div>
And I'm including this .js file in the head of the index page
$(function () {
$('div.link a').click(function () {
$('div.link').removeClass('current');
$(this).closest('div.link').addClass('current');
if($('div.link a').hasClass('home')) {
$('#content').load('/home.php');
} else if($('div.link a').hasClass('about')) {
$('#content').load('/about.php');
} else if($('div.link a').hasClass('forums')) {
$('#content').load('/forums.php');
} else if($('div.link a').hasClass('contact')) {
$('#content').load('/contact.php');
} else return false;
});
});
But it doesn't work.
I'm new to all of this and have pieced this code together using varied sources on the internet, after trying it myself and not being able to figure it out, I've come for help.
The hierarchy of the site is as such.
-/
-res/
-css/
-default.css
-imgs/
-scripts/
-jquery.js
-load.js (this is the one shown above)
-index.php
-menu.php
-home.php
-about.php
-forums.php
-contact.php
If anyone can provide help, it will be greatly appreciated.
The first condition in your if statements is checking to see if any "div.link a" has the class "home". Therefore the first if condition is always true and you're always loading /home.php into #content. What you want to do is check to see if the link that was clicked has the class.
You should use if($(this).hasClass('home')) { ...
Also, if you want to clean things up a bit, I would suggest:
$('div.link a').click(function () {
$('div.link').removeClass('current');
$(this).closest('div.link').addClass('current');
$('#content').load('/' + $(this).attr('class') + '.php');
});
This way you don't have to maintain the if statements. Though, if you end up adding more classes to those links, this will break. Perhaps use a data-* attribute? <a href="#" data-load="contact">...

Categories