Using Javascript to emphasize Ajax Response

I am faced with a challenge of highlighting specific words within text received from an ajax response, before generating HTML code and inserting it into the DOM. At the moment, I am utilizing the following code snippet:

function highlightWords(line, word, htmltag) {
    var tag = htmltag || ["<b>", "</b>"];
    var regex = new RegExp('(' + preg_quote(word) + ')', 'gi');
    return line.replace(regex, tag[0] + "$1" + tag[1]);
}

function preg_quote(str) {
    return (str + '').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<<>>\|\:])/g, "\\$1");
}

However, this method does not allow for highlighting individual words if the query is a phrase like sit behind. It highlights the entire phrase as one unit rather than each word separately. Additionally, it does not take HTML tags into consideration leading to less aesthetically pleasing results when the query includes a term like span...

I have come across different libraries that handle text highlighting more effectively, such as or

However, these libraries tend to focus on highlighting existing content within the DOM.

My scenario involves receiving an ajax response which needs to be converted into HTML using JS before being inserted into the parent container using DOM7 (similar to jQuery). Hence, I prefer to highlight the text before generating the HTMLString and pasting it into the DOM.

Any suggestions?

Answer №1

Utilizing a library is definitely the way to go for this task. I personally recommend using an excellent library called mark.js.

This library can be used independently or with jQuery, giving you great flexibility in implementation.

  1. Initiate the AJAX request.
  2. Inject the string into the DOM.
  3. Invoke the Mark.js API on the loaded content.

Below is a sample code snippet:

document.addEventListener('DOMContentLoaded', getText);

function getText() {
  const headline = document.getElementsByTagName("h1")[0];
  const p = document.getElementsByTagName("p")[0];

  fetch('https://jsonplaceholder.typicode.com/posts/1').
  then(response => response.json()).
  then(json => {
    console.log(json);
    headline.innerHTML = json.title;
    p.innerHTML = json.body;
    addMark('aut facere');
  });
}

function addMark(keyword) {
  var markInstance = new Mark(document.querySelector('.context'));
  var options = {
    separateWordSearch: true
  };
  markInstance.unmark({
    done: function() {
      markInstance.mark(keyword, options);
    },
  });
}
<script src="https://cdn.jsdelivr.net/mark.js/8.6.0/mark.min.js"></script>
<div class="context">
  <h1></h1>
  <p></p>
</div>

Answer №2

My solution for highlighting the response of an ajax request is below:

$.ajax({
    url : url,
    type : 'POST',
    success: function(response) {
        // Implementing Highlight
        let searchTerm = 'word';
        $container = $("#selector");
        $container.show().unhighlight();
        if (searchTerm){
            $container.highlight(searchTerm, {
                done: function() {
                    $container.not(":has(mark)").hide();
                }
            });
        }
    }
});

Answer №3

Important note: Be cautious as this code utilizes DOM7 in accordance with the question

Summary: Rather than adding an entire HTML string to your #container, consider appending normal text sections as text and highlighted elements as separate elements. This approach allows for easy styling customization.

var text // response from ajax call
var strQuery = 'sit behind' // search query 

var queryWords = strQuery.split(' ')
var textWords = text.split(' ')
var bufferNormalWords  = []

textWords.forEach(function (word) {
    if (queryWords.indexOf(word) != -1) { // word found
      var normalWords = bufferNormalWords.splice(0, buffer.length) // clear buffer
      // Your DOM7 logic here
      $$('#container').add('span').text(normalWords.join(' ')) // normal text
      $$('#container').add('span').css('color', 'red').text(word + ' ') // highlight in red          
    }
    else bufferNormalWords.push(word)
})

Avoid converting text to HTMLStrings unnecessarily; simply manipulate the text and create appropriate elements for styling using DOM7.

Answer №4

In the scenario where your ajax response includes HTML, it may be challenging to avoid creating DOM elements initially. The following code effectively accomplishes the task, even if the query involves the presence of span and the ajax results contain <span>.

        function highlightWords(line, word, htmltag) {
            var words = word.split(/\s+/);
            var tag = htmltag || ["<b>", "</b>"];

            var root = document.createElement("div");
            root.innerHTML = line;
            root = _highlightWords(words, tag, root);
            return root.innerHTML;
        }

        // Recursive examination of the generated DOM element
        function _highlightWords(words, htmlTag, el) {
            var children = [];

            el.childNodes.forEach(function(el) {
                if (el.nodeType != 3) { // excluding Text Type
                    var highlighted = _highlightWords(words, htmlTag, el);
                    children.push(highlighted);
                } else {
                    var line = _highlight(el.textContent, words, htmlTag);
                    var span = document.createElement("span");
                    span.innerHTML = line;
                    children.push(span);
                }
            });

            // Clearing the element's HTML contents to add new children
            el.innerHTML = "";
            children.forEach(function (c) { el.appendChild(c)});
            return el;
        }

        // Identifying and highlighting any matching words
        function _highlight(line, words, htmlTag) {
            words.forEach(function(singleWord) {
                if (!!singleWord) {
                    singleWord = htmlEscape(singleWord);
                    line = line.replace(singleWord, htmlTag[0] + singleWord + htmlTag[1]);
                }
            });
            return line;
        }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Please be aware that any fabricated comments will not be displayed in the posts object

-I have made an EDIT at the bottom of my original post -For my plunker, please visit this link Currently, I am learning AngularJS by following a tutorial located here. At this moment, I am stuck on the step called 'Faking comment data'. I have ...

Check if the page has been loaded using Jquery

Can anyone share a helpful strategy for initiating a function in JavaScript that only begins once the entire page has finished loading? ...

"Troubleshooting issue: Vue deep watch failing to detect changes in object properties

My initial data consists of a `customer` object. As I input text into various fields, different keys are added to the object. The watcher function triggers properly when a new key is added, but if an existing key is edited with a new value, the watcher doe ...

dividing an HTML string into individual variables using JavaScript

How can a string be split in pure JavaScript (without using JQuery/dojo/etc) in the most efficient and straightforward way? For example: var tempString = '<span id="35287845" class="smallIcon" title="time clock" style="color:blue;font-size:14px;" ...

Sending Ajax forms using Mootools with various sending methods and versions

Experimented with ajax form submission using mootools and tested 3 different methods. One method was successful while the others failed. Below is the HTML Form used for testing: <div class="container"> <form id="myForm" name="myForm" action= ...

iOS fixed positioning and scrolling

One of the current challenges we are facing involves implementing an action button similar to the one found in GMail for adding new content. This button needs to remain fixed during scroll. Here is the HTML code: <div class="addButton actionButton" on ...

difficulty in making an https request

My application was developed using OFFICEjs and was functioning properly on LOCALHOST. However, last week it suddenly started throwing an error message - "XHR Error." This issue arose out of nowhere, as I hadn't made any changes to the code over the w ...

Problem concerning the window object in a React functional component

Hey there, I am currently facing a situation where I need to access the window object within my React component in order to retrieve some information from the query string. Here is an excerpt of what my component code looks like: export function MyCompone ...

Add a variety of input values to a div in designated spots

Objective: The aim is to allow the user to connect form fields with specific locations within a content from another div, and then add the text entered in individual input fields to those corresponding locations. Here is the link to the fiddle HTML: < ...

The issue arises when the view fails to load while simulating a backend

Trying to test a specific element of the user interface requires a particular request to the backend with predefined data while allowing all other requests to pass through. Here's a more readable version in coffee script: describe 'select2 combo ...

What is the optimal approach for managing server-side data stored as a JavaScript variable?

When dealing with global variables like JSON inserted into a web page server side with PHP, the best way to handle it is up for debate. Options might include leaving it for garbage collection, omitting var initialization and deleting the variable, or simpl ...

Determining the value of an element by examining the clicked element

My goal is to determine the remaining balance in my cart based on the selected item. Let's say I have 3 items in my cart, and I choose one that costs $100. Previously, I stated that I had a total of $300. In my HTML code, there are elements with IDs ...

How can you use ajax to update the content of a single div in Yii?

I encountered a little issue when attempting to refresh the content of my div using Ajax, as it ends up replacing the entire page within that div. This is causing some trouble for me. Here is a snapshot of the problem: Problem Screenshot You can view my ...

pointing out the existing issues with the menu

I am struggling to figure out why I cannot highlight the current menu page on a navigation bar (aside from the fact that I am a complete beginner :-) I have tried using a JQuery function that I found online, but none of them seem to work. Here is the funct ...

The issue of not displaying results in a DIV when using CakePHP 2 and jQuery

I'm having trouble creating an auto-refreshing DIV with updated data. Despite everything appearing to be correct, it's not displaying any results on the webpage. Any assistance would be greatly appreciated :) Controller: public function homeNe ...

Tips for converting a number into a percentage with two decimal places using FormatJs Message Syntax

With the react-intl library, I am encountering a message that looks like this: serviceFee: { en: 'Service fee: ({fee, number, percent})', ... }, Upon calling <FormatMessage id="serviceFee" values={{ fee: 0.0625 }} /> I anticipate th ...

What is the most effective method for testing event emitters?

Imagine I have a basic component structured like this: @Component({ selector: 'my-test', template: '<div></div>' }) export class test { @Output selected: EventEmitter<string> = new EventEmitter<string>() ...

Issue encountered in Angularjs during upgrade process from version 1.2.27 to 1.4.7

Recently, I upgraded my app from using AngularJS 1.2.27 to version 1.4.7, but now I am encountering an error in the AngularJS file. SyntaxError: Unexpected token : (angular.js:12477) at Function (native) at Object.sd. ...

Implement rounded corners on D3js Donut Chart

In my AngularJS application, I have successfully implemented a donut chart as shown below: https://i.stack.imgur.com/3GVwN.png However, the design mockup indicates that we would like to achieve this look, with a border-radius property applied to the gree ...

The AngularJS application appears to have trouble accessing a local text file, even when it is deployed on

Within the same directory of my application deployed on IIS, there are 4 files: home.html Angular.js data.txt web.config (Automatically generated by IIS for default document) I am looking to display the content of 'data.txt' on 'home.html ...