How do I preserve line breaks when getting text from a textarea?

JavascriptHtml

Javascript Problem Overview


I am getting the value in a textarea when the user hits submit. I then take this value and place it elsewhere on the page. However, when I do this, it loses newline characters making the output pretty ugly.

Here is the textarea I am accessing:

<textarea id="post-text" class="form-control" rows="3" placeholder="What's up?" required></textarea>

Here is the JavaScript code accessing the post and transcribing it.

var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.append(postText);
var card = document.createElement('div');
card.append(post);
var cardStack = document.getElementById('#card-stack');
cardStack.prepend(card);

When the input is something like:

> Group Schedule: > > Tuesday practice @ 5th floor (8 pm - 11 pm) > > Thursday practice @ 5th floor (8 pm - 11 pm) > > Sunday practice @ (9 pm - 12 am)

The output is:

> Group Schedule: Tuesday practice @ 5th floor (8 pm - 11 pm) Thursday practice @ 5th floor (8 pm - 11 pm) Sunday practice @ (9 pm - 12 am)

So is there a way to preserve line breaks?

Javascript Solutions


Solution 1 - Javascript

The easiest solution is to simply style the element you're inserting the text into with the following CSS property:

white-space: pre-wrap;

This property causes whitespace and newlines within the matching elements to be treated in the same way as inside a <textarea>. That is, consecutive whitespace is not collapsed, and lines are broken at explicit newlines (but are also wrapped automatically if they exceed the width of the element).

Given that several of the answers posted here so far have been vulnerable to HTML injection (e.g. because they assign unescaped user input to innerHTML) or otherwise buggy, let me give an example of how to do this safely and correctly, based on your original code:

document.getElementById('post-button').addEventListener('click', function () {
  var post = document.createElement('p');
  var postText = document.getElementById('post-text').value;
  post.append(postText);
  var card = document.createElement('div');
  card.append(post);
  var cardStack = document.getElementById('card-stack');
  cardStack.prepend(card);
});

#card-stack p {
  background: #ddd;
  white-space: pre-wrap;  /* <-- THIS PRESERVES THE LINE BREAKS */
}
textarea {
  width: 100%;
}

<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>


Note that, like your original code, the snippet above uses append() and prepend(). As of this writing, those functions are still considered experimental and not fully supported by all browsers. If you want to be safe and remain compatible with older browsers, you can substitute them pretty easily as follows:

  • element.append(otherElement) can be replaced with element.appendChild(otherElement);
  • element.prepend(otherElement) can be replaced with element.insertBefore(otherElement, element.firstChild);
  • element.append(stringOfText) can be replaced with element.appendChild(document.createTextNode(stringOfText));
  • element.prepend(stringOfText) can be replaced with element.insertBefore(document.createTextNode(stringOfText), element.firstChild);
  • as a special case, if element is empty, both element.append(stringOfText) and element.prepend(stringOfText) can simply be replaced with element.textContent = stringOfText.

Here's the same snippet as above, but without using append() or prepend():

document.getElementById('post-button').addEventListener('click', function () {
  var post = document.createElement('p');
  var postText = document.getElementById('post-text').value;
  post.textContent = postText;
  var card = document.createElement('div');
  card.appendChild(post);
  var cardStack = document.getElementById('card-stack');
  cardStack.insertBefore(card, cardStack.firstChild);
});

#card-stack p {
  background: #ddd;
  white-space: pre-wrap;  /* <-- THIS PRESERVES THE LINE BREAKS */
}
textarea {
  width: 100%;
}

<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>


Ps. If you really want to do this without using the CSS white-space property, an alternative solution would be to explicitly replace any newline characters in the text with <br> HTML tags. The tricky part is that, to avoid introducing subtle bugs and potential security holes, you have to first escape any HTML metacharacters (at a minimum, & and <) in the text before you do this replacement.

Probably the simplest and safest way to do that is to let the browser handle the HTML-escaping for you, like this:

var post = document.createElement('p');
post.textContent = postText;
post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n');

document.getElementById('post-button').addEventListener('click', function () {
  var post = document.createElement('p');
  var postText = document.getElementById('post-text').value;
  post.textContent = postText;
  post.innerHTML = post.innerHTML.replace(/\n/g, '<br>\n');  // <-- THIS FIXES THE LINE BREAKS
  var card = document.createElement('div');
  card.appendChild(post);
  var cardStack = document.getElementById('card-stack');
  cardStack.insertBefore(card, cardStack.firstChild);
});

#card-stack p {
  background: #ddd;
}
textarea {
  width: 100%;
}

<textarea id="post-text" class="form-control" rows="8" placeholder="What's up?" required>Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea><br>
<input type="button" id="post-button" value="Post!">
<div id="card-stack"></div>

Note that, while this will fix the line breaks, it won't prevent consecutive whitespace from being collapsed by the HTML renderer. It's possible to (sort of) emulate that by replacing some of the whitespace in the text with non-breaking spaces, but honestly, that's getting rather complicated for something that can be trivially solved with a single line of CSS.

Solution 2 - Javascript

The target container should have the white-space:pre style. Try it below.

<script>
function copycontent(){
 var content = document.getElementById('ta').value;
 document.getElementById('target').innerText = content;
}
</script>
<textarea id='ta' rows='3'>
  line 1
  line 2
  line 3
</textarea>
<button id='btn' onclick='copycontent();'>
Copy
</button>
<p id='target' style='white-space:pre'>

</p>

Solution 3 - Javascript

function get() {
  var arrayOfRows = document.getElementById("ta").value.split("\n");
  var docfrag = document.createDocumentFragment();
  
  var p = document.getElementById("result");
  while (p.firstChild) {
    p.removeChild(p.firstChild);
  }
  
  arrayOfRows.forEach(function(row, index, array) {
    var span = document.createElement("span");
    span.textContent = row;
    docfrag.appendChild(span);
    if(index < array.length - 1) {
      docfrag.appendChild(document.createElement("br"));
    }
  });

  p.appendChild(docfrag);
}

<textarea id="ta" rows=3></textarea><br>
<button onclick="get()">get</button>
<p id="result"></p>

You can split textarea rows into array:

var arrayOfRows = postText.value.split("\n");

Then use it to generate, maybe, more p tags...

Solution 4 - Javascript

Here is an idea as you may have multiple newline in a textbox:

 var text=document.getElementById('post-text').value.split('\n');
 var html = text.join('<br />');

This HTML value will preserve newline. Hope this helps.

Solution 5 - Javascript

You could set width of div using Javascript and add white-space:pre-wrap to p tag, this break your textarea content at end of each line.

document.querySelector("button").onclick = function gt(){
var card = document.createElement('div');
card.style.width = "160px";
card.style.background = "#eee";
var post = document.createElement('p');
var postText = document.getElementById('post-text').value;
post.style.whiteSpace = "pre-wrap";
card.append(post);
post.append(postText);
document.body.append(card);
}

<textarea id="post-text" class="form-control" rows="3" placeholder="What's up?" required>
Group Schedule:

Tuesday practice @ 5th floor (8pm - 11 pm)

Thursday practice @ 5th floor (8pm - 11 pm)

Sunday practice @ (9pm - 12 am)</textarea>
<br><br>
<button>Copy!!</button>

Solution 6 - Javascript

I suppose you don't want your textarea-content to be parsed as HTML. In this case, you can just set it as plaintext so the browser doesn't treat it as HTML and doesn't remove newlines No CSS or preprocessing required.

<script>
function copycontent(){
 var content = document.getElementById('ta').value;
 document.getElementById('target').innerText = content;
}
</script>
<textarea id='ta' rows='3'>
  line 1
  line 2
  line 3
</textarea>
<button id='btn' onclick='copycontent();'>
Copy
</button>
<p id='target'></p>

Solution 7 - Javascript

Similar questions are here

detect line breaks in a text area input

detect line break in textarea

You can try this:

var submit = document.getElementById('submit');

submit.addEventListener('click', function(){
var textContent = document.querySelector('textarea').value;
  
document.getElementById('output').innerHTML = textContent.replace(/\n/g, '<br/>');
  

});

<textarea cols=30 rows=10 >This is some text
this is another text

Another text again and again</textarea>
<input type='submit' id='submit'>


<p id='output'></p>

document.querySelector('textarea').value; will get the text content of the textarea and textContent.replace(/\n/g, '<br/>') will find all the newline character in the source code /\n/g in the content and replace it with the html line-break <br/>.


Another option is to use the html <pre> tag. See the demo below

var submit = document.getElementById('submit');

submit.addEventListener('click', function(){

  var content = '<pre>';
  
  var textContent = document.querySelector('textarea').value;
  
  content += textContent;
  
  content += '</pre>';

  document.getElementById('output').innerHTML = content;

});

<textarea cols=30 rows=10>This is some text
this is another text

Another text again and again </textarea>
<input type='submit' id='submit'>

<div id='output'> </div>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEthan Vander HornView Question on Stackoverflow
Solution 1 - JavascriptIlmari KaronenView Answer on Stackoverflow
Solution 2 - JavascriptStefano AltieriView Answer on Stackoverflow
Solution 3 - JavascriptkolodiView Answer on Stackoverflow
Solution 4 - JavascriptrezaView Answer on Stackoverflow
Solution 5 - JavascriptfrntView Answer on Stackoverflow
Solution 6 - JavascripttkauslView Answer on Stackoverflow
Solution 7 - JavascriptAbkView Answer on Stackoverflow