This is an extension of questions I asked here: Owl Carousel 2: filtering items, but keep the sort order using Javascript (hope this is ok).
I have a menu which filters items. I want the filter to be applied when clicked from and external page link. So on page X you click FilterA this directs you to page Y and filters the items to FilterA as if you had just clicked FilterA on page Y.
In the ideal world it would simply use a link such as www.example/pageY/#filterA.
You can see the live page here.
This is the filter function:
$(document).ready(function () {
function showProjectsbyCatEur(cat) {
var owl = $(".owl8").data('owlCarousel');
owl.addItem('<div/>', 0);
var nb = owl.itemsAmount;
for (var i = 0; i < (nb - 1); i++) {
owl.removeItem(1);
}
if (cat == 'all8') {
$('#projects-copy8 .project8').each(function () {
owl.addItem($(this).clone());
});
} else {
$('#projects-copy8 .project8.' + cat).each(function () {
owl.addItem($(this).clone());
});
}
owl.removeItem(0);
}
$('.owl8 .project8').clone().appendTo($('#projects-copy8'));
$('#project-terms8 a').click(function (e) {
e.preventDefault();
$('#project-terms8 a').removeClass('active');
cat = $(this).attr('ID');
$(this).addClass('active');
showProjectsbyCatEur(cat);
});
});
My filter menu looks like this:
<div id="filter">
<h1 class="title">Eurorack</h1>
<div id="project-terms8">
<ul class="filter">
<li class="filter"><a id="all8" class="active all" onclick="event.preventDefault();" href="#">Show All</a></li>
<li class="filter 3x"><a id="3x" onclick="event.preventDefault();" href="#">Clocks, Logic & CV</a></li>
<li class="filter 2x"><a id="2x" onclick="event.preventDefault();" href="#">Filters & Resonators</a></li>
<li class="filter 1x"><a id="1x" onclick="event.preventDefault();" href="#">Waveform Modifiers</a></li>
</ul>
</div>
So the answers so far have been helpful but not quite solve my issue. If anyone else has any advice that would be great! It seems using # is not helpful as the filter uses the id this just creates anchors down to the filter, so a /?filter=FILTERITEM
would be best.
Alternatively a new filter system would be fine. As long as the sort order remains the same and this can be used with the URL as well as buttons.
This is an extension of questions I asked here: Owl Carousel 2: filtering items, but keep the sort order using Javascript (hope this is ok).
I have a menu which filters items. I want the filter to be applied when clicked from and external page link. So on page X you click FilterA this directs you to page Y and filters the items to FilterA as if you had just clicked FilterA on page Y.
In the ideal world it would simply use a link such as www.example./pageY/#filterA.
You can see the live page here.
This is the filter function:
$(document).ready(function () {
function showProjectsbyCatEur(cat) {
var owl = $(".owl8").data('owlCarousel');
owl.addItem('<div/>', 0);
var nb = owl.itemsAmount;
for (var i = 0; i < (nb - 1); i++) {
owl.removeItem(1);
}
if (cat == 'all8') {
$('#projects-copy8 .project8').each(function () {
owl.addItem($(this).clone());
});
} else {
$('#projects-copy8 .project8.' + cat).each(function () {
owl.addItem($(this).clone());
});
}
owl.removeItem(0);
}
$('.owl8 .project8').clone().appendTo($('#projects-copy8'));
$('#project-terms8 a').click(function (e) {
e.preventDefault();
$('#project-terms8 a').removeClass('active');
cat = $(this).attr('ID');
$(this).addClass('active');
showProjectsbyCatEur(cat);
});
});
My filter menu looks like this:
<div id="filter">
<h1 class="title">Eurorack</h1>
<div id="project-terms8">
<ul class="filter">
<li class="filter"><a id="all8" class="active all" onclick="event.preventDefault();" href="#">Show All</a></li>
<li class="filter 3x"><a id="3x" onclick="event.preventDefault();" href="#">Clocks, Logic & CV</a></li>
<li class="filter 2x"><a id="2x" onclick="event.preventDefault();" href="#">Filters & Resonators</a></li>
<li class="filter 1x"><a id="1x" onclick="event.preventDefault();" href="#">Waveform Modifiers</a></li>
</ul>
</div>
So the answers so far have been helpful but not quite solve my issue. If anyone else has any advice that would be great! It seems using # is not helpful as the filter uses the id this just creates anchors down to the filter, so a /?filter=FILTERITEM
would be best.
Alternatively a new filter system would be fine. As long as the sort order remains the same and this can be used with the URL as well as buttons.
Share Improve this question edited Jul 13, 2018 at 20:45 Matt 1777 bronze badges asked Jul 1, 2015 at 14:42 pinkppinkp 4552 gold badges12 silver badges31 bronze badges 1- If any of the provided solution was helpful, please be sure to accept it. – mega6382 Commented Nov 6, 2017 at 16:03
4 Answers
Reset to default 4You can get a url argument with javascript and use that in the filter.
function getURLParameter(name) {return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null
}
var filter= getParameterByName('filter');
showProjectsbyCatEur(filter);
then make the link something like "www.mysite./pageY/?filter=euro".
You have specified a preference to use an appended hashtag, so I'll answer with regard to that.
Assuming somebody makes the following request:
http://www.abstract.pinkpoliceman./products/#all8
You can, on DOM ready, retrieve the category/hashtag value and pass it to the function you're already invoking from the click event handler:
$(document).ready(function () {
// INSERT THE DOM READY CODE YOU ALREADY HAVE HERE
var hash = window.location.hash;
if(hash.length > 0)
{
showProjectsbyCatEur(hash.substring(hash.indexOf('#') + 1));
}
});
EXPLANATION:
hash.substring(hash.indexOf('#') + 1)
This will take the hash value of '#1234' and substring it after the point at which the '#' is found. It basically removes the #
character.
NOTE:
What the user submits as a hashtag is out of your control. If they don't submit all8
, your else
will still catch it and try to filter by it. So I suggest you rethink the conditional logic a bit to cater for 'bad' values.
SINCE UPDATE (Request to Use Query String Parameters)
Get the query string parameters:
$(document).ready(function () {
// INSERT THE DOM READY CODE YOU ALREADY HAVE HERE
function getUrlVars()
{
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
var filter = getUrlVars()['filter'];
if(filter.length > 0)
showProjectsbyCatEur(filter);
});
http://jquery-howto.blogspot.co.uk/2009/09/get-url-parameters-values-with-jquery.html
Url could now look like:
http://www.abstract.pinkpoliceman./products/?filter=all8
If you want the hashes to work for links on the same page, you can use an event listener to listen for hash changes:
function filterByHash(){
if(window.location.hash)//.match(/#(all8|\dx)/)
showProjectsbyCatEur(window.location.hash.substr(1));
}
$(document).ready(filterByHash);
$(window).on('hashchange',filterByHash);
You can use the regex to filter out invalid hashes.
In addition, if you want to support old browsers, you can add something like this instead of the hashchange
event listener:
$('#filter').on('click','a[href^=#]',function(){
setTimeout(filterByHash,0);
});
The setTimeout
pushes the function to the end of the event loop so that it's called after the hash changes.
user3915578 wrote a very nice RegExp, but I think it would be helpful to get a better understanding of query strings as a whole.
The "#" symbol is used by browsers to anchor to certain parts of a page (like how bookmarks work on Wikipedia).
location is a built in object in browsers. The location.search property returns the part of the current URL after the "?" symbol. The query string is the proper way to pass string parameters between pages.
So the query string is the way to go. Each one of your links is going to load the page with a different value assigned to filter. The location object itself can be used to cause a redirect whenever its value changes.
$('#project-terms8 a').click(function (e) {
e.preventDefault();
cat = $(this).attr('ID');
// this line causes a redirect to the same page, but with added query string
// to redirect to a separate page, just build the new url as a string
location = location.origin + location.pathname + '?filter=' + cat;
});
In your document ready function, you'll need to call your filter function on every new load, but only if filter has a value. That's where the rest of user3915578 's code should go.
$(document).ready(function () {
// prev code
var filter = getParameterByName('filter');
if (filter) { showProjectsbyCatEur(filter); }
});
You'll have to reset the active li inside your filter function instead of your click function. Hopefully this clears up your implementation confusion.