Why does my script not make new lines using keyup? - javascript

I'm coding a script for my forum which generates a preview of the given string.
Here is my js code
function MakePreview() {
var getText = document.getElementById('inputText').value;
document.getElementById('outputText').innerHTML = getText;}
Here is my HTML code
<article>
<h2>What are you doing?</h2>
<textarea id="inputText" onkeyup="MakePreview()"></textarea>
<br/>
<input type="submit" class="button" value="Hello"/>
</article>
<article>
<p id="outputText"></p>
</article>
Furthermore I have an textarea for the input and an paragraph for the output. But the output does not make a new line like textareas does.
Usually a paragraph makes automatically new lines when the string is longer than the width of the given content.
Does someone have a solution?
Thanks in advance

I'm not sure, if it's possible to achieve exactly what you want (due to the different font size and family), but this snippet is very close to it.
function makePreview() {
var text = document.getElementById('inputText').value;
document.getElementById('outputText').innerHTML = text;
}
.wrapper {
width: 150px;
}
.wrapper textarea {
width: 100%;
}
#outputText {
position: relative;
white-space: pre-wrap;
word-break: break-all;
border: 1px solid #ccc;
}
<div class="wrapper">
<textarea id="inputText" oninput="makePreview()"></textarea>
<p id="outputText"></p>
</div>
The idea is to wrap both the textarea and the p within a same parent to get their widths to match. word-break: break-all and white-space: pre-wrap "copies" the automatic text wrapping and entered new-lines within textarea to the p element.
However, the text might be cutted in a different place, depending on the used font family and size. You could get a better match if you'd use the same font in both elements.

You can instruct paragraph to respect new lines characters (and other whitespaces like tabs, spaces, etc.) by setting its white-space property to pre:
function MakePreview() {
var getText = document.getElementById('inputText').value;
document.getElementById('outputText').innerHTML = getText;
}
#outputText {
white-space: pre;
}
<textarea id="inputText" onkeyup="MakePreview()" rows="4" cols="20"></textarea>
<p id="outputText"></p>

In html multiple whitespaces are replaced by single space so if you want to preview in paragraph you need to replace newlines with <br/>
function MakePreview() {
var getText = document.getElementById('inputText').value;
document.getElementById('outputParagraph').innerHTML = getText.replace('\n', '<br/>');
}

Use wrap="hard" on your textArea. It will help for new line if the length is more the textArea size.
For fixed row and column you can use rows="2" cols="20" in textarea.

Related

Displaying text in textarea with formatting in place (e.g. <br>)

How can I display a wall of text example:
hello
<br>
how is your day
<br>
123
Into
hello
how is your day
123
I'm trying to display these into a textarea field as well.
I've tried with this
$('<textarea />').html(theString).text(); but it does not display my desired result
Edit:
Current code:
function displayCustom (data) {
var myString= data.getAttribute("data-contentDetails");
$('#textareaContent").html(myString);
}
this is not possible to do this with textarea. you can use content editable div
var theString = `Hello.<br>Hi.<br>Hey, <strong>user</strong> <span style="color: red">Logout</span>.`
// in pure js
document.getElementById('textareaContent').innerHTML = theString;
// OR in jQuery
$('#textareaContent').html(theString)
div {
width: 250px;
height: 150px;
border: 1px solid #ababab;
padding: 8px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="textareaContent" contenteditable="true"></div>
UPDATE
if you have to use textarea and just need to use <br /> (you couldn't use another HTML tag as a text) you can use:
var myString = `Hello<br>Hi<br>Hey, use`
$('#text').html(myString.replace(/<br>/g, '\n'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="text"></textarea>
Use a Div with a contenteditable attribute if you want the user to edit the displayed new format. Try to append or insert this.
For a textarea
$('<div contenteditable="true" />').html(theString);
Just remove the contendeditable="true" attribute if you just want to display the new format.

How to get the same text from these 2 contenteditable divs with the same content but different structures?

Here's the thing:
Contenteditables are bad. Firefox handles it with something like the div1 and Chrome does it like div2.
Both have the same text content (as from the user's perspective), but they're structured in different ways.
When I get both text contents with innerText, I get back different results, because of the way they're structured.
Is there a way to get those texts and get back the same string (since they produce the exact same text on screen)?
Something like:
div1 = div2 = "Line1\nLine2\n\nLine3\n\n\nLine4" (in fact, that's the div1 result, since it's composed only by text and breaks). div2 is the problem, in this case.
The pseudo code of what I need:
"Get my the text content of these div with the number of breaks based on what is being shown on the screen."
Final goal:
To paste new text consistently across both structures I need a way to handle them in the same way.
const div1 = document.getElementById('div1');
const div2 = document.getElementById('div2');
const p1 = document.getElementById('p1');
const p2 = document.getElementById('p2');
p1.innerText = JSON.stringify(div1.innerText);
p2.innerText = JSON.stringify(div2.innerText);
#div1 {
border: 1px dotted blue;
}
#div2 {
margin-top: 40px;
border: 1px dotted red;
}
<div id="div1" contenteditable>
Line1
<br>
Line2
<br>
<br>
Line3
<br>
<br>
<br>
Line4
</div>
<p><b>Div1 innerText:</b></p>
<p id="p1"></p>
<div id="div2" contenteditable>
<div>Line1</div>
<div>Line2</div>
<div><br></div>
<div>Line3</div>
<div><br></div>
<div><br></div>
<div>Line4</div>
</div>
<p><b>Div2 innerText:</b></p>
<p id="p2"></p>
I suggested you in comments to transform your <div>'s content into a <textarea> element. This solution avoids behavior difference between Firefox and Chrome.
Here is below a simple example about how it can be achieved. I guess you will be able to adapt it with what you want exactly (switching <p> to <div> for instance).
const contentEditable = document.querySelector('#content-editable'),
htmlPreview = document.querySelector('#html-preview');
htmlPreview.innerText = contentEditable.innerHTML;
contentEditable.addEventListener('click', contentEditableHtmlToTextarea);
/**
* Converts HTML of #content-editable into <textarea>.
*/
function contentEditableHtmlToTextarea() {
const textarea = document.createElement('textarea'),
height = contentEditable.offsetHeight;
// Converts <p> tags to \r\n.
textarea.value = this.innerHTML
.replace(/^\s*/gm, '')
.replace(/<p>(.*?)<\/p>/g, '$1\r\n')
.trim();
// Updates #content-editable HTML.
this.innerHTML = '';
this.appendChild(textarea);
textarea.style.height = `${height}px`;
htmlPreview.style.display = 'none';
this.removeEventListener('click', contentEditableHtmlToTextarea);
// A bit tricky, but without timeout, the callback is directly called.
setTimeout(() => {
document.addEventListener('click', contentEditableTextareaToHtml);
}, 0);
}
/**
* Converts <textarea>'s value into HTML for #content-editable.
*/
function contentEditableTextareaToHtml(e) {
const textarea = contentEditable.querySelector('textarea'),
// Converts lines into <p> tags.
html = textarea.value.replace(/^(.+?)$/gm, '<p>$1</p>');
// Checks if the mouse click is outside the <textarea>.
if (e.target !== textarea) {
// Updates #content-editable HTML.
textarea.remove();
contentEditable.innerHTML = html;
htmlPreview.innerText = contentEditable.innerHTML;
htmlPreview.style.display = 'block';
document.removeEventListener('click', contentEditableTextareaToHtml);
contentEditable.addEventListener('click', contentEditableHtmlToTextarea);
}
}
div {
padding: 3px;
border: 1px solid #000;
}
textarea {
margin: 0 auto;
display: block;
width: 98%;
}
<div id="content-editable">
<p>Line 1</p>
<p>Line 2</p>
<p>Line 3</p>
</div>
<pre id="html-preview"></pre>

Button highlighting not working inside textarea [duplicate]

I need to be able to render some HTML tags inside a textarea (namely <strong>, <i>, <u>, <a>) but textareas only interpret their content as text. Is there an easy way of doing it without relying on external libraries/plugins (I'm using jQuery)?
If not, do you know of any jQuery plugin I could use to do this?
This is not possible to do with a textarea. You are looking for a content editable div, which is very easily done:
<div contenteditable="true"></div>
jsFiddle
div.editable {
width: 300px;
height: 200px;
border: 1px solid #ccc;
padding: 5px;
}
strong {
font-weight: bold;
}
<div contenteditable="true">This is the first line.<br>
See, how the text fits here, also if<br>there is a <strong>linebreak</strong> at the end?
<br>It works nicely.
<br>
<br><span style="color: lightgreen">Great</span>.
</div>
With an editable div you can use the method document.execCommand (more details) to easily provide the support for the tags you specified and for some other functionality...
#text {
width: 500px;
min-height: 100px;
border: 2px solid;
}
<div id="text" contenteditable="true"></div>
<button onclick="document.execCommand('bold');">toggle bold</button>
<button onclick="document.execCommand('italic');">toggle italic</button>
<button onclick="document.execCommand('underline');">toggle underline</button>
Since you only said render, yes you can. You could do something along the lines of this:
function render(){
var inp = document.getElementById("box");
var data = `
<svg xmlns="http://www.w3.org/2000/svg" width="${inp.offsetWidth}" height="${inp.offsetHeight}">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml"
style="font-family:monospace;font-style: normal; font-variant: normal; font-size:13.3px;padding:2px;;">
${inp.value} <i style="color:red">cant touch this</i>
</div>
</foreignObject>
</svg>`;
var blob = new Blob( [data], {type:'image/svg+xml'} );
var url=URL.createObjectURL(blob);
inp.style.backgroundImage="url("+URL.createObjectURL(blob)+")";
}
onload=function(){
render();
ro = new ResizeObserver(render);
ro.observe(document.getElementById("box"));
}
#box{
color:transparent;
caret-color: black;
font-style: normal;/*must be same as in the svg for caret to align*/
font-variant: normal;
font-size:13.3px;
padding:2px;
font-family:monospace;
}
<textarea id="box" oninput="render()">you can edit me!</textarea>
This makes it so that a textarea will render html!
Besides the flashing when resizing, inability to directly use classes and having to make sure that the div in the svg has the same format as the textarea for the caret to align correctly, it's works!
Try this example:
function toggleRed() {
var text = $('.editable').text();
$('.editable').html('<p style="color:red">' + text + '</p>');
}
function toggleItalic() {
var text = $('.editable').text();
$('.editable').html("<i>" + text + "</i>");
}
$('.bold').click(function() {
toggleRed();
});
$('.italic').click(function() {
toggleItalic();
});
.editable {
width: 300px;
height: 200px;
border: 1px solid #ccc;
padding: 5px;
resize: both;
overflow: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="editable" contenteditable="true"></div>
<button class="bold">toggle red</button>
<button class="italic">toggle italic</button>
An addendum to this: You can use character entities (such as changing <div> to <div>) and it will render in the textarea.
But when it is saved, the value of the textarea is the text as rendered. So you don't need to de-encode. I just tested this across browsers (Internet Explorer back to version 11).
I have the same problem but in reverse, and the following solution. I want to put html from a div in a textarea (so I can edit some reactions on my website; I want to have the textarea in the same location.)
To put the content of this div in a textarea I use:
var content = $('#msg500').text();
$('#msg500').wrapInner('<textarea>' + content + '</textarea>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="msg500">here some <strong>html</strong> <i>tags</i>.</div>
This is possible with <textarea>.
You only need to use the Summernote WYSIWYG editor.
It interprets HTML tags inside a textarea (namely <strong>, <i>, <u>, and <a>).

Make text in paraghapghs in div overflow instead of new lines

Say I have several pretty longs lines in a paragraph:
<div style="overflow: auto">
<p>
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccc
</p>
<p>
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccc
</p>
</div>
and window width less that width of the pahagraph (a's + b's + c's). Currently scroll will appear only if width of any of components (a, b, or c) is more that width of the window and over components are carried to the new lines. I want contents of each paragraph appear on the same line with a scroll. How can I treat each paraghaph as a string, so contents of the paragraph is treated like a single line?
With CSS you can do:
p {
white-space: nowrap;
overflow: auto
}
This make the spaces non-breaking, so the paragraph will all be on one line.
You can set white-space:nowrap and overflow:auto property of css. You can assign a class to paragraph tag for which you want text on single line.
CSS
.className {
white-space: nowrap;
overflow: auto;
}
Html
<div style="overflow: auto">
<p class="className">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccc
</p>
<p class="className">
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccc
</p>
</div>
Either add styles as below
p{
overflow:auto;
white-space: nowrap;
}
or use jQuery as below
$('p').css('overflow','auto');
$('p').css('white-space','nowrap');
Here is a live fiddle example http://jsfiddle.net/mayooresan/qmCwL/

Rendering HTML inside textarea

I need to be able to render some HTML tags inside a textarea (namely <strong>, <i>, <u>, <a>) but textareas only interpret their content as text. Is there an easy way of doing it without relying on external libraries/plugins (I'm using jQuery)?
If not, do you know of any jQuery plugin I could use to do this?
This is not possible to do with a textarea. You are looking for a content editable div, which is very easily done:
<div contenteditable="true"></div>
jsFiddle
div.editable {
width: 300px;
height: 200px;
border: 1px solid #ccc;
padding: 5px;
}
strong {
font-weight: bold;
}
<div contenteditable="true">This is the first line.<br>
See, how the text fits here, also if<br>there is a <strong>linebreak</strong> at the end?
<br>It works nicely.
<br>
<br><span style="color: lightgreen">Great</span>.
</div>
With an editable div you can use the method document.execCommand (more details) to easily provide the support for the tags you specified and for some other functionality...
#text {
width: 500px;
min-height: 100px;
border: 2px solid;
}
<div id="text" contenteditable="true"></div>
<button onclick="document.execCommand('bold');">toggle bold</button>
<button onclick="document.execCommand('italic');">toggle italic</button>
<button onclick="document.execCommand('underline');">toggle underline</button>
Since you only said render, yes you can. You could do something along the lines of this:
function render(){
var inp = document.getElementById("box");
var data = `
<svg xmlns="http://www.w3.org/2000/svg" width="${inp.offsetWidth}" height="${inp.offsetHeight}">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml"
style="font-family:monospace;font-style: normal; font-variant: normal; font-size:13.3px;padding:2px;;">
${inp.value} <i style="color:red">cant touch this</i>
</div>
</foreignObject>
</svg>`;
var blob = new Blob( [data], {type:'image/svg+xml'} );
var url=URL.createObjectURL(blob);
inp.style.backgroundImage="url("+URL.createObjectURL(blob)+")";
}
onload=function(){
render();
ro = new ResizeObserver(render);
ro.observe(document.getElementById("box"));
}
#box{
color:transparent;
caret-color: black;
font-style: normal;/*must be same as in the svg for caret to align*/
font-variant: normal;
font-size:13.3px;
padding:2px;
font-family:monospace;
}
<textarea id="box" oninput="render()">you can edit me!</textarea>
This makes it so that a textarea will render html!
Besides the flashing when resizing, inability to directly use classes and having to make sure that the div in the svg has the same format as the textarea for the caret to align correctly, it's works!
Try this example:
function toggleRed() {
var text = $('.editable').text();
$('.editable').html('<p style="color:red">' + text + '</p>');
}
function toggleItalic() {
var text = $('.editable').text();
$('.editable').html("<i>" + text + "</i>");
}
$('.bold').click(function() {
toggleRed();
});
$('.italic').click(function() {
toggleItalic();
});
.editable {
width: 300px;
height: 200px;
border: 1px solid #ccc;
padding: 5px;
resize: both;
overflow: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="editable" contenteditable="true"></div>
<button class="bold">toggle red</button>
<button class="italic">toggle italic</button>
An addendum to this: You can use character entities (such as changing <div> to <div>) and it will render in the textarea.
But when it is saved, the value of the textarea is the text as rendered. So you don't need to de-encode. I just tested this across browsers (Internet Explorer back to version 11).
I have the same problem but in reverse, and the following solution. I want to put html from a div in a textarea (so I can edit some reactions on my website; I want to have the textarea in the same location.)
To put the content of this div in a textarea I use:
var content = $('#msg500').text();
$('#msg500').wrapInner('<textarea>' + content + '</textarea>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="msg500">here some <strong>html</strong> <i>tags</i>.</div>
This is possible with <textarea>.
You only need to use the Summernote WYSIWYG editor.
It interprets HTML tags inside a textarea (namely <strong>, <i>, <u>, and <a>).

Categories

Resources