Dynamically calling attirb value from li class through jQuery - javascript

Could you please help me in dynamically calling attrib value through jQuery from the 'li class' by identifying the 'itemprop'?
My HTML is as below,
<ul class="blockNoBordr">
<li class="specHeading">Model</li>
<li class="specText" itemprop="model">
<span class="attribVal newattribVal">32LJ573D</span>
</li>
</ul>
I want to dynamically call Model value into a JS code i.e., 32LJ573D

console.log($('ul li[itemprop="model"].specText').first().text());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="blockNoBordr">
<li class="specHeading">Model</li>
<li class="specText" itemprop="model">
<span class="attribVal newattribVal">32LJ573D</span>
</li>
</ul>
You need to pick li inside your ul with a specific class. The following code will work for you. I have printed text of li with class "specText" for reference. You could modify any attribute as per your requirement.
console.log($('ul li[itemprop="model"].specText').first().text());

When you choose elements by classname, multiple elements are returned in an array. So choose the first element by adding index [0].
$('.classname')[0].innerHTML

Related

Deal with multiple ID's in document

I have a problem dealing with duplicate ID's. I'm also aware it's very bad practise to have elements with the same ID but in this case, I'll end up having to change a massive part of the application to change the ID's so they can be unique.
I am having a problem toggling classes on an element in jQuery. My structure is below:
<ul>
<li id="wl-7050"> <!-- This acts as a main data group holder for the below li elements -->
<span></span>
<div id="wlHeader-7050"></div>
<div id="wlBody-7050">
<ul>
<li id="wl-7050"> <!-- This is the single element version of the data group header as above -->
<div id="wlHeader-7050"></div>
</li>
<li id="wl-7051"></li>
<li id="wl-7052"></li>
<li id="wl-7053"></li>
</ul>
</div>
</li>
</ul>
What I'm needing is a function where if I click the first instance of ID wl-7050, the child elements receive a new class. Whereas, if I select the second (single) element with ID of wl-7050 then only that one element has the new classes added to it.
I've tried using jQuery along with it's :first & :eq(0) attributes but still no luck unfortunately.
I do have classes assigned to each li element and it's child elements but whenever I run $('#wl-7050:eq(0)'), it returns both and the parent wl-7050 element get's used also.
I am flexible with JavaScript and jQuery answers.
The id attribute specifies a unique id for an HTML element (the value must be unique within the HTML document).
You can't have two wl-7050. Use classes. Then to work on "add new class on click" it's just hard code. If you need a help I can edit my answer. But is just coding. Html IDs is a concept
I've been there before: I've had to deal with applications that do weird things, where changing them to be "correct" causes more grief than just dealing with it and moving on. You know duplicate IDs are bad, I know duplicate IDs are bad; let's sort the problem. (Yes, they're bad. Yes, they shouldn't be there. Unfortunately, there they are.)
You can treat IDs just like any other attribute on an element: they're attributes, albeit special ones. Code like this will work to select all elements with the same ID: $('[id=wl-7050]').
Now, we need to bind a click event to them. We'll do the same thing as we always do:
var lis = $('[id=wl-7050]').click(function(e){
console.log(this);
});
Here's the trick, and it would happen even if these elements all had different IDs: when you're clicking in a child LI, that click event will bubble up to the parent. We'll need to shut off event propagation so we don't trigger our click event twice:
var lis = $('[id=wl-7050]').click(function(e){
e.stopPropagation();
console.log(this);
});
Now we're in business and can work to figure out which type of LI we're working with: top-level or child.
var lis = $('[id=wl-7050]').click(function(e){
e.stopPropagation();
if ($(this).children('li').length > 0) {
// Top-level LI
}
else {
// Child-level LI
}
});
That should get you where you need to be. Let's all agree to never speak of those duplicate IDs again.
If you can't change the IDs, you could try adding a different class name to both elements:
<ul>
<li id="wl-7050" class="wl-7050-main">
<span></span>
<div id="wlHeader-7050"></div>
<div id="wlBody-7050">
<ul>
<li id="wl-7050" class="wl-7050-single">
<div id="wlHeader-7050"></div>
</li>
<li id="wl-7051"></li>
<li id="wl-7052"></li>
<li id="wl-7053"></li>
</ul>
</div>
</li>
</ul>
Then you query with:
$("#wl-7050.wl-7050-main");
$("#wl-7050.wl-7050-single");
You don't need to add an id to each li that would make it overly complicated. Just use classes inside your items and call them this way:
$("#group li").on("click", function(){
alert($(this).data("id"));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id="wl-7050"> <!-- This acts as a main data group holder for the below li elements -->
<span></span>
<div id="header"></div>
<div id="body">
<ul id="group">
<li data-id="1"> <!-- This is the single element version of the data group header as above -->
<div class="wlHeader"></div>
</li>
<li data-id="2"> <!-- This is the single element version of the data group header as above -->
<div class="wlHeader"></div>
</li>
<li data-id="3"> <!-- This is the single element version of the data group header as above -->
<div class="wlHeader"></div>
</li>
</ul>
</div>
</li>
</ul>

jQuery - known class of child: find next descendent of parent in top (from parent ID)

I've been searching a lot for this, without any solution so far. As you might also have seen the topic title might be a little hard to interpret and that's because I'm not quite sure how to explain it shortly.
The problem
Looking at the HTML below, I know the class of the last element called "active" and this element is chosen dynamically in jQuery, based on which site the visitor is on currently - i.e. different elements has this class depending on the site. On another site the li with class first-sub-li could have the class active (or for that matter the li with class first). This class is, as said, added dynamically based on the site with jquery. From here on I wish to identify the parent of the element with active which is a direct descendent of top-parent and add a class called active-parent to this. I.e. in the case below i wish to add the active-parent class to the li with class second.
EDIT: Please note that the "depth" of the list can vary, therefore also requiring a "dynamic" approach to picking out the parent. I completely forgot this in the initial writing.
<ul id="top-parent">
<li class="first">
<ul class="first-sub-ul">
<li class="first-sub-li"></li>
</ul>
</li>
<li class="second">
<ul class="second-sub-ul">
<li class="second-sub-li">
<ul class="second-sub-sub-ul">
<li class="second-sub-sub-li active"></li> <!-- Here -->
</ul>
</li>
</ul>
</li>
</ul>
So far I've tried the following jQuery without succes as it doesn't identify it.
EDIT 2: This actually does work, but initially it didn't as it apparently was called before the class was loaded, despite appearing later in the javascript document. Wrapping it in a $(window).on("load", function() solves the problem as shown below.
$(window).on("load", function() {
$(".active").closest("#top-parent > li").addClass("active-parent");
});
The original code was just $(".active").closest("#top-parent > li").addClass("active-parent");
You can start traversing up with .parent(), it will excluding the self li.
$(".active").parent().closest("li").addClass("active-parent");
You can use :has() selector
$('#top-parent > li:has(.active)').addClass("active-parent");
$('#top-parent > li:has(.active)').addClass("active-parent");
.active-parent {
background-color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="top-parent">
<li class="first">
<ul class="first-sub-ul">
<li class="first-sub-li"></li>
</ul>
</li>
<li class="second">
<ul class="second-sub-ul">
<li class="second-sub-li">
<ul class="second-sub-sub-ul">
<li class="second-sub-sub-li active"></li>
<!-- Here -->
</ul>
</li>
</ul>
</li>
</ul>
I think this is what you're looking for. Find all li which are direct descendants of topmost-parent and filter that for the one which has a child .active. Apply the class.
$('#top-parent > li').filter(function(e){
return $(this).find('.active').length>0;
}).addClass("active-parent");
.active-parent{background-color:red}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="top-parent">
<li class="first">
<ul class="first-sub-ul">
<li class="first-sub-li">1.1</li>
</ul>
</li>
<li class="second">
<ul class="second-sub-ul">
<li class="second-sub-li active">2.1</li> <!-- Here -->
</ul>
</li>
</ul>

targeting a li with javascript without a ID

I have a mobile nav, that looks like this
<ul id="mobile-menu" class="menu>
<li class="normal-link">link-1</li>
<li class="dropdown-link">link-2
<ul class="submenu">
<li class="link-of-dropdown>blabla</li>
<li class="link-of-dropdown>blabla</li>
<li class="link-of-dropdown>blabla</li>
</ul>
</li>
<li class="dropdown-link">link-3
<ul class="submenu">
<li class="link-of-dropdown>blabla</li>
<li class="link-of-dropdown>blabla</li>
</ul>
</li>
<li class="normal-link">link-1</li>
</ul>
I cant change the html/wordpress generated code, but I can add css and javascript. So is there a way for me to get next to the dropdown-link's a image that will let the submenu free. if the image is pushed the image will change. if pushed again it will go back to the normal image and the dropdown dissappears again?
I am mostly looking for answer for the problem with of javascript on the dropdown link's but just so you know what i want to do with it.
This question is so very, very vague. But I guess you're looking for the nth-child() selector.
See the docs here for more information. Target your 'mobile-menu' ul, and use nth-child to select the li elements within.
My big question would be, why can't you change the HTML? If it's Wordpress, you can modify the template to change the HTML.
You question is not really clear but if you want to retrieve an element without using id, first you may use their classes
var myClass = document.getElementsByClassName("classname"); //returns a nodeList like array
myClass[0] //first element with "classname"
You may also use tag names
var divs = document.getElementsByTagName("div");
divs[2] //third "divs"
You may also use querySelectorAll, this works pretty much like CSS selector and also returns a nodeList
var qs = document.querySelectorAll(".class");
I hope this helps
You could add a class and use the Jquery class selector: $(".class-name") to target a specific <li>

.first() element not working with dynamic generated <li>

I think I am missing some minor concept here, but have done enough googling to find that but no use. Hence posting on this forum seeking some help.
I am generating navigation tab dynamically using this code:
<div class="tabbable">
<ul class="nav nav-tabs" id="testing">
<li ng-repeat="storageOption in gridOptions[$index].ownedJay" class=""><a href="#c{{storageOption.StorageHostname}}" >Data{{storageOption.StorageHostname}}</a></li>
</ul >
In above code, class is left blank. Above code can create many li based on number of elements in storageOption (ng-repeat).
But I want to add class "active" in first li only.
For that I have added following code in the script section of same page:
$(".tabbable ul li").first().addClass("active");
But above code is adding active class in all the li generated.
Can anyone please let me know where I am missing here.
Thanks in advance.
You need to do it in angular way, as angular does provided that option by ng-class that basically need expression like ng-class="{'class': expression}".In ng-class expression you could use $first that tells you its first element of ng-repeat or not, and use ng-href instead of href.
Markup
<li ng-repeat="storageOption in gridOptions[$index].ownedJay" ng-class="{'active': first}">
<a ng-href="#c{{storageOption.StorageHostname}}" >Data{{storageOption.StorageHostname}}</a>
</li>
Alternative
If you want to make active togglable then you could simply maintain one flag that will have the information of which li is selected.
<ul class="nav nav-tabs" id="testing" ng-init="selected=0">
<li ng-repeat="storageOption in gridOptions[$index].ownedJay"
ng-class="{'active': $index == $parent.selected}"
ng-click="$parent.selected == $index">
<a ng-href="#c{{storageOption.StorageHostname}}" >
Data{{storageOption.StorageHostname}}
</a>
</li>
</ul >
In above markup I used $index but you could unique thing if you have it you ng-repeat array.
$(".tabbable").find('li:nth-child(1)').addClass("active");
Try using a different selector to select the first li
FIDDLE
You can use ng-class attribute to check if the $index is 0 then add class active.

jQuery Mobile: unordered list

I have a an unordered list like this:
<ul id="mylist">
<li id="1">Heading</li>
<li id="2">Second</li>
</ul>
What I want to do is, when I add another list item:
<li id="3">First</li>
It needs to be prepended to the list item which is just below the first list item in "mylist". ie, just below 'Heading' in this case. So the final list looks like this:
<ul id="mylist">
<li id="1">Heading</li>
<li id="3">First</li>
<li id="2">Second</li>
</ul>
Thanks in advance.
NB: What I learned from trying to implement this is, when we append or prepend some content to an element selected with jQuery, it'll get prepended or appended to the content inside the selected element.
You can use after method and :first selector:
$('#mylist li:first').after('<li id="3">First</li>')
http://api.jquery.com/after/
You can use .after, or .insertAfter, for being more precise about placement in the DOM tree.

Categories

Resources