How to wrap a string with a html tag in hyperHTML through RegEx replace

170 views Asked by At

I'm building a search auto-suggest component where the results are rendered with hyperHTML. The matching string part of the suggestions returned from the server should be highlighted.

I'm using a RegEx and String.prototype.replace to highlight the matching part, but somehow I can't manage to output the return value of it to HTML. It just renders the <strong> tags as strings.

I tried quite a bit of different approaches to solve this but without any success and am running out of ideas...

This is my rendering function:

const suggestionsContainer = document.querySelector(
  ".js-suggestions-container"
);
const suggestions = [{
    title: "lorem ipsum dolor sit amet",
    url: "#"
  },
  {
    title: "lorem ipsum dolor sit amet",
    url: "#"
  }
];
let query = "ipsum";

function renderSuggestions(suggestions, query) {
  const queryRegEx = new RegExp(query, "gi");
  hyperHTML.bind(suggestionsContainer)`
      ${suggestions.map((suggestion) => hyperHTML.wire(suggestion)`
        <a href="${suggestion.url}">
          ${hyperHTML.wire()`${suggestion.title.replace(queryRegEx, "<strong>$&</strong>")}`}
        </a>
      `)}
  `;
}

renderSuggestions(suggestions, query);
a {
  display: block;
  margin: 1rem 0;
}
<script src="https://unpkg.com/hyperhtml@latest/min.js"></script>
<div class="js-suggestions-container"></div>

1

There are 1 answers

0
Andrea Giammarchi On BEST ANSWER

As you can see in this CodePen, the only change you need is to explicitly ask for html:

  ${suggestions.map((suggestion) => hyperHTML.wire(suggestion)`
    <a href="${suggestion.url}">
      ${{html: suggestion.title.replace(queryRegEx, "<strong>$&</strong>")}}
    </a>
  `)}

The {html: ...} is the most obvious way, but hyperHTML also injects arrays as HTML, but that might be unexpected, while both lighterhtml and micro html are safer by default, and interpolated content must be always explicitly injected.

P.S. wiring just text as content is also almost never necessary