Textarea \n to <br> without escaping - javascript

I am entering stuff in a textarea, and after I press a button, my JS takes the textarea input and puts it inside a div tag.
The problem is, when I enter a newline in the textarea, like so:
Hi
Goodbye
It comes out in the div as
Hi<br><br>Goodbye
When I use Firebug to inspect the actual HTML markup live, I see this in the div:
Hi<br> <br> Goodbye
This is a function I found that should replace the newlines with breaktags:
function nl2br (str, is_xhtml) {
var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '\<br \/>' : '\<br>';
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1'+ breakTag +'$2');
}
Here is how I use it:
etext = $('#mytext').val();
etext = nl2br(etext,false);
$('#mydiv').text(etext);
However as you see, it is not working.
How can I do this? If you need more code, do let me know

Perhaps it will work if you do:
$('#mydiv').html(etext);
...or with no framework:
document.getElementById("mydiv").innerHTML = etext;
The problem is that text() is automatically escaping your markup characters:
We need to be aware that this method escapes the string provided as
necessary so that it will render correctly in HTML. To do so, it calls
the DOM method .createTextNode(), which replaces special characters
with their HTML entity equivalents (such as < for <).

Related

How to display special html characters properly via javascript

I'm using javascript to get some asp.net server variables to display them, problem is that if the have some html special character the string isn't being assigned as it's on server and it displays wrong.
For example the string :
`ALBERTO GÓMEZ SÁNCHEZ`
is displaying like
`ALBERTO GóMEZ SáNCHEZ`
I know I could use a Replace function but doing that for every possible special html character seems too time consuming... I guess there must be some built-in function that solves that easily but I cannot find it or an easier method than trying to replace every possible html special character.
Do you know any way? Thanks for your help.
If you want to decode html string use this way:
function decodeHTMLEntities (str) {
if(str && typeof str === 'string') {
// strip script/html tags
str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
element.innerHTML = str;
str = element.textContent;
element.textContent = '';
}
return str;
}
Taken from here: HTML Entity Decode
If you want do put this html string into your DOM, you don't need to decode it, the browser will do this job for you.
Just insert it like this:
$("body").html(encodedHtmlStringFromServer);

JQuery detect newline in a string

A "str" variable in JavaScript return by a backend contains a string with a few paragraphs separated by line breakers.. When I do this:
console.log(str);
the Firefox console displays:
"This is paragraph 1.
This is paragraph2.
This is paragraph3"
The problem is, this str is NOT separated by a "\n" character. It's just separated by invisible linebreaks, as you can see in the console output. Is there any way to detect this line break? What I'm eventually trying to do is replace these invisible line breaks with a "br" tag so that I can append it inside the html document..
Is there a way to do this?
Thanks
(Unfortunately, there is no way to change the backend..)
Take a look at nl2br on php.js which seems exactly what you're looking for. Basically, it's:
function nl2br (str, is_xhtml) {
var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2');
}
Demo : http://devilmaycode.altervista.org/jquery-convert-line-breaks-to-br-nl2br-equivalent/
var text = "This is paragraph 1.
This is paragraph2.
This is paragraph3";
var matches = text.match(/\n/g);
var new_lines = matches ? matches.length : 0; //Get no. of new line here
Demo
As an alternative thought (and if possible in your situation), because you essentially want to render the text in HTML with the line-breaks preserved, you can make use of CSS to do this for you. Take a look at the the white-space property with a value of pre-line or pre-wrap:
Sequences of whitespace will collapse into a single whitespace. Text will wrap when necessary, and on line breaks -
W3Schools
So, if you append the string to the DOM as a paragraph like:
<p class="preserveLineBreaks">This is paragraph 1.
This is paragraph2.
This is paragraph3<p>
Then with a simple CSS selector as follows, you'll get the expected result:
.preserveLineBreaks {
white-space: pre-line; //or pre-wrap
}
Actually, the "invisible line breaks" in the Firefox console are the \n characters. I've included a line to confirm this in the code below. In addition, browsers will generally ignore the \n character in favor of the <br/> and so the str variable that you have should display nicely as one line. To however identify the "\n" chars and replace them with <br />, try this
<span id="someText">This is
some text
that I need
to modify
</span>
<script>
var text = document.getElementById("someText") ;
alert(text.innerHTML.match(/\n/g).length) ; // confirm \n are in var
alert (text.innerHTML) ;
var withBRs = text.innerHTML.replace(/\n/g, "<br />") ;
text.innerHTML = withBRs ;
</script>

How can I add html in a div repeatedly, but keep pre-existing html?

Using Javascript of jQuery I want to swap a string of text for an html tag, over and over, without losing the previous html.
FIDDLE
<p>This is <i id="text">text</i> and more text</p>
This is text and more text
function rep() {
var t = $('p').text().replace('text', '<b>html</b>');
$('p').html(t);
}
Ideally it would look like:
<p>This is <i id="text"><b>html</b></i> and more <b>html</b></p>
This is html and more html
I DONT want to change the pre-existing html. <i id="text"> should remain in the html, no matter how many times I run the function. .html().replace(.. wouldn't work because it will grab the id="text". Thanks.
You need to get the old value using .html(), not .text(), since the latter leaves out all the HTML markup. You can do it in a single call, using a function to calculate the replacement from the old value:
function rep() {
$('p').html(function(i, oldhtml) {
return oldhtml.replace(/(<[^>]*)?text/g, function($0, $1) {
return $1 ? $0 : '<b>html</b>';
});
});
}
Notice that you have to use a regular expression with the g modifier to perform multiple replacements in a string. Negative lookbehind would be the normal way to exclude id="text", but this is not available. I used the workaround from Javascript: negative lookbehind equivalent?
Tell me if this code fits with your needs (I reuse input multiple times for convenience) :
function rep(input) {
input = RegExp.escape(input); // http://stackoverflow.com/q/3561493/1636522
input = new RegExp(input + '(?![^<]*?>)');
input = $('p').html().replace(input, '<b>html</b>');
$('p').html(input);
}
A little help about (?![^<]*?>) (roughly : "some text not followed by >") :
(?!...) not followed by
[^<]* any char except "<", zero or more times
?> until next ">"
More on regular expressions : http://www.javascriptkit.com/javatutors/redev.shtml.

Removing non-break-spaces in JavaScript

I am having trouble removing spaces from a string. First I am converting the div to text(); to remove the tags (which works) and then I'm trying to remove the "&nbsp" part of the string, but it won't work. Any Idea what I'm doing wrong.
newStr = $('#myDiv').text();
newStr = newStr.replace(/ /g, '');
$('#myText').val(newStr);
<html>
<div id = "myDiv"><p>remove space</p></div>
<input type = "text" id = "myText" />
</html>
When you use the text function, you're not getting HTML, but text: the entities have been changed to spaces.
So simply replace spaces:
var str = " a     b   ", // bunch of NBSPs
newStr = str.replace(/\s/g,'');
console.log(newStr)
If you want to replace only the spaces coming from do the replacement before the conversion to text:
newStr = $($('#myDiv').html().replace(/ /g,'')).text();
.text()/textContent do not contain HTML entities (such as ), these are returned as literal characters. Here's a regular expression using the non-breaking space Unicode escape sequence:
var newStr = $('#myDiv').text().replace(/\u00A0/g, '');
$('#myText').val(newStr);
Demo
It is also possible to use a literal non-breaking space character instead of the escape sequence in the Regex, however I find the escape sequence more clear in this case. Nothing that a comment wouldn't solve, though.
It is also possible to use .html()/innerHTML to retrieve the HTML containing HTML entities, as in #Dystroy's answer.
Below is my original answer, where I've misinterpreted OP's use case. I'll leave it here in case anyone needs to remove from DOM elements' text content
[...] However, be aware that re-setting the .html()/innerHTML of an element means trashing out all of the listeners and data associated with it.
So here's a recursive solution that only alters the text content of text nodes, without reparsing HTML nor any side effects.
function removeNbsp($el) {
$el.contents().each(function() {
if (this.nodeType === 3) {
this.nodeValue = this.nodeValue.replace(/\u00A0/g, '');
} else {
removeNbsp( $(this) );
}
});
}
removeNbsp( $('#myDiv') );
Demo

Value &# to unicode convert

I have lots of characters in the form ¶ which I would like to display as unicode characters in my text editor.
This ought to convert them:
var newtext = doctext.replace(
/&#(\d+);/g,
String.fromCharCode(parseInt("$1", 10))
);
But doesn't seem to work. The regular expression /&#(\d+);/ is getting me the numbers out -- but the String.fromCharCode does not appear to give the results I'd like. What is up?
The replacement part should be an anonymous function instead of an expression:
var newtext = doctext.replace(
/&#(\d+);/g,
function($0, $1) {
return String.fromCharCode(parseInt($1, 10));
}
);
The replace method is not foolproof, if you use full HTML (i.e. don't control what the input is). For example, the method submitted by Jack (and obviously the idea in the original post as well) works excellently if your entities are all decimal, but doesn't work for hex A, and even less for named entities like ".
For this, there is another trick you can do: create an element, set its innerHTML to the source, then read out its text value. Basically, browsers know what to do with entities, so we delegate. :) In jQuery it is easy:
$('<div/>').html('&').text()
// => "&"
With plain JS it gets a bit more verbose:
var el = document.createElement();
el.innerHTML = '&';
el.textContent
// => "&"

Categories

Resources