I am trying to add a class when looping through an array, here is my current code:
var users = [{
name: "Jan",
id: "1",
number: "111-111-111"
},
{
name: "Juan",
id: "2",
number: "222-222-222"
},
{
name: "Margie",
id: "3",
number: "333-333-333"
},
{
name: "Sara",
id: "4",
number: "444-444-444"
},
{
name: "Tyrell",
id: "5",
number: "555-555-555"
},
];
var div = "<div>";
for (var i = 0; i < users.length; i ) {
div = "<p>" users[i].name "</p>";
div = "<p>" users[i].id "</p>";
div = "<p>" users[i].number "</p>";
}
div = "</div>";
document.getElementById("usersList").innerHTML = div;
<div class="contact-container">
<div class="navbar">
<ul>
<li>
<img src="https://img.icons8.com/ios-filled/50/000000/contact-card.png" />
</li>
<li>
<a href="#">View</a>
</li>
<li>
<a href="#">Add</a>
</li>
...
</ul>
</div>
<div class="users" id="usersList">
</div>
Is there any way I can add a class when looping?
CodePudding user response:
Why don't you put a class right there while looping? like this
for (var i = 0; i < users.length; i ) {
div = "<p class='myclass'>" users[i].name "</p>";
div = "<p class='myclass'>" users[i].id "</p>";
div = "<p class='myclass'>" users[i].number "</p>";
}
CodePudding user response:
Just add it into your HTML
for (var i = 0; i < users.length; i ) {
div = "<p class='user-name'>" users[i].name "</p>";
div = "<p class='user-id'>" users[i].id "</p>";
div = "<p class='user-number'>" users[i].number "</p>";
}
var users = [{
name: "Jan",
id: "1",
number: "111-111-111"
},
{
name: "Juan",
id: "2",
number: "222-222-222"
},
{
name: "Margie",
id: "3",
number: "333-333-333"
},
{
name: "Sara",
id: "4",
number: "444-444-444"
},
{
name: "Tyrell",
id: "5",
number: "555-555-555"
},
];
var div = "<div>";
for (var i = 0; i < users.length; i ) {
div = "<p class='user-name'>" users[i].name "</p>";
div = "<p class='user-id'>" users[i].id "</p>";
div = "<p class='user-number'>" users[i].number "</p>";
}
div = "</div>";
document.getElementById("usersList").innerHTML = div;
.user-name {
color: red;
}
.user-id {
color: blue;
}
.user-number {
color: green;
}
<div class="contact-container">
<div class="navbar">
<ul>
<li>
<img src="https://img.icons8.com/ios-filled/50/000000/contact-card.png" />
</li>
<li>
<a href="#">View</a>
</li>
<li>
<a href="#">Add</a>
</li>
...
</ul>
</div>
<div class="users" id="usersList">
</div>
CodePudding user response:
You could try creating your elements like this:
let div = document.createElement("div");
let p = document.createElement("p");
then add the class name:
p.className = "css class";
then add the parts to their parents:
div.appendChild(p);
document.getElementById("usersList").appendChild(div);
This is cleaner and more efficient than adding elements with innerHTML
CodePudding user response:
While you've already accepted an answer, I thought this might be an interesting opportunity to try to learn – for my own benefit, but hopefully to contribute an answer – about using custom elements.
So, with that in mind see the code below with its explanatory comments (though this remains something of a black-magic to me, hence my interest in working on it to formulate an answer):
// defining the custom-element, naming it 'user-card' which
// will lead to the element being a <user-card> element in the DOM:
customElements.define('user-card',
class extends HTMLElement {
constructor() {
super();
// we get the <template> element via its id (other
// selection methods are available, of course):
let template = document.getElementById('user-card');
// and retrieve its content:
let templateContent = template.content;
// here we assign its shadow root as 'open', which
// allows us - and JavaScript - to modify it:
const shadowRoot = this.attachShadow({
mode: 'open'
})
// and here we append the content of the <template>,
// including its child nodes (the 'true' argument
// to cloneNode()):
.appendChild(templateContent.cloneNode(true));
}
}
);
// your data:
let users = [{
name: "Jan",
id: "1",
number: "111-111-111"
},
{
name: "Juan",
id: "2",
number: "222-222-222"
},
{
name: "Margie",
id: "3",
number: "333-333-333"
},
{
name: "Sara",
id: "4",
number: "444-444-444"
},
{
name: "Tyrell",
id: "5",
number: "555-555-555"
},
],
userDiv = document.querySelector('#usersList');
// here we use Array.prototype.forEach() to iterate over the
// data, along with an anonymous Arrow function to pass the
// current user Object into the body of the function:
users.forEach(
(user) => {
// we create a new <user-card> element:
let card = document.createElement('user-card'),
// we create a new <li> element:
li = document.createElement('li'),
// we create a document fragment to contain the
// HTML we're going to create to hopefully minimise
// repaints:
fragment = document.createDocumentFragment();
// we then use Object.prototype.keys() to iterate over the
// array of Object keys returned (in order to access the
// contents of the user Object), and pass that key into
// the body of the function:
Object.keys(user).forEach(
(key) => {
// we create a clone of the <li> element:
let clone = li.cloneNode();
// we apply the class-name of the current key, so
// each element gets a class of 'name', 'id' or 'number',
// obviously other classes could be used but these made
// the most sense given the context:
clone.classList.add(key);
// because the <style> of the <user-card> element's template
// doesn't (seem to) apply to content added later, we use
// CSSStlyleDeclaration.setProperty() to set the relevant
// CSS properties of the cloned <li> element; here we
// define the 'grid-area' property to properly place the
// current element into the appropriate grid-area (defined
// in the <template>):
clone.style.setProperty('grid-area', key);
// we add the property-value of the current Object key:
clone.textContent = user[key];
// and append the clone to the fragment, using
// Element.append():
fragment.append(clone);
})
// once all the data is within the document fragment, we
// append that fragment to the <user-card> element:
card.append(fragment);
// and then append that <user-card> to the relevant ancestor
// <div> in the document:
userDiv.append(card);
});
/* a very basic reset, to minimise cross-browser differences and
and reset elements to their basic 'zero-style' state: */
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
font-family: Calibri, Helvetica, Ubuntu, Arial, sans-serif;
line-height: 1.4;
margin: 0;
padding: 0;
}
.users {
/* specifying display: grid, since it's a typical (and
relatively aesthetic) convention for 'cards': */
display: grid;
gap: 0.5em;
/* allows the grid to adjust its layout to best fit the
content within the constraints of the device: */
grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
margin: 1em auto;
max-width: 90vw;
}
<!-- the template element that contains the structure to be re-used, with an id
attribute for easy access via JavaScript, though other means of selection
are possible -->
<template id="user-card">
<!-- because the defined style of the light DOM (or COM) doesn't penetrate
into the shadow root we declare relevant CSS here, though there are
concerns about this too; from experimentation the CSS declared here
will target elements present in the <template> but not content added
later, via JavaScript: -->
<style>
ol {
border: 1px solid #ccc;
list-style-type: none;
display: grid;
gap: 0.5em;
grid-template-areas:
"id name name"
"number number number";
padding: 0.25em;
margin: 0;
}
</style>
<!-- I've chosen to use an <ol> since the data seems to be
ordered/structured: -->
<ol>
<!-- we use a <slot> element to contain the data we'll be appending
(later) via JavaScript: -->
<slot></slot>
</ol>
</template>
<!-- for reasons of brevity I removed the extraneous content and retained
only the minimal content relevant to the demo, which is why we have
only the elements below: -->
<div class="contact-container">
<div class="users" id="usersList"></div>
</div>
References:
- HTML:
- JavaScript:
- Arrow functions.
Array.prototype.forEach()
.CSSStyleDeclaration.setProperty()
.document.createElement()
.document.createDocumentFragment()
.document.querySelector()
.document.querySelectorAll()
.Element.append()
.Element.classList
API.Element.slot
.HTMLSlotElement
.HTMLTemplateElement
.Node.cloneNode()
.Object.prototype.keys()
.
Bibliography: