2

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>

4
  • Are you sure you need to put the tag as <bold> instead of <b> ? And also I'd suggest rather something like <span style="font-weight:bold;">...</span> as the b-tag should be used as a last resort. Commented Jul 14, 2020 at 17:00
  • @casenonsensitive Yes, you're right. I'd meant to use <strong> and not <bold>. I edited the post to correct it. But that doesn't change anything about the main problem that the tag is not rendered as html but as a string, regardless of the kind of html tag I use. Commented Jul 14, 2020 at 17:12
  • I'm guessing the a element is created correctly, so the problem would be inside it. Have you tried making it more easy, replacing the ${wire()`${suggestion.title.replace(queryRegEx, '<strong>$&</strong>')}`} with ${suggestion.title.replace(queryRegEx, '<strong>$&</strong>')} ? Commented Jul 14, 2020 at 20:13
  • @casenonsensitive Yes, tried that as well. Makes no difference. I replaced the code example in my original question with a runnable code snippet to make it a bit easier to understand/reproduce. Commented Jul 15, 2020 at 5:32

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.