forEach displays only last item from the list - javascript

I would like to display some of my data for each item from my list. The problem is that the function is displaying only information about the last item.
Here's how the function looks:
drivers.forEach(addLink);
function addLink(driver, index) {
const nameList = document.getElementById('nameList');
const driverImg = document.getElementById('driverImg');
nameList.href = `?driver=${index}`;
nameList.textContent = driver.name;
driverImg.src = driver.image;
driverImg.height = "45";
list.appendChild(nameList);
list.appendChild(driverImg);
}
It was working when it was creating elements (const nameList = document.createElement('a'); , but I wanted to change that to getElementById
html looks like this:
<nav id="list">
<a id="nameList"></a>
<img id="driverImg">
</nav>

Your function is called addLink but it gets an existing element (with getElementById) and changes it. When you change it multiple times, you end up with the last set of changes you made to it.
If you want to create a link you need createElement.

Since you actually want to add Elements you need to create them like you did before, now you are just getting the same element that allready is on the document and changing it's values (overwrititing the changes from the previous iteration in every iteration)

Related

How do I initialize a whole div from LocalStorage in HTML without breaking it with "/"?

So, I am creating a "favorites page" using local storage to store the items that you click to add to favorites, the items are normal cards like this (just an example):
<div class="card__box">
<div class="heart-wrapper"></div>
<div onclick="link('index.html?BI=auditoria')">
<div class="card__icon"><img src="./assets/icons/auditoria.png"></div>
<div class="icon__text">
<span class="icon__header"><strong>Auditoria</strong></span>
</div>
</div>
</div>
I am saving them in local storage with outer.HTML
(how localStorage is saving them)
the thing is, when I try to show them in the HTML the LocalStorage give the value with some alterations like bars "/" and "\n". (like this):
"<div class="card_mini_box"> \n <div class="times-mini-wrapper"><a href="#" class="fas fa-times" id="auditoria" aria-hidden="true">\n <div onclick="link('index.html?BI=auditoria')">\n <div class="card_mini_icon"><img src="./assets/icons/auditoria.png">\n <div class="icon_mini_text">\n <span class="icon_mini_header">Auditoria\n \n \n "
As u can see all messed up.
I am saving them in localstorage like this:
let favorites = JSON.parse(localStorage.getItem('favorites')) || []
const source = favdiv.outerHTML;
favorites.push(source);
localStorage.setItem('favorites', JSON.stringify(favorites));
(favdiv is the whole div selected)
And I am trying to show them in HTML like this:
var output = document.getElementById("mini__cards");
var element = document.createElement("div");
element.textContent = localStorage.getItem('favorites');
output.appendChild(element);
please help me I tried a lot of different methods and none of them worked.
Already Tried saving with innerHTML and also tried to put them in html with innerHTML as well.
for this method to work, some details were missing when saving and showing the favorites.
When getting the div, use innerHTML, it gets the elements inside the selected div, so there is no risk of duplicating IDs.
Before saving, removing breaking lines.
When showing data, remember to use a loop to show all stored data.
Your code would look like this to save:
var favorites = JSON.parse(localStorage.getItem("favorites")) || [];
var favdiv =
document.getElementById("divs").innerHTML.replace(/(\r\n|\n|\r|\s\s)/gm, "");
favorites.push(favdiv);
localStorage.setItem("favorites", JSON.stringify(favorites));
Using replace, I remove line breaks, with \n and \r.
And to view the saved divs, I use a forEach to go through the entire array, create a template and show its content as the last element:
var favorites = JSON.parse(localStorage.getItem("favorites"));
var output = document.getElementById("mini__cards");
favorites.forEach((favorite) => {
let tempElement = document.createElement("template");
tempElement.innerHTML = favorite.trim();
output.append(tempElement.content);
});
More detailed explanation about above code: https://stackoverflow.com/a/35385518/20815693
This is the result for your case, using jquery this code can be reduced and easier to handle DOM. I hope I have helped you.

Getting the index of an array item in vanilla javascript when new items are pushed

<label for="accTopic">Accordion Topic</label><br/>
<input type="text" name="accTopic" id="accTopic"><br/><br/>
<label for="accordionPanel">Accordion Content</label><br/>
<textarea name="accordionPanel" id="accordionPanel" rows="20" cols="50"></textarea><br>
let items = [];
function getItems() {
let accTopic = document.getElementById("accTopic").value;
let accPanel = CKEDITOR.instances.accordionPanel.getData();
items.push(
{
topic: accTopic,
panel: accPanel,
}
);
return(items);
}
Hello and thank you for looking at this. I am hoping to figure out how to get the index of the above array so I can assign to a button for editing.
Project Info:
I'm hoping to create a tool that customers can use to build an accordion without writing HTML but just pasting the HTML into the source code of CK Editor.
My obstacle is assigning the index of the array to a variable that I can reference from the HTML to edit the topic/detail of an accordion item.
Basically, if I had to talk it out, would go like this:
Accordion item created. It's the third item in the array
There is a for loop that assigns the appropriate classes, IDs and attributes to the items which allows expanding/collapsing of items
There is an 'Edit' button that allows someone to edit the accordion item, which is identified by the index of the array via an HTML attribute. This assignment would be assigned in the for... loop. If it's the third item, the index would be 2 which would trigger an edit function.
Am I off-base with this? Please let me know and thank you,
You can directly get all the items using document.querySelectorAll and get the index of the clicked element using Array#indexOf.
let items = [...document.querySelector('.accordion').querySelectorAll('.accordion-item')];
let index = items.indexOf(elem);

Selecting an element with placing a custom dataset as the class

I'm new to javascript And facing a little issue,
I hope I will get the solution here
I have a nav Item with a data like this
<button data-home="home" class="nav-item"></button>
I did select the button element as a var and got its dataset
var navI = document.querySelector('.nav-item')
var homeC = navI.dataset
And then I wanted to set this item as a class to select a new element
new element,
<div class="home"></div>
And placed the dataset like this to select the element
var pageHome = document.querySelecter('.' + homeC)
But pageHome comes with a null element
Pls pass me a solution if possible
dataset is the entire data set, i.e. the result of all data-* attributes on the element or properties set via the element data API.
You need to reach into it and get the property you need. In short, change
var homeC = navI.dataset
to
var homeC = navI.dataset.home
Also be aware that these days var is not recommended; use let or const.
[EDIT]
Since you know say the home element has the ID "home", not the class "home", you need:
document.querySelector('#'+homeC);

Javascript selectors how to only get first ranking a refs

Hi there I'm fiarly new to coding. and doing some javascipt layouting. but I need to make some variables. and don't know how. I want to make a dropdown menu. for this site. bertconinx.com now in order to do the thing I want to do I need to be albe to select a href without having to change any html. let the browser go to the link and then execute some javascript so what I need to do is find a way how to select the specific a href. I need to select the head menu intem without selecting any submen Items. because they should be dropdowns on a clickevent.
I got as far as this..
a href="http://bertconinx.com/category/portrets/">Portrets</a
a href="http://bertconinx.com/category/weddings/">Weddings</a>
should load first and then should dropdown his submenu clickevents.
but slecting the a href seems trick I've tried.
var MenuEvent = document.getElementsByClassName("menu-item").getElementsByTagName("a");
But it does not work.
Any Ideas on how to select them?
thanks.
The documentNode.getElementsByClassName returns a list of items, so while you can call .getElementsByTagName on each one, you can't call the function on the list directly. What you need to do is something like
// initialize an array to hold the anchors we get, and get all menu items on the document
var firstAnchors = [],
menuItems = document.getElementsByClassName('menu-item');
// iterate through the menu items and their specific anchors, adding only the first one of each menu item to our list
for(var menuItem of menuItems){
firstAnchors.push(menuItem.getElementsByTagName('a')[0]);
}
// now, our anchors should be here
console.log(firstAnchors);
var parentMenus = [],
parentMenueElems = document.getElementById("menu-main-nav").children;
for(var parentMenueElem of parentMenueElems){
if(!parentMenueElem){continue;}
var parentMenue = {
"name": parentMenueElem.firstElementChild.text,
"anchor": parentMenueElem.firstElementChild
};
parentMenus.push(parentMenue);
}
console.log(parentMenus)
OutPut:
[
{"name":"Portrets","anchor":element},
{"name":"Weddings","anchor":element},
{"name":"Wild","anchor":element},
{"name":"Commercial Work","anchor":element},
{"name":"About","anchor":element}
]
Example: element --> Portrets
Now you can perform any event on element
parentMenus[2].anchor.click();

Onclick event - MULTIPLE CLICKS

I'm building a site and I wish to have an image that once clicked it is replaced by another image and, on a second click, replaced by a third image an so on.
I've written a JavaScript function for this. The problem is that I can only call out one item on my index list, it never allows me several clicks to go trough all of my index items.
This is the code I've written so far:
function change (index) {
var links = new Array();
links[0] = img/videoplace.jpg;
links[1]="img/hiroshima.jpg";
var image = document.getElementById('social');
image.src = links[index];
}
<div class="box box1">
<img class="textOverImage" src="img/beehive.jpg" alt="social logo" id="social" onclick= "change(0); change(1)" >
</div>
Writing in the Html <img class="textOverImage" src="img/beehive.jpg" alt="social logo" id="social" onclick= "change(0); change(1)"> just causes the image to be replaced by the one corresponding to change(1) on first click.
Really appreciate any help that can be given.
Attach the event handler properly using Javascript instead (inline handlers are widely considered to be poor practice, and they're difficult to manage). Then, in the Javascript, you can keep a persistent variable of the current image index that's being displayed. On every click, increment the index, and display the appropriate image:
const links = [
'img/beehive.jpg', // first image is already displayed when page is loaded
'img/videoplace.jpg',
'img/hiroshima.jpg'
];
let index = 0;
const img = document.querySelector('#social');
img.addEventListener('click', () => {
index++;
img.src = links[index];
});
Note that declaring an array all at once is often nicer and more concise than using new Array() and assigning to indicies one-by-one.
If you want the displayed images to wrap around so that, once the last image is clicked on, the first image is displayed again, then use modulo. Instead of
index++;
do
index = (index + 1) % links.length;

Categories