Get element after a specific sibling element by the sibling's text - javascript

I have the following html code:
<div class="account-type">
<h3>Assets</h3>
<ul> ...lots of data in here... </ul>
<div class="account-type">
<h3>Liabilities</h3>
<ul> .... lots of elements in here... </ul>
How do I isolate the div tag with the class of "account-type" that is the direct parent of the h3 tag with the text "Liabilities"? I need to isolate it and then loop through all of the elements in it's ul tags.

Assuming <ul> should come after <h3>, you can use this combination:
:contains
:next
children
function getItemByTitle( title ){
return $(`h3:contains("${title}")`).next('ul').children()
}
var listItems = getItemByTitle("Liabilities")
console.log(listItems.length)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="account-type">
<h3>Assets</h3>
<ul></ul>
</div>
<div class="account-type">
<h3>Liabilities</h3>
<ul>
<li>1</li>
<li>2</li>
</ul>
</div>

There is no text match in DOM so need to select all the elements, look to see if the text matches. If it does select the parent.
const h3 = Array.from(document.querySelectorAll(".account-type > h3")).find(elem => elem.textContent.trim() === 'Liabilities');
console.log(h3)
const div = h3.closest(".account-type");
console.log(div);
const lis = div.querySelectorAll("ul li");
console.log(lis.length);
// or
console.log(h3.nextElementSibling.children)
<div class="account-type">
<h3>Assets</h3>
<ul></ul>
</div>
<div class="account-type">
<h3>Liabilities</h3>
<ul>
<li>a</li>
<li>b</li>
</ul>
</div>

Related

How could I replace multiple div without set few functions onclick?

I'm using vanilla JS for some reasons and trying to replace div content while click on li.
I'm tried to replace by function(target, source) but target is always = id.
So I'm clone my function and onclick li insert 2 functions + params.
<body>
<li onClick="replaceContentInContainer('target', 'replace_target_div2'); replaceContentInContainerTwo('targetTwo', 'replace_target_div2_02')">View Div 2</li>
<li onClick="replaceContentInContainer('target', 'replace_target_div3'); replaceContentInContainerTwo('targetTwo', 'replace_target_div3_02')">View Div 3</li>
<div>
<span id="target">div1</span>
</div>
<div style="display:none">
<span id="replace_target_div2">div2</span>
</div>
<div style="display:none">
<span id="replace_target_div3">div3</span>
</div>
<div>
<span id="targetTwo">div1</span>
</div>
<div style="display:none">
<span id="replace_target_div2_02">div2 02</span>
</div>
<div style="display:none">
<span id="replace_target_div3_02">div3 03</span>
</div>
</body>
<script>
function replaceContentInContainer(target, source) {
document.getElementById(target).innerHTML = document.getElementById(source).innerHTML;
}
function replaceContentInContainerTwo(targetTwo, sourceTwo) {
document.getElementById(targetTwo).innerHTML = document.getElementById(sourceTwo).innerHTML;
}
</script>
I would like to have elegant way to do so.
I think what you mean is that you want to keep your HTML clean.
You could use a click eventhandler on all li within a certain ul.
HTML
<ul id="theList">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
JS add Click event handler
// Get all list items in ul with id 'theList'
var listItems = document.querySelectorAll('#theList li');
// Add a click event handler on each list item
for (i = 0; i < listItems.length; i++) {
listItems[i].addEventListener("click", function(){
console.log(this) // This is your target html
});
}
For the last step I'm not sure what you want. I don't know how your source is chosen. I will edit if you explain it more.
You can user this code:
<body>
<li onClick="replaceContentInContainer('target', 'div2');">View Div 2</li>
<li onClick="replaceContentInContainer('target', 'div3')">View Div 3</li>
<div>
<span class="target">div1</span>
</div>
<div>
<span class="target">div1</span>
</div>
</body>
<script>
function replaceContentInContainer(div, text) {
var ids = document.getElementsByClassName(div);
for (var i = 0; i < ids.length; i++) {
ids[i].innerText = text;
}
}
</script>

how to get text inside a li element on click in pure javascript

The folliwing code is working ONLY with the getElementById method, but i need it to works even in the case there is not an ID on element.
My HTML is:
<div id="container">
<ul class="menu">
<li>
<ul class="submenu">
<li>text i have to get</li>
</ul>
</li>
</ul>
</div>
My JS is:
<script>
var el = document.getElementById("pid");
el.onclick = function what_to_do(){
var theText = this.innerHTML;
alert(theText);
</script>
So i need to get the text in the deepest nested LI element that has no ID when the user clicks over it.
usually with jquery i can make $("#container ul li ul li").on("click, ...
but i am trying to work with pure javascript (vanilla js).
Is there anyone else that can help me?
Thanks in advance
You can use document.querySelectorAll().
Note: You can't just set event to the document.querySelectorAll() like jQuery you need to loops through whole array
const items = document.querySelectorAll('li > ul > li');
items.forEach(item => {
item.addEventListener('click',(e)=>{
console.log(e.target.textContent);
}
)
})
<div id="container">
<ul class="menu">
<li>
<ul class="submenu">
<li>text i have to get</li>
</ul>
</li>
</ul>
</div>
use document.querySelector
var el = document.querySelector("#container > .menu > li > .submenu > li");
el.onclick = function what_to_do(){
var theText = this.innerHTML;
alert(theText);
}
<div id="container">
<ul class="menu">
<li>
<ul class="submenu">
<li>text i have to get</li>
</ul>
</li>
</ul>
</div>

Remove child elements, but keep contents using jQuery/javascript

So I have some HTML that looks like this:
<div class="spinning-items">
<div>
<ul>
<li>
Hello, How Are You?
</li>
</ul>
</div>
</div>
I need to remove all the elements inside the "spinning-items" - div, but keep it's contents. In this case "Hello, How Are you?".
So, I want it to look like this afterwards:
<div class="spinning-items">
Hello, How Are You?
</div>
Can anyone please point me in the right direction, or perhaps help me with a working solution?
Thank you in advance.
Try following
$(".spinning-items").html($(".spinning-items").text().trim())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="spinning-items">
<div>
<ul>
<li>
Hello, How Are You?
</li>
</ul>
</div>
</div>
In case there are more than 1 element with class spinning-items
$(".spinning-items").each((i,e) => $(e).html($(e).text().trim()))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="spinning-items">
<div>
<ul>
<li>
Hello, How Are You?
</li>
</ul>
</div>
</div>
<div class="spinning-items">
<div>
<ul>
<li>
Hello, How Are You Doing?
</li>
</ul>
</div>
</div>
With native javascript you can do this using regex and trim() to remove white space
let k = document.getElementsByClassName('spinning-items')[0].innerHTML;
var rex = /(<([^>]+)>)/ig;
document.getElementsByClassName('spinning-items')[0].innerHTML = k.replace(rex, "").trim();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="spinning-items">
<div>
<ul>
<li>
Hello, How Are You?
</li>
</ul>
</div>
</div>
$(".spinning-items"")
.clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.text(); //get the text of element
this will give you only text

Chaining jquery append

I'm trying to figure out how I can chain multiple append into my markup. Basically after appending an element, I would like the next element to append it to the first appended element. I hope what I'm saying makes sense.
If you take a look at my code, I just appended the element <ul class="menu" /> into the element #footer .research-centers-menu .research.
Then on the next code I'm trying to insert/append the variable centers to the <ul class="menu" />
The current output right now doesn't insert the element but places it outside instead. Apologies for my bad english and explanation
var researchCenters = $('a[href$="/items"]').next().clone(),
centersList = $('li', researchCenters),
centers = centersList.slice(0);
var research = $('#footer .research-centers-menu .research').append('<ul class="menu" />');
$(research).append(centers);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<ul>
<li>item one</li>
<li>item two</li>
</ul>
</li>
</ul>
<div id="footer">
this is a footer
<div class="research-centers-menu">
<div class="research">
</div>
</div>
</div>
The cause of your appending issue is because append() returns the original element, not the appended element.
To make your code work you could invert the logic so that you create the new ul, then use appendTo(). This will retain the reference required to append the li. Try this:
var researchCenters = $('a[href$="/items"]').next().clone(),
centersList = $('li', researchCenters);
var $research = $('#footer .research-centers-menu .research');
var $ul = $('<ul class="menu" />').appendTo($research);
$ul.append(centersList);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<ul>
<li>item one</li>
<li>item two</li>
</ul>
</li>
</ul>
<div id="footer">
this is a footer
<div class="research-centers-menu">
<div class="research"></div>
</div>
</div>
try to append like this.
var researchCenters = $('a[href$="/items"]').next().clone(),
centersList = $('li', researchCenters),
centers = centersList.slice(0);
var research = $('#footer .research-centers-menu .research')
var ul =$('<ul class="menu" />').append(centers);
research.append(ul);

Locate the value of an attribute, match and find the value on other elements and alter the css

So essentially I am trying to find the value of an attribute, in this instance, 'data-location', and then search for that value elsewhere, in this instance in the form of an ID, and alter the CSS for that matched value.
I have the below so far which I thought would work, but I am not sure how to check for various different values for various elements and apply accordingly, so I have grouped the different sections in div's with classes so I can break them up from one another
Thanks guys
var getvalue = $('ul#test').find('li').attr('data-location');
if( $('div.other div').attr('id').val() == getvalue ) {
$( this ).css('background-color','red');
};
#thebirchplot3 {
padding:30px;
background:#fff;
}
#theashplot3 {
padding:30px;
background:blue;
color:#fff;
}
#thediveplot1 {
padding:30px;
background:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h1 id="title">Change CSS based on values</h1>
<ul id="test">
<li data-location="thebirchplot3">one</li>
<li data-location="theashplot3">two</li>
<li data-location="thediveplot1">three</li>
</ul>
<ul id="show">
<li data-location="theashplot3">one</li>
<li>two</li>
<li>three</li>
</ul>
<ul id="display">
<li data-location="thediveplot1">one</li>
<li>two</li>
<li>three</li>
</ul>
------
<div>
<div class="other">
<div id="thebirchplot3">
adfasdfasfsafdsafdsfsadfdsafdsafdsfafadsf
</div>
<div id="theashplot3">
adfasdfasfsafdsafdsfsadfdsafdsafdsfafadsf
</div>
<div id="thediveplot1">
adfasdfasfsafdsafdsfsadfdsafdsafdsfafadsf
</div>
</div>
</div>
You need to do it like below:-
Working Example:-
$('ul#test').find('li').each(function(){ // iterate over each li element
var ultest = $(this); //assign current li object to variable
$('div.other').children().each(function(){ // now iterate to each child div of other div
if($(this).attr('id') == ultest.data('location')){ // compare id with data-location
$( this ).css('background-color','red'); // if same then add background color
}
});
});
#thebirchplot3 {padding:30px;background:#fff;}
#theashplot3 {padding:30px;background:blue;color:#fff;}
#thediveplot1 {padding:30px;background:yellow;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 id="title">Change CSS based on values</h1>
<ul id="test">
<li data-location="thebirchplot3">one</li>
<li data-location="theashplot3">two</li>
<li data-location="thediveplot1">three</li>
</ul>
<ul id="show">
<li data-location="theashplot3">one</li>
<li>two</li>
<li>three</li>
</ul>
<ul id="display">
<li data-location="thediveplot1">one</li>
<li>two</li>
<li>three</li>
</ul>
------
<div>
<div class="other">
<div id="thebirchplot3">
this is dummy
</div>
<div id="thebirchplot355435">
text
</div>
<div id="theashplot3">
which shows you
</div>
<div id="theashplot35465464">
that everything
</div>
<div id="thediveplot1">
working fine now
</div>
</div>
</div>
use jquery find() method for your requirement as
var getvalue = $('ul#test').find('li').attr('data-location');
$('div.other').find('#'+getvalue).css('background-color','red');
working fiddle is js fiddle

Categories

Resources