ganesh kaspate
ganesh kaspate

Reputation: 2695

Highlighting a text from string by using sub-string method

I have a string which you can is like:

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged

Now, in this string, I do have an json object in which from back-end all the start and end offsets of string which I have to highlight.

Now, for highlighting I am using following logic:

$scope.highlightHTML = function(content, startoffset, endoffset) {
  var className = 'mark';
  console.log(content.substring(startoffset, endoffset));
  return content.replace(content.substring(startoffset, endoffset), '<span class="' + className + '">$&</span>');
}

Here content is the given string and start and end are the endoffsets of the highlighting string.

Now, while calling this:

jsonDataArray.forEach(function(item) {
  responseData = $scope.highlightHTML(responseData, item.startOffset, item.endOffset, item.color);
});
$rootScope.data.htmlDocument = responseData.replace(/\n/g, "</br>");

Here consider responseData is the string which I provided in the question. From this I am calling the highlighthtml function.

Here the problem is that I am replacing the string with the span tags. Now what happens in loop is that when first lets say in array first value to highlight is the printing and typesetting industry. . So, offsets of this I get from the backend. Now, it will highlight that by replacing with the spans.

Now, when in array for second value, let's say a galley of type and scrambled it I get offsets but when it goes in highlight function then it is not getting the exact string because we have changed that string just by adding the span so now the offsets are changed for that string. So, because of this I am not able to highlight the proper words.

Upvotes: -1

Views: 169

Answers (2)

Sebastian Speitel
Sebastian Speitel

Reputation: 7346

You could go through you replacements from back to front by using a reversed loop to ensure the offsets of the elements, which aren't precessed yet aren't changed in the loop.

I added the sorting method as well, if you aren't sure if your data is in the correct order.

$scope.highlightHTML = function(content, startoffset, endoffset) {
  var className = 'mark';
  console.log(content.substring(startoffset, endoffset));
  return content.replace(content.substring(startoffset, endoffset), '<span class="' + className + '">$&</span>');
}

//Only if you don't know if they are in the correct order:
jsonDataArray = jsonDataArray.sort((a, b) => a.startOffset - b.startOffset);

for (var i = jsonDataArray.length - 1; i >= 0; i--) {
  const item = jsonDataArray[i];
  responseData = $scope.highlightHTML(responseData, item.startOffset, item.endOffset, item.color);
};
$rootScope.data.htmlDocument = responseData.replace(/\n/g, "</br>");

Upvotes: 3

cнŝdk
cнŝdk

Reputation: 32175

You can update the offsets by adding the extra length for the spans text added, in your loop like this:

var length = '<span class="mark"></span>'.length:
jsonDataArray.forEach(function(item, index) {
    responseData = $scope.highlightHTML(responseData, item.startOffset + (index * length), item.endOffset + (index * length), item.color);
});
$rootScope.data.htmlDocument = responseData.replace(/\n/g, "</br>");

So here in each iteration, you will be incrementing both offsets with (index *length), so for the first iteration you won't update them because indexis 0, then you will increment it by 1*length and so on.

Upvotes: 1

Related Questions