match elements by data attribute and id - javascript

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

Related

Obtaining Upper level li text

So I currently have a list like so on my page
<li class="head">
<b>Introduction</b>
<ul>
<li class="sub">somethingsomething</li>
</ul>
</li>
This list is being used with sortable, so the user can decide on the order, and I am passing this information to a grails controller for use in application logic. So, I am trying to read it in, and place the text contained in the "head" and "sub" classes in 2 different arrays. However, when I use a jquery selector to obtain the head elements, and obtain the text attribute of the element, it contains the inside list as well.
$('#divname').find("ul > li.head").each(function()
{
var current = $(this);
console.log(current.text());
});
results in Introductionsomethingsomething
Is there any way to only obtain the 'Introduction' text from the list, and ignore the text in the nested <ul> and <li.sub>? Due to it being nested, I am unable to figure out how to use jQuery's :not() selector
You can find the b tag using jquery tagname selector.Like this:
var current = $(this).find('b');
console.log(current.text());
Working Demo
May be this is solution:
<script>
$('#divname').find("ul > li.head").each(function()
{
var current = $(this).find("b");
console.log(current.text());
});
</script>

How to get Value / Text of a List item Javascript

how can i get the Value / Text of a <li> item ?
I found on the internet much ways to get the value for a dropdown list.
But not for a <li> item.
This is what I have tried so far:
var listt = document.getElementById('content1');
var selectedvalue = [listt.selectedIndex].text;
You can use the innerText property for most browsers, but the textContent property for Firefox:
<ul>
<li id="myLi">Hello, world</li>
</ul>
var li = document.getElementById("myLi")
console.log(li.textContent || li.innerText);
Here is a fiddle to demonstrate.
If you are using jQuery (you say you are, but I see no evidence) it would be as simple as using the .text() function:
$("#myLi").text();
If your <li> contains HTML markup too, you may want that. In this case you need to use the innerHTML property:
document.getElementById("myLi").innerHTML;
Again, jQuery has it's own equivalent .html() which caters for all sorts of different browsers:
$("#myLi").html();
Assuming myLi is a reference to the <li> element you want to get the text of, it's as simple as:
myLi.innerText
Note that <li> elements don't have values, because they're not inputs. They have content which can be a string of text or HTML defining other page elements. If your <li> element contained other elements, and you wanted the HTML of those as a string, you could instead do:
myLi.innerHTML
What's the difference? Let's assume your HTML looked like this:
<li><span>Some text</span></li>
Then
console.log(myLi.innerHTML); // outputs: <span>Some text</span>
console.log(myLi.innerText); // outputs: Some text
I would just use innerHTML if your list item has an ID or class name and assuming there is no other html in your list item.
<ul>
<li class="list-item">Item1</li>
<li class="list-item">Item2</li>
<li class="list-item">Item3</li>
</ul>
<script>
var list = document.getElementsByClassName('list-item');
var listArray=[];
for (var i=0;i<list.length;i++){
listArray.push(list[i].innerHTML);
console.log(listArray[i]);
}
</script>
//output
Item1
Item2
Item3
You could also try using the textContent property perhaps or innerHTML for that matter if you wanna get plain text.
var li_item=document.getElementById('content1');
console.log(li_item.textContent)

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();

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

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.

Selecting element to copy using jQuery Clone

I have a guide where each chapter is located in a separate LI of a UL. I am trying to use the jQuery Clone function to search through the parent UL that contains all of these 'chapter' LIs, and return those chapters that contain specific text.
Right now, I'm getting odd results, likely because it's copying elements at their smallest child, rather than just the entire div.
Also, each of these chapter LIs should only be returned once.
makeIntoSldieshowUL - UL that contains all 'chapters'
slideShowSlide - class name for each 'chapter'
searchResultsArea - Div in which to append 'chapters' that contain text
So far I have:
$("#makeIntoSlideshowUL").find(".slideShowSlide:contains('" + $(this).val() + "')").clone().appendTo("#searchResultsArea");
To give you an idea of the content I'm looking to clone, here is a brief sample
<ul id="makeIntoSlideshowUL">
<li class="slideShowSlide" id="0">
<div class="topicTitle">Cardholder responsibilities</div>
<p>Cardholders are responsible for ensuring proper use of the card. If your division or department has approved you for a Pro-Card, you must use the card responsibly in accordance with the following requirements:</p>
<ul>
<li>Purchase items for UCSC business use only</li>
<li>Never lend or share your Pro-Card</li>
<li>Purchase only allowable goods and services</li>
</ul>
</li>
<li class="slideShowSlide" id="1">
<div class="topicTitle"><strong>Restricted and Unallowable Pro-Card Purchases</strong></div>
<p>Some types of purchases are restricted are not allowed with the Pro-Card. Disputes with suppliers are initially handled by the Cardholder if, for example, they don't recognize a transaction on their statement, or the amount doesn't match their receipt. The Cardholder is responsible for contacting the supplier immediately to try to resolve the matter.</p>
</li>
Use jQuery's .children() method instead of .find() since it sounds like the .slideShowSlide elements are immediate children.
$("#makeIntoSlideshowUL").children(".slideShowSlide:contains('" + $(this).val() + "')").clone().appendTo("#searchResultsArea");
Or you could use the > child selector instead.
$("#makeIntoSlideshowUL > .slideShowSlide:contains('" + $(this).val() + "')").clone().appendTo("#searchResultsArea");
EDIT: At one point, you seem to refer to the chapters as divs. If they're a child of the <li> elements, you'll likely need something like:
$("#makeIntoSlideshowUL > li > .slideShowSlide:contains('"...
try using the has or contains selector
has will not change the current element on the jquery stack.
$("#makeIntoSlideshowUL")
.has(".slideShowSlide:contains('" + $(this).val() + "')")
.clone()
.appendTo("#searchResultsArea");

Categories