I would like to automate duplicating a class from a parent div to each separate child span based on a word.
As an example: parent div contains the following classes: grid-item tag-street-style tag-slender tag-classic tag-navy tag-grey tag-white is-loaded
I would like to duplicate any classes within the parent div with the precursor "tag-" and place them into each separate child span. In this case, the parent div contains the classes with the initial "tag-" word: tag-street-style tag-slender tag-classic tag-navy tag-grey tag-white
Some other parent divs will contain other classes that contain the initial word "tag-"
The "tag-" classes can be different in other parent divs but there will always be 5 "tag-" classes. As an example, a different parent div may contain the following classes with the initial "tag-" word: tag-smart-style tag-casual tag-modern tag-red tag-black tag-green
I already have a code snippet but this is locked in to 5 specific "tag-" classes. Here is the code:
let classMap = {
"tag-street-style": ".colour-tag-1",
"tag-slender": ".colour-tag-2",
"tag-navy": ".colour-tag-3",
"tag-grey": ".colour-tag-4",
"tag-white": ".colour-tag-5",
};
I would like the first "tag-" class identified within the parent div to be duplicated into "colour-tag-1" within the first child span.
Then I would like the second "tag-" class identified within the parent div to be duplicated into "colour-tag-2" within the second child span.
Then I would like the third "tag-" class identified within the parent div to be duplicated into "colour-tag-3" within the third child span.
Then I would like the fourth "tag-" class identified within the parent div to be duplicated into "colour-tag-4" within the fourth child span.
Then I would like the fifth "tag-" class identified within the parent div to be duplicated into "colour-tag-5" within the fifth child span.
$(document).ready( function() {
$(".grid-item .grid-meta-wrapper").each(function(e){
$(this).append('<div class="product-view-item-colour-tags"><span class="product-view-item-colour-tag colour-tag-1">tag1</span><span class="product-view-item-colour-tag colour-tag-2">tag2</span><span class="product-view-item-colour-tag colour-tag-3">tag3</span><span class="product-view-item-colour-tag colour-tag-4">tag4</span><span class="product-view-item-colour-tag colour-tag-5">tag5</span></div>');
});
let classMap = {
"tag-street-style": ".colour-tag-1",
"tag-slender": ".colour-tag-2",
"tag-navy": ".colour-tag-3",
"tag-grey": ".colour-tag-4",
"tag-white": ".colour-tag-5",
};
for (let cls in classMap) {
document.querySelector(classMap[cls]).classList.add(cls);
}
});
<style>
.tag-street-style {
background-color: purple;
}
.tag-slender {
background-color: red;
}
.tag-navy {
background-color: blue;
}
.tag-grey {
background-color: grey;
}
.tag-white {
background-color: black;
color: white;
}
.tag-red {
background-color: black;
color: red;
}
.tag-black {
background-color: white;
color: black;
}
.tag-green {
background-color: black;
color: green;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="grid-item tag-street-style tag-slender tag-classic tag-navy tag-grey tag-white is-loaded">
<section class="grid-meta-wrapper">
<div class="grid-main-meta">
<div class="grid-title"> T-Shirt </div>
<div class="grid-prices">
<div class="product-price">
<span>12.99</span>
</div>
</div>
</div>
<div class="grid-meta-status"></div>
</section>
</div>
<br><br><br>
<div class="grid-item tag-smart-style tag-casual tag-modern tag-red tag-black tag-green is-loaded">
<section class="grid-meta-wrapper">
<div class="grid-main-meta">
<div class="grid-title"> T-Shirt </div>
<div class="grid-prices">
<div class="product-price">
<span>12.99</span>
</div>
</div>
</div>
<div class="grid-meta-status"></div>
</section>
</div>
First, here is a testable solution:
$(document).ready( function() {
$(".grid-item .grid-meta-wrapper").each(function(e){
$(this).append('<div class="product-view-item-colour-tags"><span class="product-view-item-colour-tag colour-tag-1">tag1</span><span class="product-view-item-colour-tag colour-tag-2">tag2</span><span class="product-view-item-colour-tag colour-tag-3">tag3</span><span class="product-view-item-colour-tag colour-tag-4">tag4</span><span class="product-view-item-colour-tag colour-tag-5">tag5</span></div>');
});
let classes = [...document.getElementById("tag-specifier").classList].filter(item => item.indexOf("tag-") === 0);
for (let index = 0; index < classes.length; index++) {
let currentItem = document.querySelector(".colour-tag-" + (index + 1));
if (currentItem !== null) {
currentItem.classList.add(classes[index]);
}
}
});
.tag-street-style {
background-color: purple;
}
.tag-slender {
background-color: red;
}
.tag-navy {
background-color: blue;
}
.tag-grey {
background-color: grey;
}
.tag-white {
background-color: black;
color: white;
}
.tag-red {
background-color: black;
color: red;
}
.tag-black {
background-color: white;
color: black;
}
.tag-green {
background-color: black;
color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="tag-specifier" class="grid-item tag-street-style tag-slender tag-classic tag-navy tag-grey tag-white is-loaded">
<section class="grid-meta-wrapper">
<div class="grid-main-meta">
<div class="grid-title"> T-Shirt </div>
<div class="grid-prices">
<div class="product-price">
<span>12.99</span>
</div>
</div>
</div>
<div class="grid-meta-status"></div>
</section>
</div>
Now, let's understand it:
id
of tag-specifier
to the element which has the classes, so the code will have an easy time finding the classes to work withdocument.getElementById("tag-specifier").classList
is returning an object of key-value pairs where the keys are indexes (starting from 0) and the values are class namesclassList
into an array via [...document.getElementById("tag-specifier").classList]
because I intend to use the filter()
function of the array, alternatively I could have written a loop with similar effect.filter()
is being called for the newly converted array. This function takes a callback (more on that below) that determines which items we are interested about from the array and returns an array that contains only the items that the callback found interesting.filter()
is a function which will be executed for each elements of the array and will evaluate them whether they are interestingitem => item.indexOf("tag-") === 0
, which is a function (we use the arrow operator =>
to differentiate the parameter, which is item
and the actual function body, which is item.indexOf("tag-") === 0
), that is, we are only interested about items whose name starts with tag-
.filter()
, the value assigned to classes
is an array of class names that only holds valuable class names from our perspective, that is, class names starting with tag-
classes
using a variable we create for this purpose, named index
".colour-tag-" + (index + 1)
. The reason for the index + 1
is that Javascript arrays are 0-indexed and your tag indexes start from 1(index + 1)
is enclosed into parantheses. The reason for this is that +
is an operator that acts both as concatenator and numeric addition and evaluates from left-to-right, that is, without the paranthesis around (index + 1)
the result of ".colour-tag-" + index + 1
would be looking like .colour-tag-01
instead of .colour-tag-2
currentItem
exists, so we program defensively, so, if any anomaly occurs, we intend our code to handle it gracefullycurrentItem
existed, then we add the current class, which is classes[index]
EDIT
The initial solution I have implemented was assuming that we deal with a single such case, while your problem included multiple similar cases on the same page. To solve this issue, I have added an extra layer to the solution, querying the roots of all relevant subtrees in HTML and using them as the context of their respective problem-spaces.
Here is a snippet that illustrates it (yes, the first 3 tags will be unstyled, but this is not due to the logic of the code, but it is rather due to the styling specification of the structure):
$(document).ready( function() {
$(".grid-item .grid-meta-wrapper").each(function(e){
$(this).append('<div class="product-view-item-colour-tags"><span class="product-view-item-colour-tag colour-tag-1">tag1</span><span class="product-view-item-colour-tag colour-tag-2">tag2</span><span class="product-view-item-colour-tag colour-tag-3">tag3</span><span class="product-view-item-colour-tag colour-tag-4">tag4</span><span class="product-view-item-colour-tag colour-tag-5">tag5</span><span class="product-view-item-colour-tag colour-tag-6">tag6</span></div>');
});
for (let context of $(".list-grid .grid-item")) {
let idDeclaration = context.id;
let classes = [...context.classList].filter(item => item.indexOf("tag-") === 0);
for (let index = 0; index < classes.length; index++) {
let currentItem = context.querySelector(".colour-tag-" + (index + 1));
if (currentItem !== null) {
currentItem.classList.add(classes[index]);
}
}
}
});
.product-view-item-colour-tags .tag-navy {
background-color: blue;
}
.product-view-item-colour-tags .tag-grey {
background-color: grey;
}
.product-view-item-colour-tags .tag-white {
background-color: black;
color: white;
}
.product-view-item-colour-tags .tag-red {
color: red;
}
.product-view-item-colour-tags .tag-black {
background-color: white;
color: black;
}
.product-view-item-colour-tags .tag-green {
color: green;
}
.product-view-item-colour-tags .tag-yellow {
background-color: black;
color: yellow;
}
.product-view-item-colour-tags .tag-orange {
color: orange;
}
.product-view-item-colour-tags .tag-pink {
color: pink;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list-grid">
<div id="thumb-product-3-9" class="grid-item tag-street-style tag-slender tag-classic tag-navy tag-grey tag-white is-loaded">
<section class="grid-meta-wrapper">
<div class="grid-main-meta">
<div class="grid-title"> T-Shirt 1</div>
<div class="grid-prices">
<div class="product-price">
<span>9.99</span>
</div>
</div>
</div>
<div class="grid-meta-status"></div>
</section>
</div>
<br>
<div id="thumb-product-3-12" class="grid-item tag-social-style tag-thicker tag-premium tag-green tag-black tag-red is-loaded">
<section class="grid-meta-wrapper">
<div class="grid-main-meta">
<div class="grid-title"> T-Shirt 2</div>
<div class="grid-prices">
<div class="product-price">
<span>12.99</span>
</div>
</div>
</div>
<div class="grid-meta-status"></div>
</section>
</div>
<br>
<div id="thumb-product-3-1" class="grid-item tag-outdoor-style tag-warmer tag-premium tag-pink tag-white tag-orange is-loaded">
<section class="grid-meta-wrapper">
<div class="grid-main-meta">
<div class="grid-title"> T-Shirt 3</div>
<div class="grid-prices">
<div class="product-price">
<span>14.99</span>
</div>
</div>
</div>
<div class="grid-meta-status"></div>
</section>
</div>
<br>
<div id="thumb-product-3-4" class="grid-item tag-street-style tag-slender tag-casual tag-green tag-yellow tag-red is-loaded">
<section class="grid-meta-wrapper">
<div class="grid-main-meta">
<div class="grid-title"> T-Shirt 4</div>
<div class="grid-prices">
<div class="product-price">
<span>15.99</span>
</div>
</div>
</div>
<div class="grid-meta-status"></div>
</section>
</div>
</div>