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

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>

Related

How to achieve level 3 div with javascript and apply styling

Hello I would like to reach a level 3 div and change the style of this div
in my example I would therefore like to be able to apply disply:none on style color red
to make the word Warning invisible
<div id="Zone">
<div class="MR-Widget ">
<div class="Title"> </div>
<div class="Errors" style="display: none"></div>
<div class="Content">
<div class="search"> </div>
<div class="resultat" style="width: 120px;"></div>
<div class="MR" id="Lock" style="display: none;"> </div>
<div style="color: red"> Warning </div>
</div>
</div>
</div>
To select 3rd level div:
document.querySelector('#Zone > div > div > div')
Now the problem is you have 4 div at 3rd level. So needed to select all and check style color. That gives:
const warningNone = () => {
Array.from(document.querySelectorAll('#Zone > div > div > div')).forEach(el => {
if (el) {
if (el.style.color === 'red') {
el.style.display = 'none';
}
}
})
}
window.addEventListener('load', warningNone);
<div id="Zone">
<div class="MR-Widget ">
<div class="Title"> </div>
<div class="Errors" style="display: none"></div>
<div class="Content">
<div class="search"> </div>
<div class="resultat" style="width: 120px;"></div>
<div class="MR" id="Lock" style="display: none;"> </div>
<div style="color: red"> Warning </div>
</div>
</div>
</div>
I modified the snippet to check the >div>div>div existence
By the way, I put the function to be fired when document loaded, otherwise your red will not apply
3...
try to split the query line in 2:
const warningNone = () => {
const els = document.querySelectorAll('#Zone > div > div > div');
els.forEach(el => {
if (el.style.color === 'red') {
el.style.display = 'none';
}
})
}
window.addEventListener('load', warningNone);
now in dev tools check which line fire the error

Trying to loop through click event and make the div´s with it´s texts visible. Does somebody what the mistake is?

Here is the html container:
<div class="arrow-1">
<div class="text-event">
<p class="text-style-11">Text 1
</p>
</div>
<div class="arrow">
<div class="diamond">
</div>
</div>
</div>
<div class="arrow-2">
<div class="text-event">
<p class="text-style-11">Text 2
</p>
</div>
<div class="arrow">
<div class="diamond">
</div>
</div>
</div>
<div class="arrow-3">
<div class="text-event">
<p class="text-style-11">Text 3
</p>
</div>
<div class="arrow">
<div class="diamond">
</div>
</div>
</div>
<div class="arrow-4">
<div class="text-event">
<p class="text-style-11"> Text 4
</p>
</div>
<div class="arrow">
<div class="diamond">
</div>
</div>
</div>
<div class="arrow-5">
<div class="text-event">
<p class="text-style-11"> Text 5
</p>
</div>
<div class="arrow">
<div class="diamond">
</div>
</div>
</div>
</div>
The paragraphs should be "visible" when text-event class clicked. Text style class is "hidden" by default. I did that already with other div boxes and it worked. Is there a 'p' declaration missing in the loop function? There is not even a console feedback when I pass the textEvent variable to the console.
const textEvent = document.querySelectorAll('.text-event');
for (var j = 0; j < textEvent.length; j++) (function (j) {
textEvent[j].addEventListener('click', onclick);
textEvent[j].onclick = function (ctrls) {
ctrls.forEach(ctrl => {
/* ctrl.getElementsByClassName('p')[0].innerHTML; */
ctrl.document.getElementsByClassName('text-style-11').style.visibility = "visible";
})
}
})(j);
I could not understand very well your code but this is how I would do it.
First get all the element with class "text-event"
loop over that array and add an event listener to each of them.
When you click in one of them select the element with the class of text-style-11
To something to that element.
const textContainers = document.querySelectorAll(".text-event");
textContainers.forEach((element) => {
element.addEventListener("click", () => {
const textElement = element.querySelector(".text-style-11");
textElement.style.visibility = "hidden";
});
});
Instead of adding styles directly, I recommend you to create a class and use classList toggle to add and remove that class.
textContainers.forEach((element) => {
element.addEventListener("click", () => {
const textElement = element.querySelector(".text-style-11");
textElement.classList.toggle("show");
});
});
I have tested this code it should work fine:
const textEvent = document.querySelectorAll('.text-event');
for (var j = 0; j < textEvent.length; j++) {
textEvent[j].addEventListener('click', (el) => {
const clickedElement = el.currentTarget;
const innerParagraph = clickedElement.querySelector('.text-style-11');
innerParagraph.style.visibility = 'visible';
});
}
You've already got a valid answer.. by the way here's the live snippet using the proper strategy to add an event listener to all your .text-event elements that will hide the inner paragraph embedded in the clicked box:
document.querySelectorAll('.text-event').forEach((el) => {
el.addEventListener('click', (event) => {
const clickedElement = event.currentTarget;
const innerParagraph = clickedElement.querySelector('.text-style-11');
innerParagraph.style.visibility = 'visible';
});
});
.text-event {
border: dotted gray 3px;
margin-bottom: 2px;
cursor: pointer;
}
.text-style-11{
visibility: hidden;
}
<div class="arrow-1">
<div class="text-event">
<p class="text-style-11">Alle Personen, die nicht sozialversicherungspflichtig beschäftigt sind (Beamte, Selbstständige, etc.)
</p>
</div>
<div class="arrow">
<div class="diamond">
</div>
</div>
</div>
<div class="arrow-2">
<div class="text-event">
<p class="text-style-11">Einmalige Wartezeit 1 Monate
</p>
</div>
<div class="arrow">
<div class="diamond">
</div>
</div>
</div>
<div class="arrow-3">
<div class="text-event">
<p class="text-style-11">Keine Karenzzeit
</p>
</div>
<div class="arrow">
<div class="diamond">
</div>
</div>
</div>
<div class="arrow-4">
<div class="text-event">
<p class="text-style-11">Versichert sind nur Erstdiagnosen während der Versicherungslaufzeit (Herzinfarkt, Schlaganfall, Krebs, Blindheit oder Taubheit)
</p>
</div>
<div class="arrow">
<div class="diamond">
</div>
</div>
</div>
<div class="arrow-5">
<div class="text-event">
<p class="text-style-11">Übernahme des noch ausstehenden Restsaldos von bis zu 135.000 €
</p>
</div>
<div class="arrow">
<div class="diamond">
</div>
</div>
</div>

How to do an accordion with HTML and JS

I want an accordion to drop down when a user clicks on the greater than sign.
<div class="row">
<div class="col-2">
<p>DEP-08B827E791<button class="accordion"><i class="fa-solid fa-greater-than fa ps-1"></i></button></p>
</div>
<div class="col-3">
<P>Omodeko Divine</P>
</div>
<div class="col-2">
<p>EE</p>
</div>
<div class="col-3">
<p>[ETHIOPE EAST]</p>
<P>DELSU HEALTH CENTER ABRAKA</P>
</div>
<div class="col-2">
<button class="btn btn-primary">GENERATE ID</button>
</div>
<div class="panel" onclick="document.getElementByclassname(panel).style.display='none'">
<p>No, but there must be adequate evidence that would help to support your claim.</p>
</div>
</div>
This is the javascript
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
/* Toggle between adding and removing the "active" class,
to highlight the button that controls the panel */
this.classList.toggle("activee");
/* Toggle between hiding and showing the active panel */
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}});}
On click of the greater than sign, the .panel is supposed to dropdown.
Add onclick event to the greater than icon
Next add id to .panel div
Next in script write the logic for hide and show, please refer to below code snippet
function showDropDown(){
const targetDiv = document.getElementById("panelDivId");
if (targetDiv.style.display !== "none") {
targetDiv.style.display = "none";
} else {
targetDiv.style.display = "block";
}
}
<div class="row">
<div class="col-2">
<p>DEP-08B827E791<button class="accordion"><i class="fa-solid fa-greater-than fa ps-1" onclick="showDropDown()">greaterThanIcon</i></button></p>
</div>
<div class="col-3">
<P>Omodeko Divine</P>
</div>
<div class="col-2">
<p>EE</p>
</div>
<div class="col-3">
<p>[ETHIOPE EAST]</p>
<P>DELSU HEALTH CENTER ABRAKA</P>
</div>
<div class="col-2">
<button class="btn btn-primary">GENERATE ID</button>
</div>
<div class="panel" id="panelDivId" onclick="document.getElementByclassname(panel).style.display='none'">
<p>No, but there must be adequate evidence that would help to support your claim.</p>
</div>
</div>

jQuery callback function to check number of child elements on element click

I have a set of "div" whose children count I want to check when a user fadeOut images under that div block, if the all childrens have be closed out i want to call the function: kind of like:
edited: the current code always alerts YES whenever the div is faded,
how do i destroy the DOM entirely without having to use :visible
filter. getting rid of the entire card class after fading out
considering the HTML:
<div class='scrolling-wrapper'>
<div class='card'>
<div class='panel panel-primary'>
<div class='panel-body'>
<div class='img-wrap'>
<span class='close-x'> × </span>
<img width='100%' id='3' class='' src='resizer/resizer.php?file=profiles/images/default_cover.jpg&width=700&height=400&action=resize&watermark=bridgoo&watermark_pos=tl&color=255,255,255&quality=100' />
</div>
<div class='title h5'>
<span class='user-popover'>
<a href='/groupstomason/'><b>tomason</b></a>
</span>
<br/>
<small class='small-text'>for max tomason
</small>
</div>
</div>
<div class='panel-heading'>
<button class='btn btn-primary'> <span class='fa fa-plus-circle fa-fw'> </span>Join </button>
</div>
</div>
<div class='card-group-holder' style='width:250px; background-color:inherit;'>
</div>
<div class="card"> another card</div>
<div class="card"> another card</div>
<div class="card"> another card</div>
</div>
and the jquery below:
$('.img-wrap .close-x').on('click', function() {
var card = $(this).closest('.card');
card.fadeOut('slow', function() {
var cardWrapper = $(this).closest('.card').closest('scrolling-wrapper');
var cardcount = cardWrapper.children('.card');
if (cardcount.length < 1) alert('yes');
});
});
when the <span class = 'close-x'> × </span> is clicked the
entire <div class='card'> is fadedOut, then on fadeout, if no more
cards exist or the last cards have been faded, then alert('yes');
Assuming that multiple .card elements are nested in the same parent, you can check if all the siblings have faded out.
In your original markup, you have an unclosed </div>, which causes the .card elements not to be siblings of each other, I believe this is a typo on your part, since it is the most parsimonious explanation.
Since .fadeOut() hides the element, you can simply check if the filtered set of :visible returns a length of 1 or more:
$('.img-wrap .close-x').on('click', function() {
var card = $(this).closest('.card');
card.fadeOut('slow', function() {
var cardWrapper = $(this).closest('.scrolling-wrapper');
var cardcount = cardWrapper.children('.card');
if (cardcount.filter(':visible').length < 1) {
console.log('All cards have faded out');
}
});
});
Here is a proof-of-concept example:
$(function() {
$('.close').on('click', function() {
var card = $(this).closest('.card');
card.fadeOut('slow', function() {
// Get wrapping ancestor
var cardWrapper = $(this).closest('.scrolling-wrapper');
var cardcount = cardWrapper.children('.card');
// Filter out those that are not visible, and check for remaining visible cards
if (cardcount.filter(':visible').length < 1) {
console.log('All cards have faded out');
}
});
});
});
/* Just styles for a dummy call-to-action element in .card */
span.close {
cursor: pointer;
color: steelblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scrolling-wrapper">
<div class="card">Card 1. <span class="close">Click to hide me.</span></div>
<div class="card">Card 2. <span class="close">Click to hide me.</span></div>
<div class="card">Card 3. <span class="close">Click to hide me.</span></div>
<div class="card">Card 4. <span class="close">Click to hide me.</span></div>
<div class="card">Card 5. <span class="close">Click to hide me.</span></div>
</div>
In your callback you may simply test if at least a card is visible:
if ($(this).closest('.card').siblings('.card:visible').length < 1) alert('yes');
$('.img-wrap .close-x').on('click', function () {
var card = $(this).closest('.card');
card.fadeOut('slow', function () {
if ($(this).closest('.card').siblings('.card:visible').length < 1) console.log('yes');
});
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class='scrolling-wrapper'>
<div class='card'>
<div class='panel panel-primary'>
<div class='panel-body'>
<div class='img-wrap'>
<span class='close-x'> × </span>
<img width='100%' id='3' class=''
src='resizer/resizer.php?file=profiles/images/default_cover.jpg&width=700&height=400&action=resize&watermark=bridgoo&watermark_pos=tl&color=255,255,255&quality=100'/>
</div>
<div class='title h5'>
<span class='user-popover'>
<a href='/groupstomason/'><b>tomason</b></a>
</span>
<br/>
<small class='small-text'>for max tomason
</small>
</div>
</div>
<div class='panel-heading'>
<button class='btn btn-primary'><span class='fa fa-plus-circle fa-fw'> </span>Join</button>
</div>
</div>
<div class='card-group-holder' style='width:250px; background-color:inherit;'>
</div>
</div>
<div class='card'>
<div class='panel panel-primary'>
<div class='panel-body'>
<div class='img-wrap'>
<span class='close-x'> × </span>
<img width='100%' id='3' class=''
src='resizer/resizer.php?file=profiles/images/default_cover.jpg&width=700&height=400&action=resize&watermark=bridgoo&watermark_pos=tl&color=255,255,255&quality=100'/>
</div>
<div class='title h5'>
<span class='user-popover'>
<a href='/groupstomason/'><b>tomason</b></a>
</span>
<br/>
<small class='small-text'>for max tomason
</small>
</div>
</div>
<div class='panel-heading'>
<button class='btn btn-primary'><span class='fa fa-plus-circle fa-fw'> </span>Join</button>
</div>
</div>
<div class='card-group-holder' style='width:250px; background-color:inherit;'>
</div>
</div>
</div>

Sorting of divs in Jquery

My code have divs of movies which are used to display movie with poster, now i want jquery to sort divs for me on basis of title,
<!-- Movie -->
<div class="movie" title="Reservoir Dogs">
<div class="movie-image">
<span class="play"><span class="name">Reservoir Dogs |
Reservoir Dogs</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMTQxMTAwMDQ3Nl5BMl5BanBnXkFtZTcwODMwNTgzMQ##._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Saw">
<div class="movie-image">
<span class="play"><span class="name">Saw |
Saw</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMjAyNTcxNzYwMV5BMl5BanBnXkFtZTgwMzQzNzM5MjE#._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Scarface">
<div class="movie-image">
<span class="play"><span class="name">Scarface |
Scarface</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMjAzOTM4MzEwNl5BMl5BanBnXkFtZTgwMzU1OTc1MDE#._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Signs">
<div class="movie-image">
<span class="play"><span class="name">Signs |
Signs</span></span><img src="http://ia.media-imdb.com/images/M/MV5BNDUwMDUyMDAyNF5BMl5BanBnXkFtZTYwMDQ3NzM3._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in3">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
<!-- Movie -->
<div class="movie" title="Stir of Echoes">
<div class="movie-image">
<span class="play"><span class="name">Stir of Echoes |
Stir of Echoes</span></span><img src="http://ia.media-imdb.com/images/M/MV5BMTU0OTAyMDQzNV5BMl5BanBnXkFtZTcwNTg1NjYyMQ##._V1_SX300.jpg" alt="movie">
</div>
<div class="rating">
<p>RATING</p>
<div class="stars">
<div class="stars-in4">
</div>
</div>
<span class="comments"></span>
</div>
</div>
<!-- end Movie -->
Now here is my current code
$(document).ready(function () {
var desc = false;
document.getElementById("sort").onclick = function () {
sortUnorderedList("movie", desc);
desc = !desc;
return false;
}
});
function sortUnorderedList(ul, sortDescending) {
if (typeof ul == "string")
var lis = document.getElementsByClassName("movie");
var vals = [];
for (var i = 0, l = lis.length; i < l; i++)
vals.push(lis[i]);
debugger;
vals.sort(function (a, b) { return a.title - b.title });
//vals[].title.sort();
if (sortDescending)
vals.reverse();
for (var i = 0, l = lis.length; i < l; i++)
lis[i].innerHTML = vals[i].innerHTML;
}
above code is not giving desired result
can u suggest better way to do it
You can significantly simplify your code if you use more jQuery, anyway you are using it. Entire code in this case will be:
$(document).ready(function () {
var desc = false;
$("#sort").click(function () {
sortUnorderedList("movie", desc);
desc = !desc;
});
});
function sortUnorderedList(ul, sortDescending) {
$('.' + ul).sort(function(a, b) {
return sortDescending ? a.title.localeCompare(b.title) : b.title.localeCompare(a.title);
}).appendTo('body');
}
Just note that instead of appendTo('body'), you should append to appropriate container that holds .movie elements. I'm appending to body because this is a container for movie divs in my demo.
Demo: http://jsfiddle.net/212oc0kw/

Categories

Resources