querySelectorAll Need to select all divs - javascript

I'm in need of getting a working search bar for these cards (only one included in the code to save space), the js I've been using worked fine for now, but recently I had to add a new div (with class sce-all) which made it search only some of the items or actually too many from different divs and makes the other info into display:none when I search for anything from div (with class sce-e). When I try to search anything right now, it also searches from div (with class sce-e), I only need it to search from div (with class sce-tt) or it could be both, but it gives it the display:none tag currently. I tried changing up the ('.card div:nth-child(2)') in the js which is the cause of the problem it seems.
Thanks for any help
const searchEl = document.querySelector('.searchbox');
const x = document.querySelectorAll('.card div:nth-child(2)');
function search(e) {
x.forEach((item, index) => {
if (!item.innerHTML.toLowerCase().includes(e.target.value)) {
item.parentElement.style.display = 'none';
} else {
item.parentElement.style.display = 'block';
}
})
}
searchEl.addEventListener("keyup", search);
<form class='searchbox'>
<input class="searchbar" type="text" placeholder="Search.." name="search">
</form>
<div class="main-container">
<div class="cards-vid">
<div class="video anim card">
<div class="video-wrapper">
<div class="video-wrapper-inside">
<a href="vid.mp4"><video preload="metadata">
<source src="vid.mp4#t=139" type="video/mp4">
</video></a>
</div>
</div>
<div class="sce-all">
<div class="sce-e">Link Title<span class="length-t">0ms</span></div>
<div class="sce-tt">Title</div>
</div>
<div class="tags-and-info">
<div class="tags"><a><span class="category-tag">Main</span></a><span class="language-edit">ENG</span></div>
<hr class="sce-hr">
<div class="sce-inf">Info<span class="seperate video-seperate"></span>0h 46m<span class="seperate video-seperate"></span>2023</div>
</div>
</div>
</div>
</div>

Change x to just select the .sce-tt divs. Then when it decides whether to hide or show the parent, use closest('.card') to find the containing card, rather than specifying .parent.
const searchEl = document.querySelector('.searchbox');
const x = document.querySelectorAll('.card .sce-tt');
function search(e) {
x.forEach((item, index) => {
if (!item.innerHTML.toLowerCase().includes(e.target.value)) {
item.closest(".card").style.display = 'none';
} else {
item.closest(".card").style.display = 'block';
}
})
}
searchEl.addEventListener("keyup", search);
<form class='searchbox'>
<input class="searchbar" type="text" placeholder="Search.." name="search">
</form>
<div class="main-container">
<div class="cards-vid">
<div class="video anim card">
<div class="video-wrapper">
<div class="video-wrapper-inside">
<a href="vid.mp4"><video preload="metadata">
<source src="vid.mp4#t=139" type="video/mp4">
</video></a>
</div>
</div>
<div class="sce-all">
<div class="sce-e">Link Title<span class="length-t">0ms</span></div>
<div class="sce-tt">Title</div>
</div>
<div class="tags-and-info">
<div class="tags"><a><span class="category-tag">Main</span></a><span class="language-edit">ENG</span></div>
<hr class="sce-hr">
<div class="sce-inf">Info<span class="seperate video-seperate"></span>0h 46m<span class="seperate video-seperate"></span>2023</div>
</div>
</div>
</div>
</div>

Related

How do I edit the text of a button when the content is displayed/actively showing?

Using this example:
$('[data-switch]').on('click', function(e)
{
var
$page = $('#page-2')
, blockToShow = e.currentTarget.getAttribute('data-switch')
;
// Hide all children.
$page.children().hide();
// And show the requested component.
$page.children(blockToShow).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button data-switch="#about_me">Click to read about me</button>
<button data-switch="#education">Click to show my education</button>
<button data-switch="#about_name_bravitus">Click to read about the name Bravitus</button>
<div id="page-2">
<div id="about_me" class="container">
<h1>This is about me section</h1>
<div>about me about me about me</div>
</div>
<!-- Hidden blocks that you show when requested. -->
<div id="education" class="container" style="display: none;">
<h1>This is about my education</h1>
<div>education education education</div>
</div>
<div id="about_name_bravitus" class="container" style="display: none;">
<h1>This is about the name bravitus</h1>
<div>bravitus bravitus bravitus</div>
</div>
</div>
How would one go about changing the font color and weight of the button text when the content is being displayed (not based on when the button is clicked)?
I have tried to find posts with a similar request, but I am greatly struggling. Any direction would be appreciated.
There is many ways to do that, like this one :
const
btns_Switch = document.querySelectorAll('[data-switch]')
, page2_parent = document.querySelector('#page-2')
;
btns_Switch.forEach( btn =>
{
btn.onclick = e =>
{
page2_parent.dataset.switch = btn.dataset.switch;
setButtonActive();
}
})
setButtonActive(); // init on page load...
function setButtonActive()
{
let activBtn = page2_parent.dataset.switch;
btns_Switch.forEach( btn =>
btn.classList.toggle('active', activBtn === btn.dataset.switch ))
}
#page-2[data-switch="about_me"] > div:not(#about_me) ,
#page-2[data-switch="education"] > div:not(#education) ,
#page-2[data-switch="about_name_bravitus"] > div:not(#about_name_bravitus)
{
display : none;
}
button.active
{
background : yellow;
font-weight : bold;
}
<button data-switch="about_me">Click to read about me</button>
<button data-switch="education">Click to show my education</button>
<button data-switch="about_name_bravitus">Click to read about the name Bravitus</button>
<div id="page-2" data-switch="education" > <!-- set initial ID value -->
<div id="about_me" class="container">
<h1>This is about me section</h1>
<div>about me about me about me</div>
</div>
<div id="education" class="container" >
<h1>This is about my education</h1>
<div>education education education</div>
</div>
<div id="about_name_bravitus" class="container" >
<h1>This is about the name bravitus</h1>
<div>bravitus bravitus bravitus</div>
</div>
</div>

how to display the right movie informations in an overlay?

I'm looking for solutions to display the right movie information in my overlay.
I have a "popup window" that appears when i click on a movie and it is supposed to display movie's informations in it but when I click on a movie, no matter which one it is, it only displays the last movie informations, what Should I do to fix it ?
const movieIntegration =() => {
allMovies.map(movie=> {
movieGallery.innerHTML += `<div class="imgContainer">
<img src="${movie.img}" alt="${movie.name}">
<div class="titleContainer">
<div class="movieTitle"> ${movie.name} </div>
<div class="seemore"> See more </div>
</div>
</div>`
const seemore = document.querySelectorAll(".seemore")
seemore.forEach(elm => {
elm.addEventListener("click",() => {
pageContainer.innerHTML += `<div class="popupContainer">
<div class="popup">
${movie.name}
<div id="likeButton">
<img src="img/like.png">
</div>
<div id="editButton">
<img src="img/edit.png">
</div>
<a href="submit.html">
<div id="addingButton">
<img src="img/add.png">
</div>
</a>
</div>
</div>`
console.log(true)
}, true)
})
})
}
the problem is that you are getting all the .seemore element for each movie and you are editing the content of ALL elements for each movie, so the last movie will overwrite the content for all the previous.
A solution could be something like this:
const movieIntegration = () => {
allMovies.map((movie) => {
movieGallery.innerHTML += `<div class="imgContainer">
<img src="${movie.img}" alt="${movie.name}">
<div class="titleContainer">
<div class="movieTitle"> ${movie.name} </div>
<div class="seemore"> See more </div>
</div>
</div>`
})
const seemore = document.querySelectorAll('.seemore')
seemore.forEach((elm, i) => {
elm.addEventListener(
'click',
() => {
pageContainer.innerHTML += `<div class="popupContainer">
<div class="popup">
${allMovies[i].name}
<div id="likeButton">
<img src="img/like.png">
</div>
<div id="editButton">
<img src="img/edit.png">
</div>
<a href="submit.html">
<div id="addingButton">
<img src="img/add.png">
</div>
</a>
</div>
</div>`
},
true
)
})
}
In this way you are mapping the .seemore elements AFTER you finish the map of allMovies and, for each .seemore element you get the associated movie and write his name inside.

How to check if all the input values are equal to my data?

I have 32 items in my array, all of them have these properties: id, word, image. User has to guess what's in all the images and write their guess in inputs (so 32 inputs in total). I need to check if the input equals my arrays property "word" and then when clicked a button (type submit, all my pic's and inputs are in a form) display some text for example "Oops! Guess again" if wrong and "Yay! You got it correctly" if right. The text should appear below every input. I displayed all the pictures and inputs with a forEach, and i'm using bulma framework for this page:
const wordBox = info.forEach((words) => {
mainColumns.innerHTML += `
<div class="column is-one-quarter">
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src=${words.image} alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="media">
<div class="media-content">
<input class="input" id="text" type="text" placeholder="Įvesk žodį">
</div>
</div>
<div class="content">
Content
</div>
</div>
</div>
</div>`;
});
Any ideas?
This is how it should look like (the result should appear in content place)
Something like this
I use change instead of a button click
const info = [
{word:"flower",image:"flower.gif"},
{word:"boat",image:"boat.gif"}
];
const mainColumns = document.getElementById("mainColumns");
mainColumns.innerHTML = info.map(({image,word}) =>
`<div class="column is-one-quarter">
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src=${image} alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="media">
<div class="media-content">
<input class="input" data-word="${word}" type="text" placeholder="Įvesk žodį">
<span class="correct hide">Yay</span>
<span class="wrong hide">NOO</span>
</div>
</div>
<div class="content">
Content
</div>
</div>
</div>
</div>`).join("");
mainColumns.addEventListener("change",function(e) {
const correct = [...mainColumns.querySelectorAll("[data-word]")].map(input => {
if (input.value) {
const correct = input.value === input.dataset.word;
parent = input.closest("div");
parent.querySelector(".correct").classList.toggle("hide",!correct)
parent.querySelector(".wrong").classList.toggle("hide",correct);
return correct ? 1 : 0;
}
else return 0;
}).reduce((a,b)=>a+b);
document.getElementById("correct").innerText = correct;
})
#mainColumns { display:flex; }
.hide { display: none; }
<div id="mainColumns"></div>
Correct: <span id="correct"></span>
What you can do is to filter the word array with word from the input value. Then check if the length is equal zero, No match, if the length is greater than one, then there is a match.
const status = wordBox.filter(item => item.word === inputWord)
I'd move towards keeping the objects and the HTML separate, binding the HTML to the object and vice versa. This means including a couple more properties to your array elements.
let info = [{
image: 'flower.png',
word: 'flower',
content: '',
guess: ''
}];
function bindWords() {
info.forEach((words) => {
mainColumns.innerHTML = `
<div class="column is-one-quarter">
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src=${words.image} alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="media">
<div class="media-content">
<input class="input" data-word="${words.word}" type="text" placeholder="Įvesk žodį" value="${words.guess}">
</div>
</div>
<div class="content">
${words.content}
</div>
</div>
</div>
</div>`;
});
}
bindWords();
check.addEventListener('click', () => {
info = Array.from(document.querySelectorAll('.card')).map(el => ({
image: el.querySelector('img').src,
word: el.querySelector('.input').dataset.word,
guess: el.querySelector('.input').value,
content: el.querySelector('.input').value === el.querySelector('.input').dataset.word ?
'Correct' : 'Incorrect'
}));
bindWords();
});
<div id="mainColumns"></div>
<button id="check">Check Answers</button>

how to make the button click executes code only one time

I want the button with the id #show-text-area execute the postButton(); function only once so it won't create a second elements whenever clicked (i want it to create it for only one time and won't work again until clicked another button).
Hope my question was clear enough.
HTML
<div id="post-creator" class="creator-container">
<div class="post-type">
<div class="text-post" id="post">
<button onclick="postButton();">Post</button>
</div>
<div class="media-post">Image & Video</div>
<div class="link-post">Link</div>
</div>
<div class="post-title">
<input type="text" class="title-text" name="post-title" placeholder="Title">
</div>
<div class="post-content">
</div>
<div class="post-footer">
<div class="spoiler">Spoiler</div>
<div class="nsfw">NSFW</div>
<button class="post">post</button>
</div>
</div>
Javascript
let postButton = function() {
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
}
You could disable the button after activation, this has the benefit of informing the user that further clicks won't do anything.
let postButton = function() {
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
document.getElementsByTagName("button")[0].disabled = true;
}
Otherwise you could simply have the function short-circuit if it has already been called.
// alreadyPosted is scoped outside of the function so it will retain its value
// across calls to postButton()
let alreadyPosted = false;
let postButton = function() {
// do nothing if this isn't the first call
if (alreadyPosted) { return; }
// mark the function as called
alreadyPosted = true;
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
document.getElementsByTagName("button")[0].disabled = true;
}
The following works.
let postButton = function(event) {
event.target.disabled = true;
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
};
document.getElementById('post').addEventListener('click', postButton);
<div id="post-creator" class="creator-container">
<div class="post-type">
<div class="text-post" id="post">
<button>Post</button>
</div>
<div class="media-post">Image & Video</div>
<div class="link-post">Link</div>
</div>
<div class="post-title">
<input type="text" class="title-text" name="post-title" placeholder="Title">
</div>
<div class="post-content">
</div>
<div class="post-footer">
<div class="spoiler">Spoiler</div>
<div class="nsfw">NSFW</div>
<button class="post">post</button>
</div>
</div>
You can also use hide show function on textarea if you do not want to create one.
let postButton = function() {
let d = document.getElementById('post_data').style.display;
if(d=='none'){
document.getElementById('post_data').style.display = 'block';
}
}
document.getElementById('post_data').style.display = 'none';
document.getElementById('post_btn').addEventListener('click', postButton);
<div id="post-creator" class="creator-container">
<div class="post-type">
<div class="text-post">
<button id="post_btn">Post</button>
</div>
<div class="media-post">Image & Video</div>
<div class="link-post">Link</div>
</div>
<div class="post-title">
<input type="text" class="title-text" name="post-title" placeholder="Title">
</div>
<div class="post-content">
<textarea class="post-data" id="post_data" placeholder="Text (optional)"></textarea>
</div>
<div class="post-footer">
<div class="spoiler">Spoiler</div>
<div class="nsfw">NSFW</div>
<button class="post">post</button>
</div>
</div>

Javascript function to rotate some div elements on page

I have some javascript function - shows me a popup with some texts. I try to rotate two "section" elements, but if I add to HTML one more section with class custom, the page shows only first element. Please, help me to add 1-2 more elements and to rotate it. The idea is to have 2 or more elements with class custom and to show it in random order, after last to stop. Thanks.
setInterval(function () {
$(".custom").stop().slideToggle('slow');
}, 2000);
$(".custom-close").click(function () {
$(".custom-social-proof").stop().slideToggle('slow');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="custom">
<div class="custom-notification">
<div class="custom-notification-container">
<div class="custom-notification-image-wrapper">
<img src="checkbox.png">
</div>
<div class="custom-notification-content-wrapper">
<p class="custom-notification-content">
Some Text
</p>
</div>
</div>
<div class="custom-close"></div>
</div>
</section>
Set section display none of page load instead of first section. Check below code of second section:
<section class="custom" style=" display:none">
<div class="custom-notification">
<div class="custom-notification-container">
<div class="custom-notification-image-wrapper">
<img src="checkbox.png">
</div>
<div class="custom-notification-content-wrapper">
<p class="custom-notification-content">
Mario<br>si kupi <b>2</b> matraka
<small>predi 1 chas</small>
</p>
</div>
</div>
<div class="custom-close"></div>
</div>
</section>
And you need to make modification in your jQuery code as below:
setInterval(function () {
var sectionShown = 0;
var sectionNotShown = 0;
$(".custom").each(function(i){
if ($(this).css("display") == "block") {
sectionShown = 1;
$(this).slideToggle('slow');
} else {
if (sectionShown == 1) {
$(this).slideToggle('slow');
sectionShown = 0;
sectionNotShown = 1;
}
}
});
if (sectionNotShown == 0) {
$(".custom:first").slideToggle('slow');
}
}, 2000);
Hope it helps you.

Categories