Second hide and show div with link - javascript

So, yesterday I got advice with my html code which shows a div with text when I press on a link.
This is what I have https://jsfiddle.net/4qq6xnfr/3/
Got any idea after I get a div to show, an example if I click "felge"( in english wheels) I get BBS ENKEI and KONIG, I want to make those three also clickable to get a third div next to them, so basicly when i pick wheel from first div, bbs, enkei and konig appear and then those are clickable too, and then I can pick one of those from the second div to show a third one.
I tried this :
<div class="col-md-2">
<ul class="nav nav-pills nav-stacked" id="menu">
<li>Felge</li>
<li>Gume</li>
<li>Branici</li>
<li>Farovi</li>
</ul>
</div>
<div class="col-md-3">
<div class="nav nav-pills nav-stacked div" id="content1">
<ul>
---> <li>BBS</li>
<li>ENKEI</li>
<li>KONIG</li>
</ul>
</div>
<div class="div" id="content2">
<p>Michelin</p>
<p>Hankook</p>
<p>Sava</p>
</div>
<div class="div" id="content3">
<p>AMG</p>
<p>Brabus</p>
<p>Original</p>
</div>
<div class="div" id="content4">
<p>Angel Eyes</p>
<p>Devil Eyes</p>
<p>Original</p>
</div>
</div>
where I added a href in the second div, its marked with an arrow in the code above and did the same script with diferent names as for the first hide/show div but it doesnt work as it should. How should/could I do this?

Hope this may help you adding subcontent divs
<div class="col-md-4">
<div class="div" id="subcontent1">
<p>BBS</p>
<p>ENKEI</p>
<p>KONIG</p>
</div>
<div class="div" id="subcontent2">
<p>Michelin</p>
<p>Hankook</p>
<p>Sava</p>
</div>
<div class="div" id="subcontent3">
<p>AMG</p>
<p>Brabus</p>
<p>Original</p>
</div>
<div class="div" id="subcontent4">
<p>Angel Eyes</p>
<p>Devil Eyes</p>
<p>Original</p>
</div>
</div>`
and adding another javascript function
function showsub(id) {
var number = id.replace('sublink', '');
var blocks = document.querySelectorAll("[id^=subcontent");
for (var i = 0; i < blocks.length; i++) {
blocks[i].style.display = 'none';
}
document.querySelector('#subcontent' + number).style.display = 'block';
}
function show(id) {
var number = id.replace('link', '');
var blocks = document.querySelectorAll("[id^=content");
var subblocks = document.querySelectorAll("[id^=subcontent");
for (var i = 0; i < blocks.length; i++) {
blocks[i].style.display = 'none';
}
for (var j = 0; j < subblocks.length; j++) {
subblocks[j].style.display = 'none';
}
document.querySelector('#content' + number).style.display = 'block';
}
and position it according to where you need

Related

JavaScript, HTML search engine - how to get parent of an element?

My problem is:
Search script is working, but it only hides h3 elements from the code.
<h3 class="post-subtitle" style="display: flex;">Protokoły tunelowania VPN</h3>
<h3 class="post-subtitle" style="display: flex;">Certyfikat cyfrowy</h3>
I need the code to hide the whole div with "post" ID instead of just h3 element.
How do i do that?
HTML Code for Search Bar:
<div id="kontener" class="container">
<div style="text-align:center" id="search-bar">
<input type="text" id="searchbar" onkeyup="searchBar()" class="shadow-lg">
</div>
</div>
HTML Code on Website
<!-- First element -->
<div id="post">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-preview">
<a href="URL">
<h2 class="post-title"><i class="far fa-sticky-note fa-xs" aria-hidden="true"></i> ASO</h2>
<h3 class="post-subtitle" style="display: flex;">Protokoły tunelowania VPN</h3>
</a>
<p class="post-meta">11 Maj, 2021</p>
</div>
</div>
</div>
<hr>
</div>
<!-- End of First element -->
<!-- Second element -->
<div id="post">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-preview">
<a href="URL">
<h2 class="post-title"><i class="far fa-sticky-note fa-xs" aria-hidden="true"></i> ELSK</h2>
<h3 class="post-subtitle" style="display: flex;">Certyfikat cyfrowy</h3>
</a>
<p class="post-meta">26 Kwiecień, 2021</p>
</div>
</div>
</div>
<hr>
</div>
<!-- End of Second element -->
JavaScript code:
<script>
function searchBar() {
let input = document.getElementById('searchbar').value
input=input.toLowerCase();
let x = document.getElementsByClassName('post-subtitle');
for (i = 0; i < x.length; i++) {
if (!x[i].innerHTML.toLowerCase().includes(input)) {
x[i].style.display="none";
}
else {
x[i].style.display="flex";
}
}
}
</script>
You just need to target couple of parent nodes, either by .parentElement / .parentNode or use .closest function.
Example:
<script>
function searchBar() {
let input = document.getElementById('searchbar').value
input=input.toLowerCase();
let x = document.getElementsByClassName('post-subtitle');
for (i = 0; i < x.length; i++) {
if (!x[i].innerHTML.toLowerCase().includes(input)) {
x[i].closest('#post').style.display="none";
// Or this below (note each parentElement targets parent tag)
// x[i].parentElement.parentElement.parentElement.parentElement.parentElement.style.display="none";
}
else {
x[i].closest('#post').style.display="flex";
}
}
}
</script>

How to get children of a div

User can, by pressing a button, select a particular topic of interest. When that happens, various divs will either become visible or invisible depending on whether that div has a link referring to that topic.
function GetPostsByTopic(topic) {
var area = document.getElementById("postArea");
var topicAreas = area.getElementsByClassName("topicArea");
for (i = 0; i < topicAreas.length; i++) {
var children = topicAreas[i].children;
var topics = [];
for (j = 0; j < children.length; j++) {
topics.push(children[j].getAttribute("asp-route-name"));
document.getElementById("firstTest").innerHTML = children[j].toString();
}
var b = topics.includes(topic);
if (b == true) {
var parentId = document.getElementById(topicAreas[i]).parentNode.id;
document.getElementById(parent).style.display = 'block';
} else {
document.getElementById(parent).style.display = 'none';
}
}
}
<div class="topicBox">
<button class="topicButton" onclick="GetPostsByTopic('Pets')">Pets</button>
<button class="topicButton" onclick="GetPostsByTopic('Vacation')">Vacation</button>
</div>
<div id="postArea">
<div class="post" id="post1">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
<div class="post" id="post2">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Vacation">Vacation</a>
</div>
</div>
<div class="post" id="post3">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
</div>
The trouble, as far as I can tell, begin early in the JS part. I can see that when a do var children=topicAreas[i].children, I get nothing.
I hope this is what you're trying to do. Based on what button you click, respective div is displayed.
function GetPostsByTopic(topic) {
var area = document.getElementById("postArea");
var topicAreas = area.getElementsByClassName("topicArea");
for (i = 0; i < topicAreas.length; i++) {
var children = topicAreas[i].children;
for (j = 0; j < children.length; j++) {
var parentId = topicAreas[i].parentNode.id;
if(children[j].getAttribute("asp-route-name") === topic){
document.getElementById(parentId).style.display = 'block';
}else{
document.getElementById(parentId).style.display = 'none';
}
}
}
}
<div class="topicBox">
<button class="topicButton" onclick="GetPostsByTopic('Pets')">Pets</button>
<button class="topicButton" onclick="GetPostsByTopic('Vacation')">Vacation</button>
</div>
<div id="postArea">
<div class="post" id="post1">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
<div class="post" id="post2">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Vacation">Vacation</a>
</div>
</div>
<div class="post" id="post3">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
</div>
Children isn't the issue. When you run your code you get the error "Uncaught TypeError: Cannot set property 'innerHTML' of null". Looking at your code where you are using .innerHTML, we see that you are trying to reference an element that you don't have in this code:
document.getElementById("firstTest")
Now, after adding that, you still have some items that you should change.
asp-action and asp-route-name are invalid HTML. Are you using a
framework that requires this syntax?
Don't use .getElementsByClassName().
Use .querySelectorAll() and Array.forEach() on the result for
easier looping.
Don't use .innerHTML when you aren't working with HTML strings as there are security and performance implications to doing so.
Avoid inline styles when you can. Using them causes duplication of code and code is harder to scale. Instead, use CSS classes and the .classList API.
It's not super clear exactly what is supposed to happen when clicking your buttons, but see the updated code below:
function GetPostsByTopic(topic) {
var area = document.getElementById("postArea");
// Don't use .getElementsByClassName() as it provides a live node list
// and causes quite a performance hit, especially when used in loops.
// Use .querySelectorAll() and then use .forEach() on the collection that
// it returns to iterate over them.
area.querySelectorAll(".topicArea").forEach(function(area){
var topics = [];
// No need for children, here. Again, use .querySelectorAll()
area.querySelectorAll("*").forEach(function(child) {
topics.push(child.getAttribute("asp-route-name"));
document.getElementById("firstTest").textContent = child.getAttribute("asp-route-name");
});
if (topics.indexOf(topic) > -1) {
// Don't use inline styles if you can avoid it.
// Instead use pre-made classes.
area.classList.add("hidden");
}
else {
area.classList.remove("hidden");
}
});
}
/* Use CSS classes when possible instead of inline styles */
.hidden { display:none; }
<div class="topicBox">
<button class="topicButton" onclick="GetPostsByTopic('Pets')">Pets</button>
<button class="topicButton" onclick="GetPostsByTopic('Vacation')">Vacation</button>
</div>
<div id="postArea">
<div class="post" id="post1">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
<div class="post" id="post2">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Vacation">Vacation</a>
</div>
</div>
<div class="post" id="post3">
<div class="topicArea">
<a asp-action="Topic" asp-route-name="Pets">Pets</a>
</div>
</div>
</div>
<div id="firstTest"></div>

Vanilla Javascript insertBefore() in for loop

I have the following html structure.
<div id="page1" class="page">
<div class="firstchild"></div>
<div class="secondchild"></div>
<div class="thirdchild"></div>
<div class="forthchild"></div>
</div>
<div id="page2" class="page">
<div class="firstchild"></div>
<div class="secondchild"></div>
<div class="thirdchild"></div>
<div class="forthchild"></div>
</div>
<div id="page3" class="page">
<div class="firstchild"></div>
<div class="secondchild"></div>
<div class="thirdchild"></div>
<div class="forthchild"></div>
</div>
And my javascript structure is.
var pageCLASS = frame.querySelectorAll(".page");
//var pageCLASS = frame.getElementsByClassName('page')[0];
var leng = pageCLASS.length;
for (var i = 0; i < leng; ++i) {
var pageID = frame.getElementById('page' + (i + 1));
var firstchild = frame.getElementsByClassName('firstchild')[0];
var secondchild = frame.getElementsByClassName('secondchild')[0];
var thirdchild = frame.getElementsByClassName('thirdchild')[0];
pageID.insertBefore(thirdchild, firstchild.nextSibling);
//pageCLASS.insertBefore(thirdchild, firstchild.nextSibling);
}
Now I have problems with the thirdchild being moved to below the firstchild and above the secondchild in all of page1, page2, and page3 together. The code above only moves it in page1, but for the other 2 which does nothing. The frame shown in the source is an iframe stored on the same domain with access to it's elements. Can I please get some advice on what I am doing wrong as I want to move all thirdchilds in each div to below the first child in each of their parent div?
The problem you are having is that you are constantly targeting the same elements with e.g.
var firstchild = frame.getElementsByClassName('firstchild')[0];
because this instruction always returns the first occurrence of such an element in the iframe and never the second or third.
In order to be sure that you are targeting the correct elements you can rewrite some of your code to only search for the elements that are contained within a certain parent and not inside the whole iframe.
You can then use something like this instead
var firstChild = pageID.querySelector('.firstchild');
which will only search for an element (the first occurrence) with class firstchild that is contained within some other element (in this case the element saved in pageID).
Check below (I exchanged the form for document so we can test here):
var pageCLASS = document.querySelectorAll(".page");
var leng = pageCLASS.length;
for (var i = 1; i <= leng; i++) {
var pageID = document.getElementById('page' + i);
var firstChild = pageID.querySelector('.firstchild');
var thirdChild = pageID.querySelector('.thirdchild');
firstChild.parentNode.insertBefore(thirdChild, firstChild.nextSibling);
}
.page {
border: 1px solid #09f;
}
<div id="page1" class="page">
<div class="firstchild">first child</div>
<div class="secondchild">second child</div>
<div class="thirdchild">third child</div>
<div class="forthchild">fourth child</div>
</div>
<div id="page2" class="page">
<div class="firstchild">first child</div>
<div class="secondchild">second child</div>
<div class="thirdchild">third child</div>
<div class="forthchild">fourth child</div>
</div>
<div id="page3" class="page">
<div class="firstchild">first child</div>
<div class="secondchild">second child</div>
<div class="thirdchild">third child</div>
<div class="forthchild">fourth child</div>
</div>

How do I get text of nested div in a specific HTML list element as alert message onclick [duplicate]

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
This is my HTML file structure:
var li = document.getElementById("myList").getElementsByTagName("li");
for (var i = 0; i < li.length; i++) {
li.onclick = function () {
alert(document.getElementsByClassName("title")[i].innerHTML);
}
}
<div class="maincontent">
<ul id="myList">
<li>
<div class="image">
<img src="http://lorempixel.com/100/100/">
<div class="button option-vertical-grid"></div>
</div>
<div class="info">
<div class="url">lorempixel.com</div>
<div class="title" id="title">M1</div>
<div class="play"><section>0</section></div>
</div>
<div class="info2">
<div class="date">30.11.2016</div>
<div class="button option-vertical"></div>
</div>
</li>
<li>
<div class="image">
<img src="http://lorempixel.com/102/100/">
<div class="button option-vertical-grid"></div>
</div>
<div class="info">
<div class="url">lorempixel.com</div>
<div class="title">M2</div>
<div class="play"><section>0</section></div>
</div>
<div class="info2">
<div class="date">30.11.2016</div>
<div class="button option-vertical"></div>
</div>
</li>
<li>
<div class="image">
<img src="http://lorempixel.com/103/100/">
<div class="button option-vertical-grid"></div>
</div>
<div class="info">
<div class="url">lorempixel.com</div>
<div class="title">M3</div>
<div class="play"><section>0</section></div>
</div>
<div class="info2">
<div class="date">30.11.2016</div>
<div class="button option-vertical"></div>
</div>
</li>
</ul>
</div>
The first task is:
On click of the list it should show an alert message with the title of the clicked list, i.e. the text in the div class "title", i.e. (M1 or M2....)
The second task is:
On click of the div class "button option-vertical" it should give me another alert containing the class title as in task above and additionally the img src value from the div class "image", for example: (http://lorempixel.com/100/100)
When showing the alert from the second task, the alert from the first task should not be shown and vice versa. Please all without jQuery, only JavaScript.
With the JavaScript I tried above, a click on the list item doesn't give me any alert message.
The getElementsByClassName()|getElementsByTagName method returns a collection of all elements in the document with the specified class|tag name, as a NodeList object.
The NodeList object represents a collection of nodes. The nodes can be accessed by index numbers. The index starts at 0.
var li = document.getElementById("myList").getElementsByTagName("li"),
len = li.length,
i;
for (i = 0; i < len; i += 1) {
li[i].onclick = function() {
//Li only has one child with class "title"
alert(this.getElementsByClassName("title")[0].innerHTML);
}
}

Wrapping an anchor tag around dynamically generated divs

I have a div that generates multiple elements inside it:
<div class="lists">
<?php for($i=0;$i<6;$i++) { ?>
<div class="list history[[$i]]" id="history[[$i]]">
<div class="info">
<div class="picture monophoto">
<div class="text">BO</div>
<div class="img" style="background-image: url();"></div>
</div>
<div class="right">
<div class="lineone">John Smith</div>
<div class="linetwo">Daily Essentials</div>
</div>
</div>
<div class="boxes">
<div class="left">
<div class="box box1"></div>
</div>
<div class="right">
<div class="box box2"></div>
<div class="box box3"></div>
</div>
</div>
<a class="cbutton whiteonblack">VIEW LIST<!--SEE <span class="owner">JOHN'S</span>--></a>
</div>
<?php } ?>
</div>
I am trying to wrap the following div with an anchor tag so it links:
<div class="boxes"> </div>
Using jQuery I am trying to wrap this using jQuery that is part of a loop:
for(var i = 0; i < listLength; i++){
for(var y = 0; y < result.history[i].length; y++){
var history = document.getElementById('history' + i);
history.querySelector('.boxes').wrap('');
}
}
This is not resulting in an anchor tag showing up at all on the DOM. What am I doing wrong and how do I fix it?
Edit: I clarified which div
Edit 2: To clarify, each of the links are actually going to be dynamically generated. I am just using google.com as an example. So effecting all of a specific class wont work.
querySelector returns a NodeList object, wrap() is a jquery function, they won't work together, try this :
for(var i = 0; i < listLength; i++){
for(var y = 0; y < result.history[i].length; y++){
$('#history' + i).find('.boxes').first().wrap('');
}
}
You can do this in a single line by selecting the .list .boxes elements:
$('.lists .boxes').wrap('')
Example fiddle
Note that this will only work if you are using HTML5, otherwise it would be invalid to have a block level element (a div) inside an inline element (the a).

Categories

Resources