0
\$\begingroup\$

Objective

I set up my page to dynamically wrap <i> tags around a targeted keyword (string) on a title.

Background

When I worked on the static parts of the website, I could manually wrap that word. But Some parts of the page will be generated by the server, so if the word appears in the title, I need it wrapped so that it shows up as italicized.

For the sake of an example, let's say that if the keyword is "cool" then it needs to be converted to <i>cool</i> if it appears in a title, which in this case is class "exec-company"

<div class="exec-company"><?php the_field('company') ?></div>

Lets say the output was this HTML

<div class="exec-company">Cool company</div>

I followed along to this tutorial. Which advised on using jQuery and showed this sample

var oldString = 'john',
newString = '<span>John</span>',
newText = $('p').text().replace(RegExp(oldString,"gi"),newString);

$('p').html(newText);

I modified to this so that it is always uppercase, and always italicized

var oldString = 'cool',
newString = '<i>COOL</i>',
newText = $('.exec-company').text().replace(RegExp(oldString,"gi"),newString);

$('.exec-company').html(newText);

On codepen, I made a demo which produced this.

enter image description here

but wondering if this was the best way to approach this problem. Especially since the solution won't really scale well since the word is used site wide.

\$\endgroup\$
  • \$\begingroup\$ Looks like you're using WordPress and maybe ACF plug-in. If so, you are better off adding a filter to hook into specific WP functionality. Lots more work to do it client side in JS... \$\endgroup\$ – Patrick Moore Jan 25 '17 at 2:47
1
\$\begingroup\$

First of all, I would highly recommend NOT doing this in JS for the following reasons:

  • You'd have JS scan through words, which may be slow.
  • FOUC, where the word is not italic until the JS runs.
  • jquery.text() captures newlines and whitespace. If the word is split with unexpected newlines in between, the script breaks.
  • jquery.html replaces HTML using innerHTML. This means:
    1. Existing event handlers, especially those created by frameworks, are not cleaned up properly.
    2. Existing event handlers will not be re-attached to your new HTML.

In addition to that, I suggest not hardcoding the replacement string. Use capture groups to have RegExp capture the match. Then convert the matched string to upper case and wrap it with the element afterwards. That way, you don't have hard-coded replacements, only the searches.

What I highly suggest is to do this on the PHP side instead. You can take the same logic, except just to it there. I believe preg_replace is what you need for this. If you cannot access the server-side code, then request access.

JS might be the quick and easy way to do this, but stuff like this over time leads to fragmented, highly unmaintainable, and hard-to-find code. A normal developer would think "Hey, it's probably italicized in the source." until they find out days later (yes, days) it was never in PHP. Thenthey'll have to hunt it down in JS, except they won't know where to start.

\$\endgroup\$
0
\$\begingroup\$

If your goal is to take text input from the element and return it in all caps, with <i> tags wrapped around it, you can simply use a function to apply this outcome to any string.

To change the entire string:

 function italicCapsAll(str){
   return '<i>' + str.toUpperCase() + '</i>'
 }

Or if you need to target just a specific word or phrase:

function italicCapsPart(str, target){
  return str.replace(target,'<i>' + target.toUpperCase() + '</i>')
}

Then just select your element's text and pass it in.

 var targetEl = document.querySelector('.exec-company')
 var targetText = targetEl.textContent //or targetEl.innerHTML;

 targetEl.innerHTML = italicCapsAll(targetText)
 //or
 targetEl.innerHTML = italicCapsPart(targetText, 'cool')
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.