Get inner text to the before lastchild element - javascript

I have the following example, where I'm trying to extract the inner text for "a" element , which is a child of "i" element located before the last child of the list.
Example:
<div class="lms-pagination" id="lms-pagination">
<ul>
<li class="disabled">
<span class="current prev">Previous page</span>
</li>
<li class="active">
<span class="current en-lang">1</span>
</li>
<li>
<a data-page="1" class="page-link en-lang">2</a>
</li>
<li>
<a data-page="2" class="page-link en-lang">3</a>
</li>
<li class="disabled"><span class="ellipse">...</span></li>
<li>
<a data-page="17" class="en-lang">18</a> <!-- Try to extract 18 in this example -->
</li>
<li>
Next page
</li>
</ul>
</div>
I'm trying to use something like
lastPage = await newPage.$$eval('#lms-pagination>ul>li:nth-child(???)>a', el => el.innerText);

Using Javascript:=
function myFunction() {
var list = document.getElementById("myList").lastChild.innerHTML;
document.getElementById("demo").innerHTML = list;
var items = document.querySelectorAll("li");
var lastchild = items[items.length - 2].innerHTML;
document.getElementById("demo1").innerHTML = lastchild;
}
<p>Example list:</p>
<ul id="myList">
<li>Coffee</li>
<li>Tea</li>
<li>Coffee22</li>
<li>Tea22</li>
<li>Coffee33</li>
<li>Tea33</li>
</ul>
<p>Click the button to get the HTML content of the list's last child node.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<p id="demo1"></p>
<script>
</script>
Using jQuery:=
alert($("li:nth-last-of-type(2)").text())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="lms-pagination" id="lms-pagination">
<ul>
<li class="disabled">
<span class="current prev">Previous page</span>
</li>
<li class="active">
<span class="current en-lang">1</span>
</li>
<li>
<a data-page="1" class="page-link en-lang">2</a>
</li>
<li>
<a data-page="2" class="page-link en-lang">3</a>
</li>
<li class="disabled"><span class="ellipse">...</span></li>
<li>
<a data-page="17" class="en-lang">18</a>
<!-- Try to extract 18 in this example -->
</li>
<li>
Next page
</li>
</ul>
</div>

You can get second last child value like this.
$("li").eq(-2).text()

Related

Filter nested elements using javascript

I have a nested list with groups and subgroups, and links contained therein.
function filtersearch() {
var input, filter, ul, tr, search, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
ul = document.getElementById("list");
tr = ul.getElementsByTagName("li");
for (i = 0; i < tr.length; i++) {
search = tr[i].getElementsByTagName("a")[0];
txtValue = search.textContent || search.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
<input id="myInput" class="RxSearchbox" onkeyup="filtersearch()" placeholder="Filter" title="Filter list" type="text">
<div id="list">
<ul>
<li>
Group 1
<ul>
<li>
Subgroup1
<ul class="nav">
<li>
link1
</li>
<li>
link2
</li>
<li>
link3
</li>
<li>
link4
</li>
<li>
link5
</li>
</ul>
</li>
<li>
Subgroup2
<ul class="nav">
<li>
link6
</li>
<li>
link7
</li>
<li>
link8
</li>
<li>
link9
</li>
<li>
link10
</li>
</ul>
</li>
<li>
Subgroup3
<ul class="nav">
<li>
link11
</li>
<li>
link12
</li>
<li>
link13
</li>
<li>
link14
</li>
<li>
link15
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
I have an input box and am using Javascript to try to filter that list (e.g. if you type in "1", it would only show "1", "10", "11", "12", "13" etc., but it's only doing so on the parent element (i.e. will only show "Group 1") and not the children.
How can I get the script to filter all elements of li, parents and children, not just the parent?
Based on your HTML structure, the following JS code shall work fine.
P.S. Only unhide_parent() function was needed on top of your code.
function filtersearch() {
var input, filter, ul, tr, search, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
ul = document.getElementById("list");
tr = ul.getElementsByTagName("li");
for (i = 0; i < tr.length; i++) {
search = tr[i].getElementsByTagName("a")[0];
txtValue = search.textContent || search.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
unhide_parent(tr[i])
} else {
tr[i].style.display = "none";
}
}
}
unhide_parent = (ele) => {
if(ele.parentNode.parentNode.style.display=="none") {
ele.parentNode.parentNode.style.display='';
unhide_parent(ele.parentNode.parentNode)
}
};
<input id="myInput" class="RxSearchbox" onkeyup="filtersearch()" placeholder="Filter" title="Filter list" type="text">
<div id="list">
<ul>
<li>
Group 1
<ul>
<li>
Subgroup1
<ul class="nav">
<li>
link1
</li>
<li>
link2
</li>
<li>
link3
</li>
<li>
link4
</li>
<li>
link5
</li>
</ul>
</li>
<li>
Subgroup2
<ul class="nav">
<li>
link6
</li>
<li>
link7
</li>
<li>
link8
</li>
<li>
link9
</li>
<li>
link10
</li>
</ul>
</li>
<li>
Subgroup3
<ul class="nav">
<li>
link11
</li>
<li>
link12
</li>
<li>
link13
</li>
<li>
link14
</li>
<li>
link15
</li>
</ul>
</li>
</ul>
</li>
<li>
Group 2
<ul>
<li>
Subgroup-dup-1
<ul class="nav">
<li>
link-dup-1
</li>
<li>
link-dup-2
</li>
<li>
link-dup-3
</li>
<li>
link-dup-4
</li>
<li>
link-dup-5
</li>
</ul>
</li>
<li>
Subgroup-dup-2
<ul class="nav">
<li>
link-dup-6
</li>
<li>
link-dup-7
</li>
<li>
link-dup-8
</li>
<li>
link-dup-9
</li>
<li>
link-dup-10
</li>
</ul>
</li>
<li>
Subgroup-dup-3
<ul class="nav">
<li>
link-dup-11
</li>
<li>
link-dup-12
</li>
<li>
link-dup-13
</li>
<li>
link-dup-14
</li>
<li>
link-dup-15
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
I would start by placing a data attribute data-id within each li that corresponds with the link number. Then get all the .nav li elements using querySelectorAll('.nav li') this will return everyone of the list elements. Then you can iterate over these using a forEach loop checking the el.dataset.id to see if it includes the input.value, if it does we have a match.
You can then reference these however you wish, hidden elements you turn visible or highlighting the list-items a tag...
function filtersearch() {
const input = document.getElementById("myInput");
const lists = document.querySelectorAll('.nav li')
lists.forEach((list, i) => {
const dataId = list.dataset.id
dataId.includes(input.value) && input.value !== '' ?
list.children[0].classList.add('green') :
list.children[0].classList.remove('green')
})
}
.green {
background-color: lightgreen;
color: darkgreen;
}
<input id="myInput" class="RxSearchbox" onkeyup="filtersearch()" placeholder="Filter" title="Filter list" type="text">
<div id="list">
<ul>
<li>
Group 1
<ul>
<li>
Subgroup1
<ul class="nav">
<li data-id="1">
link1
</li>
<li data-id="2">
link2
</li>
<li data-id="3">
link3
</li>
<li data-id="4">
link4
</li>
<li data-id="5">
link5
</li>
</ul>
</li>
<li>
Subgroup2
<ul class="nav">
<li data-id="6">
link6
</li>
<li data-id="7">
link7
</li>
<li data-id="8">
link8
</li>
<li data-id="9">
link9
</li>
<li data-id="10">
link10
</li>
</ul>
</li>
<li>
Subgroup3
<ul class="nav">
<li data-id="11">
link11
</li>
<li data-id="12">
link12
</li>
<li data-id="13">
link13
</li>
<li data-id="14">
link14
</li>
<li data-id="15">
link15
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>

How to apply classes based on the open linked?

My sidebar menu has the ability to expand and reveal the subsections of a section as shown below. The open section has the open active class and the clicked link has the active class.
All of my links has a different #url.So this will determine the classes.
How can I automatically place the open active and active classes based on the opened link? I can also use PHP.
<ul class="menu-items scroll-content">
<li class="open active">
<a href="javascript:;"><span class="title">first section</span>
<span class="open arrow"></span></a>
<span class="icon-thumbnail">LV</span>
<ul class="sub-menu">
<li class="active">
First Section 1
<span class="icon-thumbnail">au</span>
</li>
<li class="">
First Section 2
<span class="icon-thumbnail">ou</span>
</li>
</ul>
</li>
<li class="">
<a href="javascript:;"><span class="title">Second section</span>
<span class="arrow"></span></a>
<span class="icon-thumbnail">LV</span>
<ul class="sub-menu">
<li class="">
Second Section 1
<span class="icon-thumbnail">au</span>
</li>
</ul>
</li>
</ul>
Try like this:
HTML:
<ul>
<li class="">
<a href="javascript:;"><span class="title">first section</span>
<ul class="sub-menu">
<li class="">
First Section 1
<span class="icon-thumbnail">au</span>
</li>
<li class="">
First Section 2
<span class="icon-thumbnail">ou</span>
</li>
</ul>
</li>
<li class="">
<a href="javascript:;"><span class="title">Second section</span>
<ul class="sub-menu">
<li class="">
Second Section 1
<span class="icon-thumbnail">au</span>
</li>
</ul>
</li>
</ul>
JS:
var href = location.pathname+location.hash;
$('.sub-menu > li > a').each(function() {
if ($(this).attr("href") == href) {
$(this).parent('li').addClass('active');
$(this).parent().parent().parent('li').addClass('open active');
}
});

jquery - Add html content within a selected div like a plugin

I would like to add some html content within a selected div like most of the plugins are.
Eg:
<div id="selected-div">
</div>
$('#selected-div').foo();
When the div (selected-div) is passed to the function, I would like to add the below html content inside that div (selected-div).
<div id="lorem-ipsum-wrapper">
<ul id="lorem-ipsum-main">
<li id="btn-header-wrapper" class="main-btn">
T
<ul>
<li>
T1
</li>
<li>
T2
</li>
<li>
T3
</li>
<li>
T4
</li>
</ul>
</li>
<li class="main-btn">
<b>E</b>
</li>
<li id="btn-justify-wrapper" class="main-btn">
Gender
<ul>
<li>
M
</li>
<li>
F
</li>
<li>
other
</li>
</ul>
</li>
<li class="main-btn" id="btn-list-wrapper">
List
<ul>
<li>
List 1
</li>
<li>
List 2
</li>
</ul>
</li>
<span class="clear_both"></span>
</ul>
</div>
Demo at codepen.
Which after execution should become like this
<div id="selected-div">
<div id="lorem-ipsum-wrapper">
<ul id="lorem-ipsum-main">
...
...
...
</ul>
</div>
</div>
How can I achieve this feature using jquery? Your help and guidance will be very much appreciated. Thank you.
Use .html()
$("#selected-div").html('<div id="lorem-ipsum-wrapper">..');
or .load()
$("#selected-div").load("/path/to/html")
var data = '<div id="lorem-ipsum-wrapper">
<ul id="lorem-ipsum-main">
<li id="btn-header-wrapper" class="main-btn">
T
<ul>
<li>
T1
</li>
<li>
T2
</li>
<li>
T3
</li>
<li>
T4
</li>
</ul>
</li>
<li class="main-btn">
<b>E</b>
</li>
<li id="btn-justify-wrapper" class="main-btn">
Gender
<ul>
<li>
M
</li>
<li>
F
</li>
<li>
other
</li>
</ul>
</li>
<li class="main-btn" id="btn-list-wrapper">
List
<ul>
<li>
List 1
</li>
<li>
List 2
</li>
</ul>
</li>
<span class="clear_both"></span>
</ul>
</div>';
$("#selected-div").html(data);
You can use the JQuery text() method like this
$("#selected-div").text($('#lorem-ipsum-wrapper').text());
Here is the JS code :
$(document).ready(function(){
$("#selecteddiv").load('add.html');
});
and in add.html, you can have your html code which you want to append.
here is the working Plnkr link.
hope it helps you
append would also be an option
http://api.jquery.com/append/
$("#selected-div").append($("<h1>Some content</h1>"));

Combine Navigation UL jQuery Function

I am trying to write a function that will combine two children ul#level_2and append them to their parent li#level_1 within a dropdown #navigation.
I currently have the following which does the job, but it means I have to manually target each category. I'm sure there is a far shorter way to produce the same results with very little code.
$('li#furniture ul.level_2').children('li').appendTo('li#furniture ul.level_2:first');
$('li#furniture ul.level_2').children('li').not(':first').remove();
Here is a shortened version of my current html structure & below is the desired result:
Simple Current HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1">
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2">
Link A
</li>
</ul>
<ul class="level_2">
<li class="level_2">
Link B
</li>
</ul>
</div>
</li>
</ul>
</div>
Desire HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1">
<ul class="level_2">
<li class="level_2">
Link A
</li>
<li class="level_2">
Link B
</li>
</ul>
</li>
</ul>
</div>
Full Detailed HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1 furniture">
Furniture
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2 sofa">
Sofa
</li>
</ul>
<ul class="level_2">
<li class="level_2 bed">
Bed
</li>
</ul>
</div>
</li>
<li class="level_1 bathroom">
Bathroom
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2 shower">
<a href="#">Shower/a>
</li>
</ul>
<ul class="level_2">
<li class="level_2 bath">
Bath
</li>
</ul>
</div>
</li>
</ul>
</div>
This should do what you need.
var wrapper = $(".subnav_wrapper").contents();
$(".subnav_wrapper").replaceWith(wrapper );
$('ul.level_2').children('li').appendTo('ul.level_2:first');
$('ul.level_2').not(':first').remove();
JSFIDDLE DEMO

finding the last span in DOM with a particular classname

<div class="comments_container clearfix">
<hr />
<ul class="comment_struct">
<li class="commenter_pic">
<img src="images/im.jpg" alt="picture"/>
<span class="button blue square likes">9 Likes</span>
</li>
<li class="comment_data">
<ul class="post_info_options">
<li class="commenter_name">Abc</li>
<li class="comment"><p>hello how are you doing</p></li>
<li class="time">
<span class="comment_time">12 June 2012<>
<span class="time_elapsed">7 hours ago</span>
</li>
<li class="options">
<span>Once More</span>
<span>Comment</span>
<span>Like</span>
</li>
<li>
</li>
</ul>
</li>
<li class="delete_comment"><img src="images/Cancel.png" alt="delete_post"/></li>
</ul>
<br/>
<ul class="comment_struct">
<li class="commenter_pic">
<img src="images/im.jpg" alt="picture"/>
<span class="button blue square likes">9 Likes</span>
</li>
<li class="comment_data">
<ul class="post_info_options">
<li class="commenter_name">Abc</li>
<li class="comment"><p>hello how are you doing</p></li>
<li class="time">
<span class="comment_time">12 June 2012<>
<span class="time_elapsed">7 hours ago</span>
</li>
<li class="options">
<span>Once More</span>
<span>Comment</span>
<span>Like</span>
</li>
<li>
</li>
</ul>
</li>
<li class="delete_comment"><img src="images/Cancel.png" alt="delete_post"/></li>
</ul>
<br/>
<ul class="comment_struct">
<li class="commenter_pic">
<img src="images/im.jpg" alt="picture"/>
<span class="button blue square likes">9 Likes</span>
</li>
<li class="comment_data">
<ul class="post_info_options">
<li class="commenter_name">Abc</li>
<li class="comment"><p>hello how are you doing</p></li>
<li class="time">
<span class="comment_time">12 June 2012<>
<span class="time_elapsed">7 hours ago</span>
</li>
<li class="options">
<span>Once More</span>
<span>Comment</span>
<span>Like</span>
</li>
<li>
</li>
</ul>
</li>
<li class="delete_comment"><img src="images/Cancel.png" alt="delete_post"/></li>
</ul>
<br/>
I have html structure as above .. so starting from $('.comments_container') how can i traverse to the last span in the DOM with class 'comment_time'. Help would be appreciated.
traversing using children() is possible. But i want to know is there any simpler way
You can use :last selector:
var mySpan = $('.comments_container span.comment_time:last');

Categories