I'm trying to modify this porfolio script here: http://themes.iki-bir.com/webpaint/multipage/full/portfolio.html
It uses urls like #entry-12 (using the index number of the element to deeplink the item) and I'd like to change it to #this-is-an-item
updateURLParameter(thumb.attr("data-event-id"));
//updateURLParameter("entry-"+thumb.index());
It sets the name here (which works fine)... now it's whatever.html#this-is-an-item
But now I need to change the behaviour when they link in from the URL (as it no longer works since it's still looking for the index number instead of a name).
var deeplink = getUrlVars("#");
// DEEPLINK START IF NECESSARY
if (deeplink[0].split('entry-').length>1) {
var thmb = parseInt(deeplink[0].split('entry-')[1],0)+1;
$container.find('.item:nth-child('+thmb+')').click();
$container.find('.item:nth-child('+thmb+')').addClass("active").children('a').children('div').fadeIn(300);;
}
I'm just not sure how to do the last part, so it looks for the data-event-id instead of the index?
<li class="item installation 2013-10-13" data-event-id="installation-opening-whispering-in-the-leaves"... </li>
Try this:
var deeplink = getUrlVars("#");
var $elem;
// v--- this can be changed to .find('.item) if needed.
$container.children('.item').each(function() {
// you can use .data(...) instead of .attr("data-...")
if ($(this).data("event-id") == deeplink[0])
$elem = $(this);
});
if ($elem) {
$elem.click()
.addClass("active")
.children('a')
.children('div')
.fadeIn(300);
}
Simply iterate over all the elements in $container with the class .item, and check if the data-event-id matches the one in the URL hash. If it does, store it, and do your operations afterwards.
Related
The following code is used for my sidebar to be able to set the active subpage and properly display the the sidebar when refreshing the page.
It works well if I add the "#" symbol to the href of the subpages but didn't work when changing the href to anything else and removing the "#" symbol. Let's suppose I want to set the href as "/contactpage/. How do I indicate in the below code to choose any href not only the ones that contains the hash symbol?
<script>
(() => {
'use strict'
function setActiveItem() {
const { hash } = window.location
if (hash === '') {
return
}
const link = document.querySelector(`.d-flex a[href="${hash}"]`)
if (!link) {
return
}
const active = document.querySelector('.d-flex .active')
const parent = link.parentNode.parentNode.previousElementSibling
link.classList.add('active')
if (parent.classList.contains('collapsed')) {
parent.click()
}
if (!active) {
return
}
const expanded = active.parentNode.parentNode.previousElementSibling
active.classList.remove('active')
if (expanded && parent !== expanded) {
expanded.click()
}
}
setActiveItem()
window.addEventListener('hashchange', setActiveItem)
})()
</script>
// Select anything with an "href" attribute, regardless of its value
document.querySelectorAll('[href]')
// Select only the first link with the current page's path ("active" link)
const currentPath = window.location.pathname
document.querySelector(`a[href="${currentPath}"]`)
// Select the currently active path including the hash
const currentPathWithHash = window.location.pathname + window.location.hash
document.querySelector(`a[href="${currentPathWithHash}"]`)
To avoid issues when none of the links contain hashes, just remove the first few lines of your code up to const link = ..., which should be replaced by one of the options above (edit to suit your needs).
I also noticed that if active is also the current link, you'll end up first adding the active class to it and deleting it later in your code. Switch the order like this to avoid that:
active.classList.remove('active')
link.classList.add('active')
Note that if there could be more than one link on the page that point to the current path, you should probably add further selectors, like a class name you use for the target links. Unless of course you want to target any link with that path, in which case just use document.querySelectorAll. Yours seem to be under a .d-flex container, so add that to my examples.
I'm working on an events page in a WordPress site that uses a set of filters to query posts; the markup for the filters is as follows:
<div class="event-filter">
All Events
Conferences
Webinars
Learning
Past Events
</div>
I'm using jQuery to add an active class to whichever filter is currently in use, the simple code for which is as follows:
$('.event-filter a').each(function() {
if (this.href == window.location.href) {
$(this).addClass("active");
}
});
This works perfectly fine except in the case that the resulting posts are paginated, as the url changes to reflect the current page, i.e. /events/page/2/?event-type=conference. How can I modify my JS to add the active class to the current filter if the URL contains the respective event-type term but also accounts for "All Events", and thus appends the class to "All Events" when the other filters are not in use? A couple notes: the "Past Events" option just links to an archive page that is a separate template from the main, filterable "Events" page; also, these filters are not using Ajax, they're just altering the WordPress query by URL parameter. Thanks for any insight here!
By the looks of it you will have to do a two part check, I would try something like:
$('.event-filter a').each(function() {
var currentHref = window.location.href.split('?'); // ['https://myexamplesite.com/events/page/2', 'event-type=conference']
var thisHref = this.href.split('?'); // ['https://myexamplesite.com/events', 'event-type=conference']
var currentHrefHasQuery = currentHref.length > 1 ? true : false; // true
var thisHrefHasQuery = thisHref.length > 1 ? true : false; //true
if (currentHrefHasQuery != thisHrefHasQuery) {
return; // they don't match
}
if (currentHrefHasQuery && currentHref[1] == thisHref[1]) { // if they have a query and the query is the same, it's a match!
$(this).addClass("active");
} else if (!currentHrefHasQuery && currentHref[0].indexOf(thisHref[0]) > -1) { //check to see if the current href contains this' href
$(this).addClass("active");
}
});
This could definitely be simplified, but hopefully this is fairly easy to read.
Fiddle: https://jsfiddle.net/m0hf3sfL/
I have i 'asc' list of names, i'd like to add a letter so it would be look like something like this:
<li>Abram</li>
<li>Amanda</li>
<li>Bernard</li>
<li>Fox</li>
to
<div>A:</div>
<li>Abram</li>
<li>Amanda</li>
<div>B:</div>
<li>Bernard</li>
<div>F:</div>
<li>Fox</li>
any ideas?
Since you're using jquery, you can do something like this:
var currentLetter, prevLetter = null;
$("li").each(function() {
currentLetter = $(this).find("a").text()[0];
if (currentLetter != prevLetter)
{
$("<div>").text(currentLetter).insertBefore($(this));
}
prevLetter = currentLetter;
});
http://jsfiddle.net/Uw9L4/
Though technically you shouldn't be putting a div inside of a ul (even though it totally renders fine). I would go with inserting li without an anchor to maintain semantics.
Let's go straight to the point.
The following code must run on IE8, unfortunately.
It is supposed to find match the URL of the current page with the href attribute of the <a> tags present in the nav. Then swap the class of that tag from not-selected to selected or defaults to do it to the first <a> tag.
HTML
<ul id="nav">
<li><a class="not-selected" href="index.php"><span>Index Page</span></a></li>
<li>
<a class="not-selected" href="page1.php"><span>Page 1</span></a>
</li>
<li>
<a class="not-selected" href="page2.php"><span>Page 2</span></a>
</li>
</ul>
JavaScript (jQuery)
var url = $(document).attr('URL');
var isIndexPage = true;
var menu = $('#nav').children('li');
var anchors = menu.find('a');
anchors.each(function(index) {
// Is the href the same as the page?
if ($(this).href != null && anchor.href == url)
{
$(this).first().addClass('selected');
if ($(this).className.match(/\bnot\-selected\b/))
$(this).first().removeClass('not-selected');
indexPage = false;
}
else
{
// remove class="selected" if it has that class
if ($(this).className.match(/\bselected\b/))
{
$(this).first().removeClass('selected');
}
// Add class="trigger"
$(this).first().addClass('not-selected');
}
});
if (isIndexPage)
{
menu[0].childNodes[0].setAttribute('class', 'selected');
}
On the script, I get an error on the line that calls the match() function on the className attribute (which should be a string).
Why is that?
How can I fix it with jQuery or JavaScript that works on IE8?
Thank you in advance.
There is no className property of the jQuery object, you would use the hasClass method to check if the element has a class:
if ($(this).hasClass('not-selected'))
However, you don't need that check at all. You can just remove the class, and if it's not there in the first place the call will just do nothing. You can just do it like this:
$(this).addClass('selected').removeClass('not-selected');
Similarly in the else block, you don't need to check, just remove and add:
$(this).removeClass('selected').addClass('not-selected');
Actually, you don't even need the if, you can do it using toggleClass and a boolean value. This would be your entire loop:
anchors.each(function() {
var sel = $(this).href != null && $(this).href == url;
$(this).toggleClass('selected', sel).toggleClass('not-selected', !sel);
});
Also, you are using the undefined variable anchor where you should use $(this). Change this line:
if ($(this).href != null && anchor.href == url)
to:
if ($(this).href != null && $(this).href == url)
className is a native property of HTML elements, whereas you're trying to call it as a property on a jQuery object. Do either:
$(this)[0].className
or
$(this).attr('class')
Sidenote: you're are not first checking whether the element has a class or not - you're assuming it has. The second (jQuery) approach will error if the element has no class attribute, as it returns null if none is found (as opposed to the native className property which, in the absence of a corresponding class attribute, defaults to an empty string.)
you can replace the lines
if ($(this).className.match(/\bselected\b/))
with this
if ($(this).hasClass('selected'));
It's much simpler. The same for class 'not-selected'.
I think you should use plain JS for the URL and jQuery for the rest example:
JavaScript
var path = window.location.pathname;
$.each($('#nav li a'), function(index, anchor) {
if(path.indexOf($(anchor).attr('href')) != -1) {
$('#nav li a').removeClass('selected');
$(anchor).addClass('selected').removeClass('not-selected');
}
});
Here is an example: http://jsfiddle.net/2rSqL/
I currently have the following:
$(window).load(function(){
$(".boxdiv").click(function () {
$(this).toggleClass("selected");
});
});
Which perfectly does the first part of what I need. I have a fair amount of div's with the class "boxdiv" and they each have a unique ID that will identify it. What I need to happen is to have some kind of button that when pressed sends all of these div ID's with the class selected, to the next page.
Anyone got any idea of how I can do this?
Map the ID's in an array, and use $.param to create a querystring
$('button').on('click', function() {
var id_arr = $.map($(".selected"), function(el) {return el.id;});
window.location.href = '/next_page?' + $.param({ids : id_arr});
});
EDIT:
$('button').on('click', function() {
var id_arr = $.map($(".selected"), function(el) {return el.id;}),
qs = encodeURIComponent(id_arr.join(','));
window.location.href = '/next_page?ids=' + qs;
});
Perhaps this is what you're looking for:
$(".button").click(function(){
var id_arr = [];
$(".boxdiv").each(function(){ // Loop through each element with that class
id_arr.push($(this).attr('id'));
}); // Loop through each element with that class
});
window.location = 'next.html/ID=' + id_arr.join(',');
The ID's should be stored in id_arr
You can loop over each div that has the class selected. You can then use attr() to access the ID names.
Javascript
var ids = [];
$.each($(".selected"), function() {
ids.push($(this).attr('id'));
});
ids = ids.join(',');
HTML
<div id="boxA"></div>
<div id="boxB" class="selected"></div>
<div id="boxC" class="selected"></div>
<div id="boxD"></div>
This should return ["boxB", "boxC"]
See: http://jsfiddle.net/B4V28/1/
All of the answers submitted are in fact correct - but I think the real issue is your expectation of what jQuery is doing for you.
jQuery will gather all of the ID's in any manner, but you will need to have a way to collect them on the next page and actually do something with them. This will all need to happen server side.
Most likely, the ideal method, based on your comment of "potentially there could be many" you would want to do a mapping (see other answers), and pass the json object to your server, where it can pass it to the next page.
With the same code -
$('button').on('click', function() {
var id_arr = $.map($(".selected"), function(el) {return el.id;}),
qs = encodeURIComponent(id_arr.join(','));
alert('/next_page?ids=' + qs);
});
Here is a fiddle for you - http://jsfiddle.net/kellyjandrews/4dYfh/