Loop through text for multiple instances of same string - javascript

I have a passage of text, which might have multiple of the same word in it. Whenever this word appears, I want to replace it with itself, but wrapped in a div so that I can apply styles and add some extra text.
I have got this working for the first instance of the word:
var definition = glossaryList[index].definition;
var termStart = textAsLower.search(termAsLower);
var termEnd = term.length + termStart;
var replacedText = addDefinitionToText(textContent, term, definition, termStart, termEnd);
function addDefinitionToText(textContent, term, definition, termStart, termEnd) {
var textStart = textContent.substring(0, termStart);
var termInText = textContent.substring(termStart, termEnd);
var textEnd = textContent.substring(termEnd);
var replacedTerm = '<span class="has-definition">' + termInText;
replacedTerm += '<div class="attached-definition">';
replacedTerm += '<div class="defintion-title">' + term + '</div>';
replacedTerm += '<div class="definition-text">' + definition + '</div>';
replacedTerm += '</div>';
replacedTerm += '</span>';
return textStart + replacedTerm + textEnd;
}
I've tried putting this function into a while loop and counting up, but it is causing me issues and freezing or not returning what I am expecting:
while(something.toLowerCase().search(termAsLower)) {
var something = textAsLower.substring(termEnd);
termStart = something.search(termAsLower);
termEnd = term.length + termStart;
replacedText = addDefinitionToText(something, term, definition, termStart, termEnd);
something = replacedText.substring(termEnd);
}
Does anyone have a solution to this? Ideally I would actually like a different method to .search(), which finds all instances not just the first, but my searches haven't been too fruitful.
Thanks!

You can simply use regex to achieve what you want:
var searchWord = "tag";
var textStr = "HTML tag is used for scripting. Tag can also be self-closing.";
// case-insensitive regex
var re = new RegExp(searchWord, "gi");
textStr = textStr.replace(re, '<' + searchWord + '>');
// case-sensitive search
var re = new RegExp(searchWord, "g");
textStr = textStr.replace(re, '<' + searchWord + '>');

I did something like this before. I split the text by spaces and put that array into foreach and edit. Here's an exapmle code
if(text.includes("http")){
var returnString = '';
text.split(" ").forEach(function(link) {
if(link.includes("http")){
returnString += '<a target="_blank" style="color:white" href="' + link + '">here</a> ';
}else{
returnString += link + " ";
}
});
text = returnString;

A regular expression with the String replace method can solve this fairly easily.
This function will return a new string with the word and definition wrapped.
I have used a template literal to make things a bit cleaner but they are unsupported in IE.
function wrapWordWithDefinition(sentance, word, definition) {
var template = `<div>
<div class="attached-definition">
<div class="defintion-title">${word}</div>
<div class="definition-text">${definition}</div>
</div>
</div>`;
// global and case insensitive
var re = new RegExp(word, 'gi');
return sentance.replace(re, template);
}
var sentance = "This will replace word, when word is encountered";
var myword = "word";
var definition = "The definition of the word";
var result = wrapWordWithDefinition(sentance, myword, definition);
console.log(result)
For further reading on regular expressions: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

Related

Issue with converting a function from ES6 to vanilla JavaScript to work in Internet Explorer

I created a Directory Search using regex to match the input to the data. I followed a tutorial for half of it and added to it on my own. It is working in Chrome, but not Internet Explorer.
I figured out this is due to ES6 incompatibilities in Internet Explorer and now I am having trouble figuring out how to correctly convert my displayMatches function to vanilla javascript or jQuery with no ES6.
So far most of it is working except that I can't figure how to remove the commas in in my html for the list of matches even though I tried using .join('')
Screenshot #1
Screenshot #2 - see the commas in between?
This is the working code on Chrome:
function displayMatches() {
// console.log(this.value);
$('.suggestions').show();
var matchArray = findMatches(this.value, employees);
console.log(matchArray);
var html = matchArray.slice(0,10).map(person => {
var regex = new RegExp(this.value, 'gi');
var firstName = person.GivenName.replace(regex, `<span class="hl">${this.value}</span>`);
var lastName = person.Surname.replace(regex, `<span class="hl">${this.value}</span>`);
var extension;
if (person.Phone_Ext1 !== null){
extension = person.Phone_Ext1;
} else {extension = "N/A"}
return `
<li class="search-item" data-id=${person.EmployeeID}>
<span class="person">${firstName} ${lastName}</span>
<span class="phone-ext">Ext. ${extension}</span>
</li>
`
}).join('');
if ($('#search-box').val() == ""){
suggestions.innerHTML = "";
} else {
suggestions.innerHTML = html;
}
}
And this is my attempt to convert:
function displayMatches() {
// console.log(this.value);
$('.suggestions').show();
var matchArray = findMatches(this.value, employees);
console.log(matchArray);
var html = [];
var person;
var list;
for(var i=0; i < matchArray.slice(0,10).length; i++){
person = matchArray.slice(0,10)[i];
var regex = new RegExp(this.value, 'gi');
var hilight = '<span class="hl">' + this.value + '</span>';
var firstName = person.GivenName.replace(regex, hilight);
var lastName = person.Surname.replace(regex, hilight);
var extension;
if (person.Phone_Ext1 !== null){
extension = person.Phone_Ext1;
} else {
extension = "N/A"
}
list =
'<li class="search-item" data-id=' + person.EmployeeID +'>' +
'<span class="person">' + firstName + ' ' + lastName + '</span>' +
'<span class="phone-ext">Ext. ' + extension + '</span>' +
'</li>';
html.push(list);
}
html.join('');
console.log(html);
if ($('#search-box').val() == ""){
suggestions.innerHTML = "";
} else {
suggestions.innerHTML = html;
}
}
html.join('') returns a new string. It doesn't transmogrify the array to a string, it doesn't assign a new value to the html variable. You would need to do
html = html.join('');
or even better use two separate variables, one of the array and one for the string.
Btw, you don't even need to construct and fill the array yourself in a loop, you can use the ES5 Array map method since IE9. As #H.B. remarked in the comments, you only need to use a function expression instead of the arrow syntax.

How to find a particular value in a string in js

I have a data like this,
var str = "#data time #city";
My goal is to make this as
var str = <a src="www.test/data">#data</a> time <a src="www.test/city">city</a>
I mean in my string where ever I found # its next value i.e data should be set as a param to the link www.test/{{param}} and should be surrounded with a link.Can any one suggest help.Thanks.
For this case, the String.replace() function will help you:
var str = "#data time #city"
str = str.replace(/#(\S+)/g, '#$1')
output.textContent = str
clickable.innerHTML = str
#output { font-family: courier }
<div id="output"></div>
<div id="clickable"></div>
The following code converts you data to the expected output.
The document.write(..) are for debug.
var data='#data time #city';
var hashtags = data.match(/#\S+/g);
document.write('before: ' + data + '</br>');
for (j = 0; j < hashtags.length; j++) {
// remove # from hashtag
var tag = hashtags[j].substring(1, hashtags[j].length);
// create the link
var link = '< a src="www.test/' + tag + '>#' + tag + '< / a > ';
// replace hashtag with link
data=data.replace(hashtags[j], link);
}
document.write('after: ' + data);

Wrap each word in string with span using regular exp

how to replace each word in text with "span" using regular exp?
var text = "1:393 1:838 3:936 1:998 1:1398 1:1652 1:1718 1:1806"
final op = "<span class="word">1:393</span><span class="word">1:838</span><span class="word">3:936</span><span class="word">1:998</span><span class="word">1:139</span>...."
You don't really need a regex for that if the separator is always a single space, just split on the space (or \b if you want a regex), add some markup, and join back together again.
var text = "1:393 1:838 3:936 1:998 1:1398 1:1652 1:1718 1:1806";
var op = text.split(' ').map(function(w) {
return '<span class="word">' + w + '------</span>';
}).join('');
document.body.innerHTML = op;
.word {color : red}
var op = '<span class="word">' + text.split(' ').join('</span><span class="word">') + '</span>'
Using String#replace.
const text = "1:393 1:838 3:936 1:998 1:1398 1:1652 1:1718 1:1806";
const result = text.replace(/\d:\d+/g, '<span class="word">$&</span>');
console.log(result);
This is what you need (https://jsfiddle.net/6r005vgf/3/):
var text = "1:393 1:838 3:936 1:998 1:1398 1:1652 1:1718 1:1806";
//var final = "<span class='word'>1:393</span><span class='word'>1:838</span><span class='word'>3:936</span><span class='word'>1:998</span><span class='word'>1:139</span>....";
var final_test = "<span class='word'>" + text.replace(/\s+/g, "</span><span class='word'>") + "</span>";
//alert(final);
alert(final_test);

correctly escaping characters when generating dynamic HTML

I have the following code in a jsFiddle:
function Start() {
var TheData = 'tes"ss<div></div>t3\'k';
var TheHTML = '<div class="SomeClass">' + TestXSS(TheData) + '</div>';
TheHTML += '<input type="text" id="TheTextBox" value="';
TheHTML += TestXSS(TheData) + '" />';
$('#Dynamic').html(TheHTML);
}
function TestXSS(TheText) {
TheText = TheText.replace('"', '"');
TheText = TheText.replace("'", ''');
TheText = TheText.replace('<', '<');
TheText = TheText.replace('>', '>');
return TheText;
}
As you can see, the HTML is dynamically generated and added to the DOM with jQuery, and there's also a function to escape characters that might cause problems. But in the fiddle, there's still an issue and so I was wondering how to correctly escape characters.
Thanks.
Try
function TestXSS(TheText) {
TheText = TheText.replace(/"/g, '"');
TheText = TheText.replace(/'/g, ''');
TheText = TheText.replace(/</g, '<');
TheText = TheText.replace(/>/g, '>');
return TheText;
}
Demo: Fiddle
TheText.replace('"', '"'); // stops after first match
use g modifier for global match
TheText = TheText.replace(/"/g, '"');
The g modifier is used to perform a global match (find all matches rather than stopping after the first match).`
I'd suggest reducing the number of (unnecessary) calls to replace(), and using a regular expression in concert with a map:
function TestXSS(TheText) {
var charMap = {
39 : '&#39',
34 : '&quot',
60 : '<',
62 : '>'
}
return TheText.replace(new RegExp("['\"<>]",'g'), function(a){
return charMap[a.charCodeAt(0)] || '';
});
}
JS Fiddle demo.
References:
RegExp().
replace().

javascript replace all is not working?

I have to replace all the special character form the html and i have created an array of special character having key value pairs of special characters and class name .
But this is not working . I have tried and the following is the code and fiddle link.
var SpClass = new Array();
SpClass["&"] = "ampClass";
function temp() {
var str = "";
var tempLen = SpClass.length;
var k = 0;
var htmlForRemoveChar = $("#test").html();
for (var splChar in SpClass) {
if (k > tempLen) {
$("#test").html(htmlForRemoveChar);
}
var tempChar = "/" + splChar + "/g";
alert(htmlForRemoveChar);
htmlForRemoveChar = htmlForRemoveChar.replace(tempChar, '<span class="specialChar "' + SpClass[splChar] + '"">W</span>');
alert(htmlForRemoveChar);
k++;
}
$("#test").html(htmlForRemoveChar);
}
<div id="test">this is test & i am doing testing</div>
<input type="button" onclick="temp();" value="Remove&">
http://jsfiddle.net/aps123/y4McS/1/
You just need to change this line:
var tempChar = "/" + splChar + "/g";
To:
var tempChar = new RegExp(splChar, 'g');
At present you're replacing a literal String, e.g. '/a/g'. If you need to dynamically create the contents of a regex then you need to use RegExp. If the contents is static then you can use a regex literal.
Try replacing replace(tempChar with replace(new RegExp(splChar, 'g').
It looks like you are using a string literal, not a regex literal. A regex literal is like this:
var x = /x/g;

Categories

Resources