Why does getting value from data-attribute affect the text - javascript

I'm struggling with some syntax, mostly why the data-attribute(HTML5) is affecting the text in the way it is.
Please consider this example which does what is expected
<div id="s"></div>
<script>
var ele = document.getElementById("s");
var txt = "this is it \n and done";
ele.innerText = txt;
</script>
The result is I see 2 lines in HTML due to the \n. This is expected
The task means I need to change the way we work into
<div id="s" data-txt="this is it\nand done"></div>
<script>
var ele = document.getElementById("s");
var txt = ele.getAttribute("data-txt");
ele.innerText = txt;
</script>
Note we're now using the data attribute of data-txt. The issue is this renders the text verbatim, meaning I see 1 line: this is it\nand done
https://jsfiddle.net/he4ydvva/
The fact I can't even use replace (ele.getAttribute("data-txt").replace('\n','blah');) suggests that although I see \n, the computer is reading something different (maybe the charcode value or similar)
Why does this happen and how do I prevent it?
Edit
I have seen How can I insert new line/carriage returns into an element.textContent? but this won't suffice as I need the string to exist within the data-txt and concatenating as "this is " + String.fromCharCode(13) + " is not valid for HTML5

You are confusing HTML with JavaScript.
\n is a JavaScript character. data-* attributes are HTML. For inserting newline in HTML, you should use the HTML entity
(Newline) or 
 (carriage return) or their combination.
HTML doesn't understand \n, \r and so on.
Also note,
<div>This is a line \n Another one</div>
This won't insert newline but the code below will:
<div>This is a line
Another one</div>
Check out the full list of HTML entities

Here's what you should use:
ele = document.getElementById("t");
txt = ele.getAttribute("data-txt").replace(/\\n/g,'<br>');
ele.innerHTML = txt;
Explanation:
The \ char is an escape character and so to specify a new line, you need to use two \\ so that the 1st one escapes the meaning of the second. The second one is then treated as a normal char and is read together with the n as \n.
Further, you must replace that with a <br> because a browser will not respect CRLF chars.
Here is your example on jsfiddle fixed: https://jsfiddle.net/4eurrzgx/
var ele = document.getElementById("s");
var txt = "this is it \n and done";
ele.innerText = txt;
ele = document.getElementById("t");
txt = ele.getAttribute("data-txt").replace(/\\n/,'<br>');
ele.innerHTML = txt;
<div id="s"></div>
<p>
***
</p>
<div id="t" data-txt="this is it\nand done"></div>

Related

How to encode only part of this string and render html

I have a string myString="<pre class='ql-syntax'><code><html><body>Will this work?</body></html></code></pre>" which needs to be rendered in a webpage such that the content inside the <code> block is encoded so it shows up as is.
$('<div/>').html(htmlString).html() removes the html and body tags and outputs the following:
<pre class="ql-syntax"><code>Will this work?</code></pre>
What I want the output to be is:
<pre class="ql-syntax"><code><html>hello</html></code></pre>
so on the webpage, the entire content which is inside the code block renders.
How do I encode only the part of the myString which is between the <code> block?
I am fetching the myString from the database, so I don't have any control over how I construct the myString. I can manipulate it however I want to make sure the html inside the code block renders as is.
I suggest you want only
<code><html><body>Will this work?</body></html></code>
to be put to a pre. It's better you make a pre placeholder. Than just find it and set innerHtml. For example something like this:
<pre class="ql-syntax" id="code"></pre>
var pre = document.getElementById("code");
var codeLength = '<code>'.length;
var start = htmlString.indexOf('<code>');
var stop = htmlString.indexOf('</code>');
if (start != -1 && stop != -1 && stop > start)
pre.innerHtml = htmlString.substring(start+codeLength, stop-start-codeLength);
You can use String.prototype.match() with RegExp /(<pre?\s.+?>)|(<code>)|[^\1].+(?=<\/code>)/g to match "<pre" followed by space character followed by one or more characters followed by ">" or "<code>" or not previous capture group "<code>" followed by one or more characters followed by "</code>".
Create <div> element and append to document.body, call .shift() on array returned by .match() to get "<pre>", set div .innerHTML to result of .shift(); call .shift() to get "<code>" match, set as .innerHTML of div.firstChild : <pre>, call .shift(), set result as .textContent of div.firstChild.firstChild : <code>.
var str = `<pre class="ql-syntax"><code><html><body>Will this work?</body></html></code></pre>`;
var matches = str.match(/(<pre?\s.+?>)|(<code>)|[^\1].+(?=<\/code>)/g);
var div = document.createElement("div");
document.body.appendChild(div);
var pre = matches.shift();
div.innerHTML = pre;
var code = matches.shift();
div.firstChild.innerHTML = code;
var html = matches.shift();
div.firstChild.firstChild.textContent = html;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
If I understand your question, you need to HTML-encode the string within and including the <code> tags. See HTML-encoding lost when attribute read from input field
I'm not sure how you're constructing the string in the first place, but the code in the linked post should get you started. Perhaps something like this:
var newstring = "<pre class="ql-syntax">" + htmlEncode("<code><html><body>Will this work?</body></html></code>") + "</pre>";
Does this help?

How to write regex to remove whitespace between tag and words for HTMl minifier [duplicate]

This question already has answers here:
RegEx match open tags except XHTML self-contained tags
(35 answers)
Closed 7 years ago.
I am building a very simple HTML minifier. So far so good.
var file = process.argv[2],
html = "",
fs = require("fs");
html = fs.readFileSync(file, "utf8");
string = html.replace(/\n/g, "");
var x = string.replace(/[\t ]+\</g, "<");
var y = x.replace(/\>[\t ]+\</g, "><");
var z = y.replace(/\>[\t ]+$/g, ">");
console.log(z)
returns string: <div id="hello"><p class="new"> Hello</p></div>
How do I write a regex to get rid of any space that will appear between words and tags (before and after)? Should return: <div id="hello"><p class="new">Hello</p></div>
This should work for you:
var html = '<div id="hello"><p class="new"> Hello friend </p></div>';
var result = html.replace(/>\s+|\s+</g, function(m) {
return m.trim();
});
https://jsfiddle.net/5gbhhh25/
It will only remove spaces between a tag and a word (opening and closing). So it won't affect text in tags or spaces between text.
torazaburo makes a good point about a potential pitfall in OP's requirements where a single space is required to preserve the structure of the text. So Tushar's solution of str.replace(/\s+/g, ' '); would work perfectly in that case.
Replace any sequence of non-less-than-signs with a string which compresses multiple spaces within it to a single space:
str.replace(/[^<]+/g, function(match) { return match.replace(/\s+/, ' '); });
< "<div id="hello"><p class="new"> Hello</p></div>"
Of course, you don't want to get rid of the space before "Hello", because it is meaningful.
You can use the trim() method to get rid of empty space without regexp.
You can find an example on the W3Schooll web site
See :
var str = " Hello World! ";
alert(str.trim());

javascript remove last occurrence on a given string

How to convert the following using js regex replace or something:
var text = "line1<br>line2<br>line3<br>line4<br>"
...js regex...
so that text becomes:
text = "line1<br>line2<br>line3<br>";
of course the number of br varies, and each line length varies too
Removing just the last line without regular expressions:
var text = "line1<br>line2<br>line3<br>line4<br>";
var pieces = text.split('<br>');
var newText = pieces.splice(0, pieces.length-2).join('<br>') + '<br>';
Note that this code makes at least three important assumptions:
The separator is always <br> and not, say, <br /> or <BR>.
The input string always ends with a <br>.
The result string always ends with <br>, even if it's otherwise empty! (For example, if the input string is line1<br> then the output will be <br>.
Here is one that I am posing just because I took the time to make it. It works but needs index and null checks and such.
var text = "line1<br>line2<br>line3<br>line4<br>";
var newText = text.substring(0, text.substring(0, text.length - 4).lastIndexOf("<br>"));

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 to display text inside text area with line break instead of <br/> [duplicate]

I want to add a newline in a textarea. I tried with \n and <br/> tag but are not working. You can see above the HTML code. Can you help me to insert a newline in a textarea?
<textarea cols='60' rows='8'>This is my statement one.\n This is my statement2</textarea>
<textarea cols='60' rows='8'>This is my statement one.<br/> This is my statement2</textarea>
Try this one:
<textarea cols='60' rows='8'>This is my statement one.
This is my statement2</textarea>
Line Feed and 
 Carriage Return are HTML entitieswikipedia. This way you are actually parsing the new line ("\n") rather than displaying it as text.
Break enter Keyword line in Textarea using CSS:
white-space: pre-wrap;
I think you are confusing the syntax of different languages.
is (the HtmlEncoded value of ASCII 10 or) the linefeed character literal in a HTML string. But the line feed character does NOT render as a line break in HTML (see notes at bottom).
\n is the linefeed character literal (ASCII 10) in a Javascript string.
<br/> is a line break in HTML. Many other elements, eg <p>, <div>, etc also render line breaks unless overridden with some styles.
Hopefully the following illustration will make it clearer:
T.innerText = "Position of LF: " + t.value.indexOf("\n");
p1.innerHTML = t.value;
p2.innerHTML = t.value.replace("\n", "<br/>");
p3.innerText = t.value.replace("\n", "<br/>");
<textarea id="t">Line 1
Line 2</textarea>
<p id='T'></p>
<p id='p1'></p>
<p id='p2'></p>
<p id='p3'></p>
A few points to note about Html:
The innerHTML value of the TEXTAREA element does not render Html. Try the following: <textarea>A <a href='x'>link</a>.</textarea> to see.
The P element renders all contiguous white spaces (including new lines) as one space.
The LF character does not render to a new line or line break in HTML.
The TEXTAREA renders LF as a new line inside the text area box.
I've found String.fromCharCode(13, 10) helpful when using view engines.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode
This creates a string with the actual newline characters in it and so forces the view engine to output a newline rather than an escaped version. Eg: Using NodeJS EJS view engine - This is a simple example in which any \n should be replaced:
viewHelper.js
exports.replaceNewline = function(input) {
var newline = String.fromCharCode(13, 10);
return input.replaceAll('\\n', newline);
}
EJS
<textarea><%- viewHelper.replaceNewline("Blah\nblah\nblah") %></textarea>
Renders
<textarea>Blah
blah
blah</textarea>
replaceAll:
String.prototype.replaceAll = function (find, replace) {
var result = this;
do {
var split = result.split(find);
result = split.join(replace);
} while (split.length > 1);
return result;
};
<textarea cols='60' rows='8'>This is my statement one.
This is my statement2</textarea>
Fiddle showing that it works: http://jsfiddle.net/trott/5vu28/.
If you really want this to be on a single line in the source file, you could insert the HTML character references for a line feed and a carriage return as shown in the answer from #Bakudan:
<textarea cols='60' rows='8'>This is my statement one.
This is my statement2</textarea>
Try this. It works:
<textarea id="test" cols='60' rows='8'>This is my statement one.
This is my statement2</textarea>
Replacing for <br> tags:
$("textarea#test").val(replace($("textarea#test").val(), "<br>", "
")));
To get a new line inside text-area, put an actual line-break there:
<textarea cols='60' rows='8'>This is my statement one.
This is my statement2</textarea>
You might want to use \n instead of /n.
After lots of tests, following code works for me in Typescreipt
export function ReplaceNewline(input: string) {
var newline = String.fromCharCode(13, 10);
return ReplaceAll(input, "<br>", newline.toString());
}
export function ReplaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
}
You should also check the css white-space property (mdn docs) of your element, make sure it's set to a value that doesn't suppress line breaks, e.g.:
white-space: pre-line;
You'd be interested in these 3 values:
pre
Sequences of white space are preserved. Lines are only broken at
newline characters in the source and at <br> elements.
pre-wrap
Sequences of white space are preserved. Lines are broken at
newline characters, at <br>, and as necessary to fill line boxes.
pre-line Sequences of white space are collapsed. Lines are broken at
newline characters, at <br>, and as necessary to fill line boxes.
My .replace()function using the patterns described on the other answers did not work. The pattern that worked for my case was:
var str = "Test\n\n\Test\n\Test";
str.replace(/\r\n|\r|\n/g,'
');
// str: "Test
Test
Test"
T.innerText = "Position of LF: " + t.value.indexOf("\n");
p3.innerText = t.value.replace("\n", "");
<textarea id="t">Line 1
Line 2</textarea>
<p id='p3'></p>
If you are using react
Inside the function
const handleChange=(e)=>{
const name = e.target.name;
let value = e.target.value;
value = value.split('\n').map(str => <span>{str}<br/></span>);
SetFileds({ ...fileds, [name]: value });
}
A simple and natural solution not involving CSS styles or numeric character references like
would be to use the &NewLine; character entity reference:
The cardinal directions are:&NewLine;- North&NewLine;- East&NewLine;- South&NewLine;- West
Note: Since this is defined simply as the LF (line feed, or the U+000A Unicode code point) character, it's not 100% certain whether it suits situations where the entire CR + LF (carriage return + line feed) sequence is required. But then, it worked in my Chrome, Edge and WebView2 tests done on Windows 10, so it should be ok to use.
just use <br>
ex:
<textarea>
blablablabla <br> kakakakakak <br> fafafafafaf
</textarea>
result:
blablablabla kakakakakak fafafafafaf

Categories

Resources