0

I'm struggling with how best to do this and am hoping for some advice.

For all of the inputs in this form, I need to split the label at the colon (:) and wrap a span around the latter half of the label, to achieve something like this: <label>Regular: <span class="price">$135 (1 Year) or $225 (2 Year)</span></label>.

Would RegEx be the best route to implement this? I'm not sure how to go about it, this is a little more complex than my knowledge of RegEx.

<div class="form-item webform-component webform-component-radios" id="webform-component-discount-options">

<div id="edit-submitted-discount-options" class="form-radios">

<div class="form-item form-type-radio form-item-submitted-discount-options">
   <input type="radio" id="edit-submitted-discount-options-1" name="submitted[discount_options]" value="none" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-1">Regular: $135 (1 Year) or $225 (2 Year) </label>
</div>

<div class="form-item form-type-radio form-item-submitted-discount-options">
 <input type="radio" id="edit-submitted-discount-options-2" name="submitted[discount_options]" value="senior" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-2">Senior: $108 (1 Year) or $180 (2 Year) </label>

</div>
<div class="form-item form-type-radio form-item-submitted-discount-options">
   <input type="radio" id="edit-submitted-discount-options-3" name="submitted[discount_options]" value="student" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-3">Student: $81 (1 Year) </label>
</div>

<div class="form-item form-type-radio form-item-submitted-discount-options">
   <input type="radio" id="edit-submitted-discount-options-4" name="submitted[discount_options]" value="nonresident" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-4">Non-Resident: $108 (1 Year) or $180 (2 Year) </label>
</div>

</div>
</div>
kait
  • 305
  • 2
  • 3
  • 11
  • There are several problems with this question: First, it may be an [XY problem](√). _Why_ do you "need" to do this, and do this with JavaScript? Second, you are expected to show your research, and your attempt to solve the problem yourself. As-is, you haven't shown any effort... – random_user_name Sep 26 '19 at 21:42
  • Yes, a regular expression would be an easy way to do this. Use a capture group to get everything after the colon, and then put that inside the span in the replacement. – Barmar Sep 26 '19 at 21:42
  • Try going to regular-expressions.info and read the tutorial section on capture groups. – Barmar Sep 26 '19 at 21:43

3 Answers3

1

I'm assuming you're simply curious how to automate this as an editing task (one that seems repetitive to do manually in your code editor).

Even though it is easy enough to do this manually for 4 inputs, you could indeed accomplish it also with a regular expression instead.

A regular expression similar to /(?<=: )[^<]+/gm; can assist in finding and replacing in the manner you've described. For example, Run the code snippet below:

let html = `<div class="form-item webform-component webform-component-radios" id="webform-component-discount-options">

<div id="edit-submitted-discount-options" class="form-radios">

<div class="form-item form-type-radio form-item-submitted-discount-options">
   <input type="radio" id="edit-submitted-discount-options-1" name="submitted[discount_options]" value="none" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-1">Regular: $135 (1 Year) or $225 (2 Year) </label>
</div>

<div class="form-item form-type-radio form-item-submitted-discount-options">
 <input type="radio" id="edit-submitted-discount-options-2" name="submitted[discount_options]" value="senior" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-2">Senior: $108 (1 Year) or $180 (2 Year) </label>

</div>
<div class="form-item form-type-radio form-item-submitted-discount-options">
   <input type="radio" id="edit-submitted-discount-options-3" name="submitted[discount_options]" value="student" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-3">Student: $81 (1 Year) </label>
</div>

<div class="form-item form-type-radio form-item-submitted-discount-options">
   <input type="radio" id="edit-submitted-discount-options-4" name="submitted[discount_options]" value="nonresident" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-4">Non-Resident: $108 (1 Year) or $180 (2 Year) </label>
</div>

</div>
</div>`;

let rx = /(?<=: )[^<]+/gm;

html = html.replace(rx,`<span class="price">$&</span>`);
console.log(html);
Lonnie Best
  • 9,936
  • 10
  • 57
  • 97
0

It's generally a bad idea to parse HTML with Regex.

HTML isn't a regular language, so regular expressions are not adequately equipped to deal with it. Seriously. You could summon cthulhu.

That being said, if you know your <label> tags are only on one line, are all properly formatted, and you're really determined to use regex, this will do the trick:

<label.*?>.*?:(.*?)<\/label>

It gets an opening label tag, reads to the first instance of a colon, and then captures everything after that until it hits the label's close tag. See a demo here.

This only works for your posted examples. If there's another attribute after the label, or you have nested label tags (for some reason), or a colon appears anywhere else in the label, the regex is going to break. If you're already in JS, it's probably a much better idea to just use element.innerText to get the text and then alter it that way.

Nick Reed
  • 4,989
  • 4
  • 17
  • 37
0

This method works without impacting DOM by ensuring no children exist when editing the contents.

$("label.option").each(function(x) {
  if($(this).children().length == 0) {
    var t = $(this).text();
    var r = t.replace(/(.*?:\s*)(.*?)\s*$/, '$1<span>$2</span>');
    $(this).html(r);
    console.log(r)
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-item webform-component webform-component-radios" id="webform-component-discount-options">

<div id="edit-submitted-discount-options" class="form-radios">

<div class="form-item form-type-radio form-item-submitted-discount-options">
   <input type="radio" id="edit-submitted-discount-options-1" name="submitted[discount_options]" value="none" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-1">Regular: $135 (1 Year) or $225 (2 Year) </label>
</div>

<div class="form-item form-type-radio form-item-submitted-discount-options">
 <input type="radio" id="edit-submitted-discount-options-2" name="submitted[discount_options]" value="senior" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-2">Senior: $108 (1 Year) or $180 (2 Year) </label>

</div>
<div class="form-item form-type-radio form-item-submitted-discount-options">
   <input type="radio" id="edit-submitted-discount-options-3" name="submitted[discount_options]" value="student" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-3">Student: $81 (1 Year) </label>
</div>

<div class="form-item form-type-radio form-item-submitted-discount-options">
   <input type="radio" id="edit-submitted-discount-options-4" name="submitted[discount_options]" value="nonresident" class="form-radio">
      <label class="option" for="edit-submitted-discount-options-4">Non-Resident: $108 (1 Year) or $180 (2 Year) </label>
</div>

</div>
</div>
ctwheels
  • 21,901
  • 9
  • 42
  • 77