Writing line breaks to a <span> element using JavaScript? - javascript

My goal is to take an array, and write each element onto a HTML page using a <span> element with .textContent using a for loop. Only problem is that instead of:
Error1
Error2
I get:
Error1<br/>Error2<br/>
HTML code:
<p><span id="EBox"></span></p>
JS code:
var EBox = document.getElementById("EBox");
var eArray = []; //Elements get added via push
for (var i = 0; i < eArray.length; i++) {
EBox.textContent = EBox.textContent + eArray[i] + '<br/>';
}
The entire system works, but it just ends up as one jumbled sentence. What can I change to make it add the line breaks? I've tried '<br>', '<br />' and '\n' with similar results.

Use .innerHTML .insertAdjacentHTML instead of .textContent as .textContent does not parse the HTML <br> but simply outputs it as text.
Also if you're appending to the HTML each time, it's better to use .insertAdjacentHTML as it does not reparse the previous HTML, thus making it much faster and less error prone than .innerHTML.
var strArr = ['foo', 'bar'];
strArr.forEach(function(str) {
document.querySelector('div').insertAdjacentHTML('beforeend', str + '<br>');
});
<div></div>

Instead of .textContent use .innerHTML.
I would also recommend building up a string first before using .innerHTML so the DOM isn't rebuilt each time...
var EBox = document.getElementById("EBox");
var eArray = []; //Elements get added via push
var html = "";
for (var i = 0; i < eArray.length; i++) {
html += eArray[i] + '<br/>';
}
EBox.innerHTML = html;

I found a better answer here:
https://developer.mozilla.org/pt-BR/docs/Web/CSS/word-break
You can use CSS to do this, see below:
span{word-break: break-word;}
or
span{word-break: break-all;}
BREAKE-WORD will put the next word in a new line and BREAKE-ALL will break the text justifying the content, when it gets bigger than the div or span container.
I hope I'd help :)

Related

How to append in get HTML

I am trying get a html() in jQuery and append it to some DOM elements but unable to. Please go through the for loop as that is where the error is occurring:
$(function() {
let fig = $("figure").html();
$("#search-btn").click(function() {
let content = $("#search-input").val();
var i;
for (i = 0; i < content; i++) {
$("#photos").html() += `<figure>` + fig;
}
});
});
you can use append() and prepend()
please go throw it, it may help you.
$("#photos").append(`<figure>` + fig;)
https://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_html_append2
Try this:
$("#photos").html($("#photos").html() + '<figure>' + fig);
Sample
Declare variable and generate markup and finally append that markup using html().
var html = "";
for (i = 0; i < content; i++) {
html += `<figure>` + fig;
}
$("#photos").html(html);
You can use either Template Literals or concatenation as usual. Template Literal are great, but the only downside is compatibility [ECMAScript6 only].
Using Template Literal will be like this,
$("#photos").append(`<figure> ${fig}`);
Using concatenation will be like this,
$("#photos").append('<figure>' + fig);
to fix error use
$("#photos").append($('<figure>').html(fig))
.append() - adds element as last to selected element
$('<figure>') - create jQuery element with tag name "figure"
.html(fig) - fill jQuery element with passed string as html
NEVER override jQuery's html $("#id").html($("#id").html() + addedHtml) , because You break events on inner elements
also:
$("#search-input").val() returns type string
to use it in cicle, you must convert value to number: +$("#search-input").val() - added "+" as easy way, also see "JS parseInt()"

Javascript - How can I replace text in HTML with text in script

I am new to javascript. I was thinking getelementbyid but i don't know how to make it work
Like the title, here is what I mean
For example I have in HTML:
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
So what I want is to make script to replace those fw_93 fw_94 to what I want.
For example
Instead of displaying "fw_93" I want it to display "9.3". Same with fw_94 to 9.4
Replace fw_ with nothing, divide the number by 10:
Array.prototype.forEach.call(document.getElementsByTagName('p'), function(el) {
el.innerHTML = parseInt(el.innerHTML.replace(/[A-Za-z_]*/, '')) / 10;
});
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
Okay so select the tags.
Loop over the collection
read the html
match the string
replace the html
var ps = document.querySelectorAll("p");
for (var i=0; i<ps.length; i++) {
var p = ps[i];
var txt = p.innerHTML; //.textContent
var updated = txt.replace(/.+(\d)(\d)/, "$1.$2");
p.innerHTML = updated;
}
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
Using JQuery
Not sure why I did it with JQuery, guess I wasn't paying enough attention. No point in me re-writing as there are already good answers in JS. Though I will leave this in case it's of use to anyone that is using JQuery.
You can loop though each <p> element and covert the contents, something like this:
$("p").each(function() {
var text = $(this).html();
var text = text.substring(text.indexOf("_") + 1);
var text = text[0] + "." + text.substring(1);
$(this).html(text);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
You may need to add validation depending on how reliable your input is.
Note that the code makes the following assumptions:
There will always be a _ followed by at least 2 digits
The . will always go after the first digit
Your HTML:
<p id="p1">init_value</p>
Your JS:
document.getElementById("p1").innerHTML = "new_value";

JavaScript RegExp match text ignoring HTML

Is it possible to match "the dog is really really fat" in "The <strong>dog</strong> is really <em>really</em> fat!" and add "<span class="highlight">WHAT WAS MATCHED</span>" around it?
I don't mean this specifically, but generally be able to search text ignoring HTML, keeping it in the end result, and just add the span above around it all?
EDIT:
Considering the HTML tag overlapping problem, would it be possible to match a phrase and just add the span around each of the matched words? The problem here is that I don't want the word "dog" matched when it's not in the searched context, in this case, "the dog is really really fat."
Update:
Here is a working fiddle that does what you want. However, you will need to update the htmlTagRegEx to handle matching on any HTML tag, as this just performs a simple match and will not handle all the cases.
http://jsfiddle.net/briguy37/JyL4J/
Also, below is the code. Basically, it takes out the html elements one by one, then does a replace in the text to add the highlight span around the matched selection, and then pushes back in the html elements one by one. It's ugly, but it's the easiest way I could think of to get it to work...
function highlightInElement(elementId, text){
var elementHtml = document.getElementById(elementId).innerHTML;
var tags = [];
var tagLocations= [];
var htmlTagRegEx = /<{1}\/{0,1}\w+>{1}/;
//Strip the tags from the elementHtml and keep track of them
var htmlTag;
while(htmlTag = elementHtml.match(htmlTagRegEx)){
tagLocations[tagLocations.length] = elementHtml.search(htmlTagRegEx);
tags[tags.length] = htmlTag;
elementHtml = elementHtml.replace(htmlTag, '');
}
//Search for the text in the stripped html
var textLocation = elementHtml.search(text);
if(textLocation){
//Add the highlight
var highlightHTMLStart = '<span class="highlight">';
var highlightHTMLEnd = '</span>';
elementHtml = elementHtml.replace(text, highlightHTMLStart + text + highlightHTMLEnd);
//plug back in the HTML tags
var textEndLocation = textLocation + text.length;
for(i=tagLocations.length-1; i>=0; i--){
var location = tagLocations[i];
if(location > textEndLocation){
location += highlightHTMLStart.length + highlightHTMLEnd.length;
} else if(location > textLocation){
location += highlightHTMLStart.length;
}
elementHtml = elementHtml.substring(0,location) + tags[i] + elementHtml.substring(location);
}
}
//Update the innerHTML of the element
document.getElementById(elementId).innerHTML = elementHtml;
}
Naah... just use the good old RegExp ;)
var htmlString = "The <strong>dog</strong> is really <em>really</em> fat!";
var regexp = /<\/?\w+((\s+\w+(\s*=\s*(?:\".*?"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/gi;
var result = '<span class="highlight">' + htmlString.replace(regexp, '') + '</span>';
A simpler way with JQuery would be.
originalHtml = $("#div").html();
newHtml = originalHtml.replace(new RegExp(keyword + "(?![^<>]*>)", "g"), function(e){
return "<span class='highlight'>" + e + "</span>";
});
$("#div").html(newHtml);
This works just fine for me.
Here is a working regex example to exclude matches inside html tags as well as javascripts:
http://refiddle.com/lwy6
Use this regex in a replace() script.
/(a)(?!([^<])*?>)(?!<script[^>]*?>)(?![^<]*?<\/script>|$)/gi
this.keywords.forEach(keyword => {
el.innerHTML = el.innerHTML.replace(
RegExp(keyword + '(?![^<>]*>)', 'ig'),
matched => `<span class=highlight>${matched}</span>`
)
})
You can use string replace with this expression </?\w*> and you'll get your string
If you use jQuery, you can use the text property on the element containing the text you're searching for. Given this markup:
<p id="the-text">
The <strong>dog</strong> is really <em>really</em> fat!
</p>
This would yield "The dog is really really fat!":
$('#the-text').text();
You could do your regex search on that text instead of trying to do so in the markup.
Without jQuery, I'm unsure of an easy way to extract and concatenate the text nodes from all child elements.

jQuery issue with editing heading tags using html()

Basically I have a load of H1 H2 and H3 tags on a website and I want to be able to put a span around PART of these heading tags.
At the moment I have this:
jQuery(document).ready(function(){
// get all headings first
jQuery('h1, h2, h3').each(function(){
// get the text
var theHtml = jQuery(this).html();
// split by spaces
var theWords = theHtml.split(" ");
// count the words
var wordCount = theWords.length;
var newHtml;
if(wordCount < 2){
// only one word
newHtml = theHtml;
}
else if(wordCount == 2){
// word count is 2...
newHtml = theWords[0]+" <span style='color: #000'>"+theWords[1]+"</span>";
}
else {
// add the first two words:
newHtml = theWords[0]+" "+theWords[1]+" <span style='color:#000'>";
// need to loop through the array now
for(var i = 2; i<wordCount; i++){
newHtml = newHtml+theWords[i];
if(i+1 < wordCount){
newHtml = newHtml+" ";
}
}
//end
newHtml = newHtml+"</span>";
}
jQuery(this).html(newHtml);
});
});
Which works quite well. But now I have a problem which is sometimes there is an a element or a div (for an inline editor if logged in as an admin) in the titles which is breaking this...
How would I get around this? I need to potentially get all the html from the header tag, strip the HTML tags, add the span around the latter part, then put the html back in!
Any ideas?
Thank you.
Edit:
This is what the problematic html looks like:
<h1 class="entry-title"><div data-type="input" data-post_id="12" class="fee-field fee-filter-the_title">Bristish Society of Blood and Marrow Transplantation</div></h1>
And like this:
<h2 class="entry-title"><div data-type="input" data-post_id="62" class="fee-field fee-filter-the_title">About the Registry</div></h2>
But if not logged in as an administrator then the div's go away.
Hey! Nice one, I think this is possible with regular expressions. I made a quick example for you, covering the a and the div for the biggest part. All spaces that are not meant as real whitespaces (in the tags) are replaced with symbols like ___ or ---, which are changed back afterwards.
Take a look at this jsfiddle!
theHtml = theHtml.replace(/[\s]+\</gi,'<');
theHtml = theHtml.replace(/\s+[\'\"]/gi,'___');
theHtml = theHtml.replace(/[\'\"]\s+/gi,'---');
theHtml = theHtml.replace(/a\s/gi,'a_');
theHtml = theHtml.replace(/div\s/gi,'div_');
and backwards:
newHtml = newHtml.replace(/___/gi,' "');
newHtml = newHtml.replace(/---/gi,'" ');
newHtml = newHtml.replace(/div_/gi,'div ');
newHtml = newHtml.replace(/a_/gi,'a ');
COMMENT after your edit
This will not work for the example h1 and h2 you posted. This is just an idea of how to approach this. I hope this will help you! Good luck!
COMMENT2 after my own edit ;-)
It does work, I just forgot to add case insensitivity and recursivity! It's just not finished yet. There are more checks needed such as ' or " etc. Here you go, I hope this will get you on the right track.
Please use the jQuery .text() function to strip out all the text within any particular H1, H2 tags etc. Other HTML inside these tags will be ignored.
But, i'm not sure how you will restore all the Inner HTML tags back.
Have you tried jQuery's wrapInner() function? I think it does what you're looking for in just one line.
$('h1, h2, h3').wrapInner('<span></span>');
If you know what class will be in the "inner" HTML element, you can just grab that.
var outer = $('.entry-title');
var html = html.find('.fee-field');
if(html === null){
html = outer;
}
// html will either be your `h` element or your inner most element.

Replace Text with Image - JavaScript (getElementsByClass)

I have a span:
<span class="attr attr-value">Brand Name</span>
And I want to replace that text with an image, based on the text
Here is what I have:
<script type="text/javascript">
var oldHTML = document.getElementsByClass('attr-value').innerHTML;
var filename = oldHTML.toLowerCase().replace(/ /g, '-').replace(/([^0-9a-z-])/g,'');
var newHTML = "<img src='http://www.example.com/" + filename + ".jpg'>";
document.getElementsByClass('attr-value').innerHTML = newHTML;
</script>
What am I doing wrong here?
This line is an issue:
var oldHTML = document.getElementsByClass('attr-value').innerHTML;
document.getElementsByClass should be document.getElementsByClassName, and it returns a NodeList, which doesn't have an innerHTML property. You'd want to loop through the NodeList to look at the innerHTML of each element.
Something like this (live example):
<script type="text/javascript">
(function() {
var list, index, element, filename;
list = document.getElementsByClassName('attr-value');
for (index = 0; index < list.length; ++index) {
element = list[index];
filename = element.innerHTML.toLowerCase().replace(/ /g, '-').replace(/([^0-9a-z-])/g,'');
element.innerHTML = "<img src='http://www.example.com/" + filename + ".jpg'>";
}
})();
</script>
Changes:
Put the whole thing in an anonymous function and immediately execute that function, to avoid creating global symbols.
Use the correct getElementsByClassName
Loop through them
Operate on the innerHTML of each element.
Notes:
IE doesn't have getElementsByClassName, so you'll want to be sure you're loading a script that provides it on IE. That's not provided in the live example above, use Firefox, Chrome, or Opera. (Just search for "getElementsByClassName for IE" and you'll find several implementations to choose from.)
The above script tag will need to be placed after all of the elements you want to process in the HTML file.
class="attr attr-value" and you're calling
document.getElementsByClass('attr-value').innerHTML
document.getElementsByClassName();
It should be, (e.g)
document.getElementsByClassName('attr-value')[0];

Categories