Getting the index of the current element and change his styles - javascript

I have a function whose destination is to work onClick event.
So, we have for example 4 Span elements and 4 Div elements.
The Spans are Tabs-buttons which I would like to "open" those Divs.
The 1st Span onClick would (open) change the style.display of the 1st Div in "block", from "none", and so on for the next Spans.
This piece of code works very well, but it changes only the design of elements.
function activateSup(s) {
var workTable = s.parentNode.parentNode.parentNode.parentNode.parentNode;
var spans = workTable.getElementsByTagName("span");
var supDivs = workTable.getElementsByClassName("supDiv");
for (var i = 0; i < spans.length; i++) {
spans[i].style.backgroundColor = "";
spans[i].style.border = "";
}
s.style.backgroundColor = "#5eac58";
s.style.border = "2px solid #336633";
}
I've tried to add the code below into my function to achieve what I want, but It does not work.
var getIndex = function(s) {
for (var index = 0; s != s.parentNode.childNodes[index]; index++);
return index;
}
for (var d = 0; d < supDivs.length; d++) {
if (getIndex == d) {
supDivs[d].style.display = "block";
}
else {
supDivs[d].style.display = "none";
}
}

I'm not exactly sure what you're trying to do, but one thing I noticed is this:
var getIndex = function(s) { /* .... */ }
for (var d = 0; d < supDivs.length; d++) {
if (getIndex == d) {
supDivs[d].style.display = "block";
}
else { /* ... */ }
}
This code is comparing getIndex to d, which means it's comparing an integer (d) to the function getIndex, instead of the result of the function call getIndex(spans[d]) (which is an integer, like d).
But what I think you're really trying to do, is getting the index of the clicked <span> so you can show the <div> with the matching index (and hide the rest). To achieve this, the code could be changed like so:
function activateSup(s) {
var workTable = s.parentNode.parentNode.parentNode.parentNode.parentNode;
var spans = workTable.getElementsByTagName("span");
var supDivs = workTable.getElementsByClassName("supDiv");
var index;
for (var i = 0; i < spans.length; i++) {
spans[i].style.backgroundColor = "";
spans[i].style.border = "";
if (s == spans[i])
index = i;
}
s.style.backgroundColor = "#5eac58";
s.style.border = "2px solid #336633";
for (var d = 0; d < supDivs.length; d++) {
if (index == d) {
supDivs[d].style.display = "block";
} else {
supDivs[d].style.display = "none";
}
}
}
Instead of the function getIndex, this just saves the correct index inside the first for loop.
There are many more improvements that could be made to this code, like rewriting it so you don't need that ugly s.parentNode.parentNode.parentNode.parentNode.parentNode and working with CSS classes instead of manually setting the style. But I'll leave that to the reader.

Related

Add "No results found" message on div search

I'm making an audio player, and I have a list of divs acting as my playlist... I'm using JS to make the list, and I'm using this script to search through them:
/*Search Songs*/
function searchSongs(){
let input = _('#songSearch').value.toLowerCase();
let items = _all('.item');
let dividers = _all(".divider");
for (let i = 0; i < items.length; i++) {
if (!items[i].innerHTML.toLowerCase().includes(input)) {
items[i].style.display = "none";
}
else {
items[i].style.display = "";
}
}
// add noresults message at end if all list divs are hidden
if (!items.innerHTML.toLowerCase().includes(input)) {
_('.noResults').innerHTML = `<p>No results found for "${input}"`
}
}
I have a paragraph element at the end of my list (with nothing in it) and I want to show the message (<p>No results found for "${input}") is there some js I can use to accomplish this? The script above is working for the searching, but not working for the message.
Finished result:
/*Search Songs*/
function searchSongs(){
let input = _('#songSearch').value.toLowerCase();
let items = _all('.item');
let dividers = _all(".divider");
let counter = 0;
for (let i = 0; i < items.length; i++) {
if (!items[i].innerHTML.toLowerCase().includes(input)) {
items[i].style.display = "none";
counter++;
}
else {
items[i].style.display = "";
}
}
// keeping the result 22 letters long (for asthetic purposes)
let maxLen = 22;
if (input.length > maxLen) {
input = input.substring(0, maxLen - 3) + "...";
}
if (counter >= items.length) {
_('#noResults').innerHTML = `No results found for "${input}"` //add no results message if all items are hidden...
} else {
_('#noResults').innerHTML = `` //else hide the message by removing text.
}
}
Thanks, #Asif !!
I've made a little modification in your function. I hope this will solve your issue.
/*Search Songs*/
function searchSongs(){
let input = _('#songSearch').value.toLowerCase();
let items = _all('.item');
let dividers = _all(".divider");
let counter = 0;
for (let i = 0; i < items.length; i++) {
if (!items[i].innerHTML.toLowerCase().includes(input)) {
items[i].style.display = "none";
}
else {
items[i].style.display = "";
counter++;
}
}
// add noresults message at end if all list divs are hidden
if (counter > 0) {
_('.noResults').innerHTML = `<p>No results found for "${input}"`
}
}

innerHtml and for loop

i want to write a short code i have multi contenteditable divs and i use a function to put the value of the div to a textarea please check with me
var myContentArr = ["myContent1", "myContent2", "myContent3", "myContent4", "myContent5", "myContent6"];
var hiddenArr = ["hidden1", "hidden2", "hidden3", "hidden4", "hidden5", "hidden6"];
function myFunction(){
for (var i = 0; i < hiddenArr.length; i++) {
document.getElementById(hiddenArr[i]).value =
for (var i = 0; i < myContentArr.length; i++) {
document.getElementById(myContentArr[i]).innerHTML
}
}
return true;
}

Div not showing when onClick Function runs

I wanted to make a specific form show and the other forms disappear when I click on one of four dropdown buttons. When I tested the code, no from is showing when I clicked on a button.
Here is my javascript code:
function showClass(className)
{
var allItems = document.getElementsByClassName('change-form');
for (var i = 0; i < allItems.length; i++)
{
allItems[i].style.display = "none";
}
var formItems = document.getElementsByClassName(className);
for (var i = 0; i < formItems.length; i++)
{
formItems[i].style.display = "block";
}
}
It shows the form if I remove the top for loop.
Edit: Sorry guys I made a typo
Your code is going in and hiding all the items and then showing them right away. What you want to do is split the hide and show into different functions to trigger them at different times.
function showClass(className)
{
var formItems = document.getElementsByClassName(className);
for (var i = 0; i < formItems.length; i++)
{
formItems[i].style.display = "block";
}
}
function hideClass(className){
var allItems = document.getElementsByClassName(className);
for (var i = 0; i < allItems.length; i++)
{
allItems[i].style.display = "none";
}
}
If you want to be able to swap them with one function you could use this:
function swapHide(className){
var firstItem = document.getElementsByClassName(className)[0];
var isDisplayed = firstItem.style.display == "block"
if(isDisplayed){
hideClass(className);
}else{
showClass(className)
}
}

Is only able to use the last element of the antZipCodes array when using the pestDisplay function

I wrote some JS that involves targeting the DOM, specifically a text input form. It only changes the display for the last element of the array when the user types in 95827. If the user types in 95828 or 95604, the display isn't filtered properly.
Here's a link to the full code.
I was told it may have to do with the removeDisplay function and how it's iterating through display (divs), but still can't manage to fix it.
Still new to DOM Manipulation.
var display = document.querySelectorAll(".display");
var zipCodeSearch = document.querySelector("#site-search");
var ants = document.querySelector("#ants");
const antZipCodes = [95828, 95604, 95827];
zipCodeSearch.addEventListener('change', function(e) {
// for(var i = 0; i < antZipCode.length; i++) {
// if(antZipCode[i] === Number(e.target.value)) {
// removeDisplay(displayNone);
// addDisplay(ants);
// }
// }
pestDisplay(antZipCodes, ants, display, e);
});
function removeDisplay(items) {
for(var i = 0; i < items.length; i++) {
items[i].style.display = "none";
}
}
function addDisplay(item) {
item.style.display = "block";
}
function displayAll(items) {
for(var i = 0; i < items.length; i++) {
items[i].style.display = "block";
}
}
function pestDisplay(arr, id, display, e) {
for(var i = 0; i < arr.length; i++) {
if(arr[i] === Number(e.target.value)) {
removeDisplay(display);
addDisplay(id);
} else {
displayAll(display);
}
}
}

Number of checked checkboxes

How to rewrite this code from jQuery to vanilla JavaScript? I need to see how many checkboxes are checked. The problem is I do not know how to remove unchecked checkboxes from the total score.
$(function () {
var countChecked = function () {
var n = $("input:checked").length;
$(".output").text(n);
};
countChecked();
$("input[type=checkbox]").on("click", countChecked);
});
What should I do next?
var box = document.querySelectorAll('form input');
var par = document.querySelector('.output');
var great = 0;
for (var i = 0; i < box.length; i++) {
box[i].addEventListener('click', countIt);
function countIt() {
for (var i = 0; i < box.length; i++) {
if ( box[i].checked ) {
great++
par.innerHTML = great;
return
}
}
}
}
You need to reset the great variable each time you count (for example by moving it inside the countIt function).
var box = document.querySelectorAll('form input');
var par = document.querySelector('.output');
function countIt() {
var great = 0;
for (var i = 0; i < box.length; i++) {
if (box[i].checked) {
great++;
}
}
par.innerHTML = great;
}
for (var i = 0; i < box.length; i++) {
box[i].addEventListener('click', countIt);
}
You can also move the countIt function definition out of the loop and the same with innerHTML setting.

Categories