add aria-expanded and tabindex values to parent based on current URL - javascript

I'm creating a jQuery-powered, WAI-ARIA tree menu for a site that doesn't have any server-side capabilities. Because of this, my only way of changing the menu dynamically is to check the current URL and compare it against the current file. For a match, I need to do all of these things:
Add a class of "current" to the <li> element that holds the <a> element that matches the current page's URL
Add a class of "current" to the <li> element that holds the <ul> element that holds the <li> element that holds the <a> element that matches the current page's URL
Set the aria-expanded attribute to true on the <li> element targeted in number 2 above
Set the tabindex attribute to 0 on the child <a> element of the <li> element targeted in number 2 above (NOT the <a> that is actually the current page)
Here's what the resulting HTML should look like (if "owls.html" is the current page):
<nav id="nav-sub">
<ul role="tree">
<li role="treeitem" class="tree-parent current" aria-expanded="true">Birds
<ul role="group">
<li role="treeitem">Ducks</li>
<li role="treeitem">Geese</li>
<li role="treeitem" class="current">Owls</li>
</ul>
</li>
<li role="treeitem" class="tree-parent" aria-expanded="false">Cats
<ul role="group">
<li role="treeitem">Lions</li>
<li role="treeitem">Tigers</li>
</ul>
</li>
</ul>
</nav>
I've gotten this bit of jQuery to do the trick for items 1 through 3:
$(document).ready( function () {
var pathname = (window.location.pathname.match(/[^\/]+$/)[0]);
$("#nav-sub li a[href='" + pathname + "']").parents(".tree-parent").attr('aria-expanded', 'true');
$("#nav-sub li a[href='" + pathname + "']").parents("li").addClass("current");
});
However, I'm a JavaScript/jQuery newbie, so I'm not sure if this is the best or most efficient way to do what I want. If anyone can suggest a better way to approach it, I'd appreciate it!
But I don't know how to achieve item 4, adding the tabindex value to the first-level <a> element, because it's not actually a parent/ancestor of the current page's <a> element. What can I add to my script to target this <a> element and change its tabindex value from -1 to 0?

var $treeParent = [current <a> element].closest('.tree-parent');
$('> a', $treeParent).attr('tabindex', 0);

I'd probably use
$("#nav-sub li a[href='" + pathname + "']").closest('.tree-parent').next('a').attr('tabindex','0');
Also, I'd probably set a variable to $("#nav-sub li a[href='" + pathname + "']") so I don't have to keep traversing the tree to get it. Possibly the same with the tree-parent if I'm using it more than once.
I haven't really tested that - but something like that should get what you want.

Related

How can I completely remove a list item and its content?

i canĀ“t remove li and html content, my html looks like:
<li>
<a href="#dialog-form-image" rel="modal:open">
<img src="http://www.miapp.cl/walmart/admincontenidoatg/wp-content/themes/admincontent/images/imagen_wf.jpg" name="img_164" id="flexslider">
</a>
</li>
Remove action depend click a button with name of image.
$("#btn-url-delete").live('click',function(){
var id_img = $(this).attr("name");
$('img[name="'+id_img+'"]').prev().prev().remove();
$(this).remove();
});
The problem is prev() is siblings, not the parent. You need to select the parents to get to the li.
$('img[name="'+id_img+'"]').parent().parent().remove();
or
$('img[name="'+id_img+'"]').closest("li").remove();

match elements by data attribute and id

I am looking for a way to compare elements using jQuery. Basically for every element with a certain data attribute, I want to "appendChild" another element that has a matching ID.
So in the following example, 'a' has a data attribute of data-dropdown="drop-delivery-options". The second element has an ID="drop-delivery-options", so they match. I can select elements with this ID but how do I select elements that match data-attributes/IDs?
So a function that would be like:
If elementA[data-attribute] = elementB[ID] {
(elementA).appendChild(elementB)
}
Add Option
<div id="drop-delivery-options" data-dropdown-content class="f-dropdown content table-options drop-delivery-options">
<ul>
<li>Add Deposit Account</li>
<li>Add Cash Pickup</li>
<li>Send to Card</li>
<li>Add Home Delivery</li>
</ul>
</div>
You can use the data-dropdown attribute to select the select element, then use appendTo() to append it to the a. Note though that given your example you will end up with nested a elements, which is invalid. You should look to change the parent a element to something else.
$('.button').click(function() {
$('#' + $(this).data('dropdown')).appendTo(this);
});
Working example

showing an element on hover, using first element ID as variable in targetting second element

Basically I have two sets of elements. for example:
<ul id="feature1">
<li class="items" id="item1">Item 1</li>
<li class="items" id="item2">Item 2</li>
<li class="items" id="item3">Item 3</li>
<ul>
<ul id="feature2">
<li class="post" id="item1-post">Post 1</li>
<li class="post" id="item2-post">Post 2</li>
<li class="post" id="item3-post">Post 3</li>
<ul>
What I'm attempting to do here is fairly simple: When the user hovers over an element from #feature1, I show (and then hide on mouseout) the corresponding element in #feature2. I could write functions for each .items element and it's corresponding .post element but I'm thinking it should be possible, with the right naming scheme, to write this as a single function by first getting the id of the hovered on .items element, then applying the show/hide (or adding class, whatever) by looking for the right .post element with the saved ID variable + "-post".
To simplify: I mouse over li#item1 - jQuery saves #item1 as my variable, and then looks for a child of #feature2 with the id of item1 + "-post", showing the given element, and then hiding it on mouseout.
I've come very close, but can never seem to figure out the right logic.
If this is doable, the second aspect I'm looking to accomplish is an additional onclick that keeps the corresponding #feature2 element displayed until mouseover of the next element.
Thanks ahead of time for the help, I've been banging my head against this one all afternoon.
I'd suggest, albeit untested:
$('#feature1 li.items').hover(function(){
$('#' + this.id + '-post').show();
}, function(){
$('#' + this.id + '-post').hide();
});
Or:
$('#feature1 li.items').hover(function(){
$('li.post').eq($(this).index()).show();
}, function(){
$('li.post').eq($(this).index()).hide();
});
References:
eq().
hide().
hover().
index().
show().
Possible Without naming scheme using corresponding indexes
var $feature2 = $('#feature2'),
$hoveredElm;
$('#feature1 li').hover(function() {
var idx = $(this).index();
$hoveredElm = $feature2.find('li').eq(idx).show();
}, function(){
$hoveredElm.hide();
});

jQuery selector and cloning in a smart fashion

I am having trouble finding the way to solve this issue. I have this ul-menu output by Wordpress:
<ul class="menu">
<li>
Page 1
</li>
<li>
Page 2
</li>
</ul>
But I want the end result to be like this - cloning and appending the anchor and put a clone below:
<ul class="menu">
<li>
Page 1
Page 1
</li>
<li>
Page 2
Page 2
</li>
</ul>
I have used jQuery - but I am not having any luck at all for 2 hours of trial and error. This is as close as I can get. But it is wrong.
/*jQuery*/
$('.menu li a:first-child').eq(0).clone().insertAfter('.menu li a:first-child');
Fiddle here: http://jsfiddle.net/67jXz/1/
You're not supposed to .eq(0); that will limit it to the first a element that's matched, so that will be cloned and inserted after every subsequent a, resulting in copies of "Page 1".
Instead, you need to perform the cloning and inserting for each individual element by iterating with .each(), like so:
$('.menu li a:first-child').each(function() {
$(this).clone().insertAfter(this);
});
Note that the .insertAfter(this) part refers to inserting the cloned element after the original element that was matched by the .menu li a:first-child selector; the same this in $(this) that references the matched element.
Updated fiddle
Try this code:
$(function(){
$('.menu li a:first-child').each(function(k,v){
$(v).clone().insertAfter(v);
});
});
jsfiddle

jQuery Retrieve ID

I tried tackling my first project, an accordion menu. I have set to each item that needs to show/hide a class of .menu and an id.
While trying to retrieve the id's of each element i've used this statement:
var $currentId = $('ul.menu').attr('id');
Only problem is that it seems this only retrieves the id of the first element. Can anyone tell how can I retrieve all the It's to store them in a variable. I am planing to use if statements in order to check for each particular id when it's clicked.Thank You!
EDIT:It seems I was misunderstood what I have to do is this I'll start from the beginning:
Here is my HTML :
<ul id="container">
<li class="select">Downloads</li>
<li >
<ul class = "menu" id="first" >
<li>
iTunes
</li>
<li>
iTunes
</li>
</ul>
</li>
<li class="select">
Products List
</li>
<li>
<ul class = "menu" id="second" >
<li>
iTunes
</li>
<li>
iTunes
</li>
</ul>
</li>
What I have to do is when I click on the li with class of select I have to make the ul with the class of menu appear. How I wanted to do this to retrieve all the id's of the ul.menu and store them in a variable and when I click on any of the li.select the underlying ul should show.
Use each loop to get the ids of each element. Inside the loop use just just use this.id to get the id of the element where `this represents the dom element.
$('ul.menu').each(function(){
alert(this.id);
});
If you want the ids of all elements into an array you can use jQuery map method.
var Ids = $.map($('ul.menu'), function(){
return this.id;
});
map() translates all items in an array or object to new array of items. Ids will contain the ids of all the elements.
Then you can use $.inArray to search for a specific id within it. It will return its index or -1 if not found in the array.
if($.inArray("someId", Ids) != -1){
//Id found in the array
}
You may need to iterate over all the items and check the current status.
You can do this using the each method.
You can even dynamically add a listener for the click event for each element that matches your selector (in this case 'ul.menu'):
$('ul.menu').each(function(){
$(this).click(function()
{
alert('click');
});
});
EDIT: You can do this to hide/show the secondary items when the li.select items are clicked:
$('li.select').click(function(){
$(this).next().toggle();
});
This will give you an array that contains the ids:
var listOfIds = [];
$('ul.menu').each(function(){ listOfIds.push(this.id); });
The better thing to do would be to use
$('ul.menu li').click(function(event){
$(this).attr('id');
});
That will setup an event listener for each menu item and then allow you to do some thing when that menu item is clicked. The line with $(this).attr('id') can be replaced with any code you wish. Maybe even $(this).find('ul').show();

Categories