Regex loop and number phone - javascript

Here is my code but I can't display the other numbers because I have indexed [0] and I don't know how I can display the other numbers.
Example string: "Hello, you can contact me at 0744224422 or 0192234422."
Result code : "Hello, you can contact me at <span>0744224422</span> or <span>0744224422</span>."
On this example: my code will replace "0192234422" by 0744224422 "which is logical" but I would like it to display 0192234422... How can I do it ?
Thanks
let selector = document.querySelectorAll('.message > div > .chat');
for (let index = 0; index < selector.length; index++) {
if (selector[index].innerText) {
let text = selector[index].innerText;
const regex = /(\d[\s-]?)?[\(\[\s-]{0,2}?\d{3}[\)\]\s-]{0,2}?\d{3}[\s-]?\d{4}/gim;
if (text.match(regex).length) {
const newTexte = ` <span>${text.match(regex)[0].trim()}</span> `;
selector[index].innerHTML = text.replace(regex, newTexte);
};
}
}

If you use the $ replacement character of the replace function, it will put the right text in there. Rather than trim just put parentheses around the non-whitespace portion of your regular expression and effectively let the capturing group become the trim operation.
let selector = document.querySelectorAll('.message > div > .chat');
for (let index = 0; index < selector.length; index++) {
if (selector[index].innerText) {
let text = selector[index].innerText;
const regex = /(\d[\s-]?)?([\(\[\s-]{0,2}?\d{3}[\)\]\s-]{0,2}?\d{3}[\s-]?\d{4})/gim;
if (text.match(regex).length) {
const newTexte = ` <span class="red">$2</span> `;
selector[index].innerHTML = text.replace(regex, newTexte);
};
}
}
.red {
background: yellow
}
<div class="message">
<div>
<div class="chat">Hello, you can contact me at 0744224422 or 0192234422.</div>
</div>
</div>
I'm going to try to call attention to the difference in the regular expressions below: (because I added one set of parentheses)
/(\d[\s-]?)?[\(\[\s-]{0,2}?\d{3}[\)\]\s-]{0,2}?\d{3}[\s-]?\d{4}/gim
( )
/(\d[\s-]?)?([\(\[\s-]{0,2}?\d{3}[\)\]\s-]{0,2}?\d{3}[\s-]?\d{4})/gim;

Do you have two separate instances of the selector? If not then the selector.length is only 1 which is why only the first number is shown. You can edit the html to have more than one instance of the selector (and style with display: inline so that it doesn't line break onto a new line) EX:
let selector = document.querySelectorAll('.message > div > .chat');
for (let index = 0; index < selector.length; index++) {
if (selector[index].innerText) {
let text = selector[index].innerText;
const regex = /(\d[\s-]?)?[\(\[\s-]{0,2}?\d{3}[\)\]\s-]{0,2}?\d{3}[\s-]?\d{4}/gim;
if (text.match(regex).length) {
const newTexte = ` <span>${text.match(regex)[0].trim()}</span> `;
selector[index].innerHTML = text.replace(regex, newTexte);
};
}
}
<div class="message">
<div>
<p class="chat" style="display:inline">
Hello, you can contact me at 0744224422 or </p>
<p class="chat" style="display:inline">0192234422</p>
<!-- add more numbers as needed in another <p class="chat" style="display:inline" ></p>-->
</div>
</div>

Thank you for your answers, but I would just like to add a <span></span> (or more) when a phone number is written in the string..

Related

Target last word and wrap with span class

I am trying to target the last word within a class and then wrap it with a span so that I can style the last word using Javascript.
<h1 class="title>A long tile</h1>
<h2 class="title>A long tile</h2>
becomes
<h1 class="title>A long <span class="last-word">tile</span></h1>
<h2 class="title>A long <span class="last-word">tile</span></h2>
I've seen some jQuery solutions on Stack which helped a bit, but I'd like a JS version.
I can get this working for the first element on the page, using this code…
var paras = document.querySelector('.title');
function wrapLastWord(elem) {
const textContent = elem.textContent.split(" ");
const lastWord = textContent.pop();
// if the sentence is more than 1 word, wrap the last word with a span. If it's only 1 word, return it without being wrapped by a span
const updatedContent = textContent.join(" ") + (textContent.length > 0 ? ` <span class='last-word'>${lastWord}</span>` : lastWord);
elem.innerHTML = updatedContent;
}
wrapLastWord(paras)
However, I want to target all classes of .title and hence I thought I could use a querySelectorAll and a forEach. I am clearly not understanding how this works.
var paras = document.querySelectorAll('.title');
paras.forEach(function wrapLastWord(elem) {
const textContent = elem.textContent.split(" ");
const lastWord = textContent.pop();
// if the sentence is more than 1 word, wrap the last word with a span. If it's only 1 word, return it without being wrapped by a span
const updatedContent = textContent.join(" ") + (textContent.length > 0 ? ` <span class='last-word'>${lastWord}</span>` : lastWord);
elem.innerHTML = updatedContent;
}
wrapLastWord(paras)
})
Could anyone please give me some pointers to get this working, or suggest an alternative direction
To begin you have a syntax error in your second line missing an "
<h1 class="title>A long <span class="last-word">tile</span></h1>
<h2 class="title>A long <span class="last-word">tile</span></h2>
should be this
<h1 class="title">A long <span class="last-word">tile</span></h1>
<h2 class="title">A long <span class="last-word">tile</span></h2>
As for getting the value using javascript you can simply do
const spanText = document.querySelector('.last-word).innerText
// this will find the first match
console.log(spanText)
//if you want to find all of the ".last-words"
const lastWords = document.querySelectorAll('.last-word')
console.log(lastWords, "<-array like object")
lastWords.forEach((word)=> {
console.log(word.innerText)
})
As for your function
var paras = document.querySelectorAll(".title");
console.log(paras);
paras.forEach(function wrapLastWord(elem) {
const textContent = elem.innerText.split(" ");
console.log(textContent, ' textContent')
const lastWord = textContent.pop();
console.log(lastWord, 'last word')
// // if the sentence is more than 1 word, wrap the last word with a span. If it's only 1 word, return it without being wrapped by a span
const updatedContent = ` <span class='last-word'>${lastWord}</span>`;
console.log(updatedContent, 'updatedContent')
})
You've created updatedContent as you can see in your log, but now you have to decide what you want to do with it. Maybe use one of the append methods you can look at the docs and explore the append method if you want to add it to your page
#JimithyPicker Thanks, you led me to an answer.
My final code is as follows:
const paras = document.querySelectorAll(".title");
paras.forEach(function wrapLastWord(elem) {
const textContent = elem.textContent.split(" ");
const lastWord = textContent.pop();
// if the sentence is more than 1 word, wrap the last word with a span. If it's only 1 word, return it without being wrapped by a span
const updatedContent = textContent.join(" ") + (textContent.length > 0 ? ` <span class='last-word'>${lastWord}</span>` : lastWord);
elem.innerHTML = updatedContent;
});

Transform text inside parentheses to uppercase

What I'm am trying to do is get the html text inside parentheses and transform it to uppercase. I want the output to be:
Cat (IVA)
Dog (MANGO) etc.
What am I doing wrong?
// Transform text inside parentheses to upper case
let petName = $(".petName").text();
let regExp = /\(([^)]+)\)/;
for (var i = 0; i < petName.length; i++) {
let regExp = /\(([^)]+)\)/;
regExp.replace(petName[i].toUpperCase())
}
html
<div>
<h1 class="petName">Cat (Iva)</h1>
</div>
<div>
<h1 class="petName">Dog (Mango)</h1>
</div>
<div>
<h1 class="petName">Puppy (Mara)</h1>
</div>
Multiple things wrong here:
String objects are immutable in JS. regExp.replace(…) does not change the original, it only returns the altered result.`
You are not selecting any elements to begin with. The selector .petName h1 matches h1 elements that are descendants of an element with the class petName
you can not directly call a function while replacing, you need to do this via a callback function, that gets the match(es) passed to it.
let $petNames = $("h1.petName")
$petNames.each(function() {
$(this).text( $(this).text().replace(/\(([^)]+)\)/, function(match) {
return match.toUpperCase()
} ) )
})
This should do it. :)
$(".petName").each(function(i, el) {
const text = el.innerText;
const strToReplace = text.match(/(\(.*\))/)[0];
el.innerText = text.replace(strToReplace, strToReplace.toUpperCase());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<h1 class="petName">Cat (Iva)</h1>
</div>
<div>
<h1 class="petName">Dog (Mango)</h1>
</div>
<div>
<h1 class="petName">Puppy (Mara)</h1>
</div>

Removing a link that contains particular text

I'm building a glossary page. I have a list of each letter of the alphabet at the top of the page, linking via anchor text to the correct section of content.
I want to remove the link from the letter if the letter has no terms.
I'm not getting any errors, but the code is not removing the link, or having any affect as far as I can tell.
Trying to remove link for B
function removeLink (){
var letternavcontent = document.getElementById("letternav").innerHTML;
var letter = document.getElementsByClassName("letter");
if ( letternavcontent.indexOf('B') > -1) {
letter.removeAttribute("href");
}
}
<p id="letternav">| <a class="letter"
href="/glossary.html#a">A</a> | <a class="letter"
href="/glossary.html#b">B</a></p>
Check this pen.
document.getElementsByClassName returns all the elements with that class name, not just one. So you must loop through this list and check each one.
function removeLink (){
var letter = document.getElementsByClassName("letter");
for (var i = 0; i < letter.length; i++) {
if (letter[i].innerHTML.indexOf('B') > -1) {
letter[i].removeAttribute("href");
}
}
}
How about this?
const removeLinkFromLetter = letter => {
// iterates over every letter element
[...document.querySelectorAll('.letter')].forEach(elt => {
// if the element has the specified letter as its text...
if (elt.innerText.trim()==letter) {
// ...change its content to the letter without the anchor tag
elt.innerHTML = letter;
}
});
}
window.onload = () => {
removeLinkFromLetter('A');
}
<p id="letternav">
|
<span class="letter">
<a href="/glossary.html#a">
A
</a>
</span>
|
<span class="letter">
<a href="/glossary.html#b">
B
</a>
</span>
|
</p>

find the longest word using javascript / html form

I tried to run the code but nothing is showing on my page.
i'm not sure where the mistakes are. I tried typing javaScript code to find the longest word in a html form/input,then showing the output on the html body.
function fnLongestWord(string){
var words = str.split(" ");
console.log(words);
var findlongest=document.forms["Longestword"],
var longest = "";
for(let i=0; i < findlongest.length; i++){
console.log(findlongest[i]);
}
if ( longest.length > findlongest.length) findlongest = longest;
}
console.log(longest);
document.getElementById("showResult1") = "Number of vowels: "+ longest;
<div id="LongWord" class="Tab">
<form id="Longestword">
<label>Enter text: <input name="text "></label>
<button type="button" onclick="fnLongestWord()"> Find longest word</button>
</form>
<!--here the output show-->
<p id="showResult1"></p>
</div>
Errors
;Here you are calling fnLongestWord but not passing any argument while fnLongestWord expects a value
var words = str.split(" "); str is no where defined inside the function
You need to put this line document.getElementById("showResult1") = "Number of vowels: "+ longest; inside the function and this is an invalid assingment. You need to use innerHTML and assign the value to it
function fnLongestWord(string) {
var str = document.getElementById('input').value || string
var words = str.split(" ");
var longest = words.sort((a, b) => {
return b.length - a.length;
})
document.getElementById("showResult1").innerHTML = "Number of vowels: " + longest[0];
}
<div id="LongWord" class="Tab">
<form id="Longestword">
<label>Enter text: <input id = 'input' name="text "></label>
<button type="button" onclick="fnLongestWord()"> Find longest word</button>
</form>
<!--here the output show-->
<p id="showResult1"></p>
</div>
You've got a few mistakes in your code that need fixing.
Firstly, you call fnLongestWord() when you click the button, thus you are not passing in the string from the form. You need to get the string from the form by using:
var str = document.getElementById('longestWord').value;
This will get the value (the text) of the element with the id longestWord. This will get the text from the textbox (as I've given it the id="longestWord")
Now you want to loop over your array of words. You can use words.length in the for loop to do this.
Next, you want to fix your if statement. Currently your syntax and logic are incorrect. Instead, you need to make it if(longest.length < words[i].length) longest = words[i]; which reads that if the longest word currently found is smaller than our current word, set the new longest word equal to the current word (word[i]).
Lastly, you're not adding the answer to the page correctly. Instead, you should do:
document.getElementById("showResult1").textContent += "Longest word is: " + longest;
To set the longest word into the showResult1 paragraph.
See working example below:
function fnLongestWord() {
var str = document.getElementById('longestWord').value;
var words = str.split(" ");
var longest = "";
for (let i = 0; i < words.length; i++) {
if (longest.length < words[i].length) longest = words[i];
}
document.getElementById("showResult1").textContent += "Longest word is: " + longest;
}
<div id="LongWord" class="Tab">
<form id="Longestword">
<label>Enter text: <input id="longestWord" name="text "></label>
<button type="button" onclick="fnLongestWord()"> Find longest word</button>
</form>
<!--here the output show-->
<p id="showResult1"></p>
</div>

Search entire DOM for number

I need to search my entire document for a phone number, and compile a list of elements which have this phone number in them.
However I have encountered afew snags.
I can't simply do document.body.innerHTML and replace the numbers, as this messes up third party scripts.
The following will match the elements, but ONLY if they have the number within them, and nothing else:
let elements = document.querySelectorAll("a, div, p, li");
let found = [];
for (let elm in elements) {
if (elements.hasOwnProperty(elm)) {
if (elements[elm].textContent !== undefined && elements[elm].textContent.search("00000 000000") != -1) {
found.push(elements[elm]);
}
}
}
So the following element will not match:
<li class="footer__telephone">
<i class="fa fa-phone" aria-hidden="true"></i>00000 000000
</li>
Due to having the i tag in there.
Using textContent instead of text also does not work as the parent of an element will then match, but I don't want the parent.
Edit:
<div class="row-block hmpg-text">
<div class="wrapper">
<div class="container">
<div class="row">
<div class="twelvecol">
00000 000000
</div>
</div>
</div>
</div>
</div>
Lets say the above is my HTML, if I loop through all the elements and test them with testContent then the first is going to be returned as true, to containing my number, but I need the element with the class of twelvecol on it, not the parent which is 4 levels up.
Managed to find an answer, similar to what Phylogenesis said however couldn't get any of them examples working.
function replaceText(el, regex_display, regex_link) {
// Replace any links
if (el.tagName === "A") {
if (regex_link.test(el.getAttribute("href"))) {
el.setAttribute("href", el.getAttribute("href").replace(regex_link, replacement.replace(/\s/g, '')));
}
}
if (el.nodeType === 3) {
if (regex_display.test(el.data)) el.data = el.data.replace(regex_display, replacement);
if (regex_link.test(el.data)) el.data = el.data.replace(regex_link, replacement);
} else {
let children = el.childNodes;
for (let i = 0; i < children.length; i++) {
replaceText(children[i], regex_display, regex_link);
}
}
}
let bodyChildren = document.body.childNodes;
let search_display = new RegExp(search, "g");
let search_link = new RegExp(search.replace(/\s/g, ''), "g");
for (let i = 0; i < bodyChildren.length; i++) {
replaceText(bodyChildren[i], search_display, search_link);
}

Categories

Resources