amandathewebdev
amandathewebdev

Reputation: 259

How to loop through a div and add a class using regular expression?

I've found how to find a regular expression in a div, and even on how to add a class using one, but I haven't been able to find an example where I can loop the process. I tried indexOf() and couldn't get that to work for me. I'm not sure that's even what I need. What I'd like to do, is change text in my label #variant_label that is between two square brackets [ ], red. I can do that, but it only works on the first label - it doesn't work on the second.

Here's my HTML:

<input type="radio" name="id" value="value" id="radio_variant-id" checked="checked" />
<label for="radio_variant-id" id="variant_label">5 Packs of 4 (20 Count) [Save 10%]</label>
<p class="variant_price">PRICE <span>SKU</span></p>

<input type="radio" name="id" value="value" id="radio_variant-id" checked="checked" />
<label for="radio_variant-id" id="variant_label">10 Packs of 4 (40 Count) [Save 15%]</label>
<p class="variant_price">PRICE <span>SKU</span></p>

Here's the CSS:

.highlight {color: #F00}

Here's the JavaScript with my regex that makes "[Save 10%]" red, but doesn't work on "[Save 15%]":

var o = document.getElementById("variant_label");
o.innerHTML = o.innerHTML.replace(/(?:^|[^!])(\[[^[\]]*])/g, '<span class="highlight">$&</span>');

Here is a fiddle of what I have: https://jsfiddle.net/dr4vp2sq/1/

I found this fiddle that accomplishes what I want to do, but I need to narrow it down to just the text within my #variant_label and I'm having a hard time figuring out how. http://jsfiddle.net/cz6owdxx/4/

Upvotes: 3

Views: 86

Answers (2)

Rion Williams
Rion Williams

Reputation: 76557

You currently have multiple elements with the same id attribute, which constitutes invalid markup as they are unique by definition :

The id global attribute defines a unique identifier (ID) which must be unique in the whole document. Its purpose is to identify the element when linking (using a fragment identifier), scripting, or styling (with CSS).

Consider Using Classes Instead

Since id based targeting is going to be out of the question for multiple elements (this includes your <input> elements and anything else), you might consider using class attributes instead :

<!-- Other code omitted for brevity -->
<label for="radio_variant-id" class="variant_label">5 Packs of 4 (20 Count) [Save 10%]</label>
<label for="radio_variant-id" class="variant_label">10 Packs of 4 (40 Count) [Save 15%]</label>

and then use getElementsByClassName() to grab your labels and then apply your expression to them, which should work as expected :

// Get your labels
var labels = document.getElementsByClassName("variant_label")
for(var e = 0; e < labels.length; e++){
    // Update each label
    labels[e].innerHTML = labels[e].innerHTML.replace(/(?:^|[^!])(\[[^[\]]*])/g, '<span class="highlight">$&</span>');
}

Example

You can see an updated example of your Fiddle here and demonstrated below :

enter image description here

Upvotes: 1

Roko C. Buljan
Roko C. Buljan

Reputation: 206151

Use class class="variant_label" instead of duplicate ID:

function replacer(el) {
 el.innerHTML = el.innerHTML.replace(/(?:^|[^!])(\[[^[\]]*])/g, '<span class="highlight">$&</span>');
}

[].forEach.call(document.querySelectorAll(".variant_label"), replacer);
.highlight{color:red;}
<input type="radio" name="id" value="value" id="radio_variant-id1" checked="checked" />
<label for="radio_variant-id1" class="variant_label">5 Packs of 4 (20 Count) [Save 10%]</label>
<p class="variant_price">PRICE <span>SKU</span></p>

<input type="radio" name="id" value="value" id="radio_variant-id2" checked="checked" />
<label for="radio_variant-id2" class="variant_label">10 Packs of 4 (40 Count) [Save 15%]</label>
<p class="variant_price">PRICE <span>SKU</span></p>

Upvotes: 1

Related Questions