Add additional queries to url by link - php

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;
}

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>

Refreshing div with ajax loses link to javascript file

I have a div that includes shoutbox posts. I'm using jQuery and ajax to change the pages within the div. However, when the page changes, it loses the link to the javascript file so that the next time I try to change the page it actually continues with the link action instead of doing the ajax in the background. Then after that it's back to normal and it alternates back and forth between being linked to the file and not.
Also before, it was rendering the whole page so that my layout was being displayed on the refresh instead of just the shoutbox posts. I'm guessing that finally getting it to refresh without re displaying the whole layout again is what's causing it to lose the connection to the javascript file.
This is the code for the posts. The shoutbox_arrows contains the links to change the page. refresh_me is what I'm loading into my div to refresh the content.
<div id="shoutbox_arrows">
<?php $current_page=s tr_replace( '?', '#', getURI(fullURL())); ?>
<ul class="no_dots">
<li id="first_page"><<
</li>
<li id="previous_page"><
</li>
<li><strong>Pg#<?php if ($page > $last_page) {echo $last_page;} else {echo $_SESSION['shoutbox_page'];} ?></strong>
</li>
<li id="next_page">>
</li>
<li id="last_page">>>
</li>
</ul>
</div>
<div id="shoutbox" class="custom_scrollbar">
<div id="refresh_me">
<?php if (sizeof($shouts)==0 ) { ?>
<p>There are no posts.</p>
<?php } foreach ($shouts as $shout) { foreach ($shout as $k=>$v) { $shout[$k] = utf8_encode($v); if ($k == 'guest') { $shout[$k] = ucwords($v); } } ?>
<div class="post_info">
<div class="left">
<?php if ($shout[ 'user_id']==n ull) {echo $shout[ 'guest'];} else { ?><?php echo ucwords(userinfo($shout['user_id'])->username); ?>
<?php } ?>
</div>
<div class="right">
<?php time_format($shout[ 'created_at']); ?>
</div>
</div>
<p class="post_comment" id="shoutbox_comment_<?php echo $shout['id']; ?>">
<?php echo $shout[ 'comment']; ?>
</p>
<?php if (!$shout[ 'last_edited_by']==n ull) { ?>
<p class="last_edited">Edited by
<?php echo ucwords(userinfo($shout[ 'last_edited_by'])->username); ?>
<?php time_prefix($shout[ 'updated_at']); ?>
<?php time_format($shout[ 'updated_at']); ?>.</p>
<?php } ?>
<?php if (current_user()) { if (current_user()->user_id == $shout['user_id'] or current_user()->is_mod) { ?>
<p class="post_edit"> <span class="edit" id="<?php echo $page; ?>">
<a id="<?php echo $shout['id']; ?>" href="<?php $post_to = '?id=' . $shout['id']. '&uid=' . $shout['user_id']; echo $post_to; ?>">
edit
</a>
</span> | <span class="delete" id="<?php echo $page; ?>">
<a href="<?php $post_to = '?id=' . $shout['id']. '&uid=' . $shout['user_id']; echo $post_to; ?>">
delete
</a>
</span>
<span class="hide" id="<?php echo $page; ?>">
<?php if (current_user()->is_mod) { ?> | <a href="<?php $post_to = '?id=' . $shout['id']. '&uid=' . $shout['user_id']; echo $post_to; ?>">
hide
</a><?php } ?>
</span>
</p>
<?php }} ?>
<?php } ?>
</div>
</div>
This is the page that my ajax request is going to.
<?php
if (isset($data['page'])) {
$_SESSION['shoutbox_page'] = intval($data['page']);
}
$redirect = ltrim(str_replace('#', '?', $data['redirect']), '/');
redirect_to($redirect);
Div that contains the content to be refreshed.
<div id="shoutbox_container">
<?php relativeInclude( 'views/shoutbox/shoutbox'); ?>
</div>
jQuery
$('#shoutbox_arrows ul li a').click(function (event) {
event.preventDefault();
$.post('views/shoutbox/' + $(this).attr('href'), function (data) {
$('#refresh_me').load(location.href + " #refresh_me>", "");
$('#shoutbox_arrows').load(location.href + " #shoutbox_arrows>", "");
});
});
So I guess to clarify the issue:
The shoutbox_container displays posts for the shoutbox. The page is controller by a session that gets passed as a variable to get the correct chunk of posts to show. Clicking on the links in shoutbox_arrows sends an ajax request to a page which changes the session variable. The div that contains the post itself (refresh_me) as well as the arrows (for the links) get refreshed. After changing the page once, the shoutbox is no longer connected to the javascript file so when you click to change the page again, instead of an ajax request, the page itself actually changes to the link.
Any ideas how I can fix this? I've spent a lot of time on this and it's getting rather frustrating. I feel like I could just settle for it as it is now but it's bugging me too much that it's not working exactly how I intend (although generally it works in terms of changing the pages).
Also just a note, I used jsfiddle to tidy up the code but it looks like it did some funky stuff (looking just at $current_page=s tr_replace). lol. So there aren't any syntax errors if that's what you're thinking. ><
Also I was going to set up a fiddle but I don't really know how to handle links in it so it would have been useless.
The issue is that you bind the click handler to the a tags on document ready (the jQuery code you provided). So when you replace the content of #shoutbox_arrows you remove the click handler you previously attached since those original handlers are removed from the DOM along with the original elements.
You need to use the jQuery .on() method and event bubbling. This will attach the handler on a parent element that will not be removed in your content replace and can continue to "watch" for the event to bubble up from it children elements.
Try replacing your jQuery code with this:
$('#shoutbox_arrows').on('click', 'ul li a', function (event) {
event.preventDefault();
$.post('views/shoutbox/' + $(this).attr('href'), function (data) {
$('#refresh_me').load(location.href + " #refresh_me>", "");
$('#shoutbox_arrows').load(location.href + " #shoutbox_arrows>", "");
});
});
For performance, you should add a class to the a, and targeting it directly with $('a.aClass')
Good ways to improve jQuery selector performance?

Data attribute value from MySQL

I'm new to PHP and MySQL so i'm not quite sure what i am doing wrong here. I am using the jQuery plugin quicksand to create a filterable portfolio. The plugin uses custom data attribute data-tag inside the li item to populate the filter nav.
What I am trying to do is use a foreach loop to populate the contents of the ul. The problem is that the filter nav won't auto populate when I use php to get the value of the data attribute from the gallery_tag column in my mySQL table.
<?php
$pagetitle = "Red Penguin - Our Work";
$navcurrent = "work";
$headTitle = "RECENT WORK";
$headsubTitle = "SOME OF OUR RECENT WORK";
include_once('includes/headersub.php');
include_once('includes/connection.php');
include_once('includes/project.php');
$project = new Project;
$projects = $project->fetch_all();
?>
<div class="row">
<nav id="filter"></nav>
<section id="container">
<ul id="stage" class="three-up">
<?php foreach($projects as $project) { ?>
<li class="gallerylist" data-tag="<?php echo $project['gallery_tag']; ?>">
<a href="project.php?id=<?php echo $project['gallery_id']; ?>">
<img src="<?php echo $project['gallery_thumb']; ?> " alt="<?php echo $project['gallery_proj']; ?>" />
<?php echo $project['gallery_title']; ?>
</a>
</li>
<?php } ?>
</ul>
</section>
The error that comes up in the log is in the jquery line:
tags = elem.data('tags').split(',');
The log comes back with this error: "Uncaught TypeError: Cannot call method 'split' of undefined" for the above line.
I'm not quite sure why this is a conflict that causes the jquery to be unable to read the value of the data-attribute as taken from the gallery_tag column of my table. Any help would be appreciated.
I guess there is a spelling mistake in your html you have data-tag and you are trying to get the elem.data('tags') it should be elem.data('tag')
your elem.data('tags') returns undefined. So split() would not work on it.
Maybe I'm wrong, but I think you need: tags = elem.data('tags').split(' ');

Attribute assign image to each multi option

I have created a multi option attribute so that I show an image for each option but i can not get it to work.
I have used this code from another post on here to get a list of the options to show.
The code I used is:
<?php if($_product->getResource()->getAttribute('suitable_for')->getFrontend()->getValue($_product)): ?>
<h4>Suitable for:</h4>
<ul><li><?php
$_comma = ",";
$_list = "</li><li>";
echo str_replace($_comma,$_list,$_product->getResource()->getAttribute('suitable_for')->getFrontend()->getValue($_product)) ?>
</li></ul>
<?php endif; ?>
So this now shows a list of the options, one of on top of each other.
As I said I would like an image to be shown for each option.
I thought the best way would be to have divs and assign an image to each div.
I was hoping that I could get the output to be:
<div class="option1"></div>
<div class="option2"></div>
<div class="option3"></div>
<div class="option3"></div>
instead of the output that the code above has:
<ul>
<li>option1</li>
<li>option2</li>
<li>option3</li>
<li>option4</li>
</ul>
Change your code to
<?php if($_product->getResource()->getAttribute('suitable_for')->getFrontend()->getValue($_product)): ?>
<h4>Suitable for:</h4>
<div class="<?php
$_comma = ",";
$_list = "\"></div><div class=\"";
echo str_replace($_comma,$_list,$_product->getResource()->getAttribute('suitable_for')->getFrontend()->getValue($_product)) ?>
</div>
<?php endif; ?>

prev - next dynamic content display with jquery

I am trying to make prev - next sliding between content on a page. I have the following markup:
<div class="right">
Previous
Next
</div>
<?php foreach ($chapters as $chapter) : ?>
<div id="chapters-container-<?php echo $chapter->id; ?>" style="display: none">
<div class="left">
<h1 class="hmc"><?php echo $chapter->title; ?></h1>
</div>
<ul class="attachments scroll-pane">
<?php foreach ($chapter->files as $file) : ?>
<!--video zone-->
<?php if ($file->extension == '.mpeg') : ?>
<li class="wide">
<img src="" />
<span class="duration hmc"><?php $file->duration; ?></span>
<h1 class="hmc">The title is a title</h1>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
</div>
<?php endforeach; ?>
</div>
Basically I generate some content dynamically with PHP. I have wrapped each content generated in a div and I do not display it only with jQuery.
Now I tried doing something like:
$('body').on('click', 'a#next-button', function(){
$('#chapters-container-').next();
});
but ofc it is not working as I want it. How can I make the content change when i toggle between prev and next button based on the markup I am generating.
I think that you don't get what
$('#chapters-container-').next();
does. This, according to the documentation,
Get the immediately following sibling of each element in the set of
matched elements. If a selector is provided, it retrieves the next
sibling only if it matches that selector.
so you are just selecting the next element after the element with id = chapters-container-
Youy should do something like:
$('body').on('click', 'a#next-button', function(){
var visisbleContainer = $('div[id^=chapters-container-]:visible');
visisbleContainer.next().show();
visisbleContainer.hide();
});
when user clicks on next button get the visible div( chapter ) id attribute.You would receive the chapter id add 1 to this chapter id and generate another string such as chapters-container-2.
Now hide the current div and show the div of the generated string i.e $('#'+ newstring).show()

Categories