Textarea with height: auto and line breaks - javascript

If I have a textarea with some text on it, and the text has some line breaks on it, if I set my style to:
textarea {
height: auto;
overflow: hidden;
resize: none;
}
When I load the page, then the text area will only automatically set the height of the textarea until it finds the first line break, example:
For a textarea with this text:
This is an
example text
When the page is loaded, the textarea will be shown as:
This is an
Browser thinks line breaks are the end of the whole text. How do I fix it?

The text is still there if you use the arrow keys to move down, it's just that the textarea by default isn't tall enough to show all the text. You can use the rows attribute to define now many rows of text the textarea should have by default.
Alternatively, if you want more control you can use a div with the attribute contenteditable="true".
textarea {
height: auto;
overflow: hidden;
resize: none;
}
/*
* CSS for div with contenteditable="true"
*/
.textarea {
display: inline-block;
white-space: pre-wrap;
overflow-wrap: break-word;
border: 1px solid;
padding: 2px;
}
<textarea rows="3">This is an
example text
</textarea>
<div class="textarea" contenteditable="true">This is an
example text
</div>

To any one reading this, the solution I came up with is simple. With JQuery, on document ready:
$( document ).ready(function() {
var trueHeight = $( '#your_textarea' ).prop( 'scrollHeight' );
$( '#your_textarea' ).height( trueHeight );
});
Works like a charm.

.textarea {
height: auto;
overflow: hidden;
resize: none;
background-color: #000000;
color: #ffffff;
padding-left: 20px;
}
<div class="textarea"><p>This is an</p><p>example text</p></div>
Please check the above code.

You can use the rows attribute to set the height of your textarea.
<textarea rows='100'>this is an
example text</textarea>
Fiddle: https://jsfiddle.net/jvw7s1rz/2/

Related

Span label doesn't treat pressed Enter button as new line when returned

I have a custom span label with the role of textarea where I expect to enter multi-line text into it.
.input,
.textarea {
border: 1px solid #ccc;
font-family: inherit;
font-size: inherit;
padding: 5px 50px;
}
.textarea {
display: block;
width: 1000px;
overflow: hidden;
resize: none;
min-height: 200px;
line-height: 20px;
white-space: pre-wrap;
}
.textarea[contenteditable]:empty::before {
content: "Mail Body Template";
color: gray;
}
<p><span id="mail_body_template" oninput="generate(this.value)" class="textarea" role="textbox" contenteditable></span></p>
However, when I print the read value of the textarea, it appears it doesn't create new lines on pressing Enter but can do so only with Shift+Enter.
I tried to add a onpresskey listener on the span to catch the Enter and create a new line but it never works.
$(document).ready(function() {
$('#mail_body_template').on('keypress',function(e) {
if(e.which == 13) {
$('#mail_body_template').val($('#mail_body_template').val() + "\r\n");
}
});
Ultimately, I want to be able to let the span treat Enter as a new line same as it does with Shift+Enter.
Is there a way to do that?
the content of a contentEditable is HTML.
using .val() or .value doesn't return the content of the span.
It is not a console line. You cannot use \r or \n to force a line break.
You can however insert a <br> tag and this should allow the line break.
in order to access the value, you should use innerHTML.
your code is missing the generate function to further get where the error might be located. (The fact that you bind a keypress / Keydown event on the span also might trigger some weird behaviour we might not be able to reproduce.
function generate(myVal){
console.log("this.value : "+myVal)
console.log("jqueryVal : "+$("#mail_body_template").val());
console.log("innerHtml : "+document.getElementById("mail_body_template").innerHTML);
console.log("jqueryHtml : "+$("#mail_body_template").html());
console.log("plainText : "+$("#mail_body_template").text());
}
https://jsfiddle.net/kezqs7tv/5/
Here is a js.fiddle snippet that shows what I mean.

Textarea with initial auto height by content with pure CSS

I've been looking for a simple CSS solution to make a texarea match height to its content.
I DO NOT want an auto resizing textarea that changes as you type. I have a textarea with text already in it and I want it to match the content.
Is there any way to do this using CSS?
No, because, by definition, a textarea isn't sized according to its content.
You could however, use a <div contenteditable="true"></div> and style it to look and act like a textarea.
.textarea {border:1px solid #e0e0e0; max-height:100px; overflow-y:scroll;}
<div contenteditable="true" class="textarea">jdsklf ;askf; fs;dlfkj sad;flkasdj f;laskfj as;lfkajsd f;lasdkfj asl;dkfj sad;lfkasjd f;laskdjf a;sldfkj asdf;lkasdjf ;lasdkfj asd;lfkjsad f;laksdjf ;alsdkfjs ad;lfkjsad f;lksadjf ;lasdkfjasdl;fk jasdl;fkj asdf;lksadj f;lsadkfj sad;lfkjsd f;lksadjf; lsadkfjsda;lfk jsd;lfk jsdf</div>
Here's a 100% css way to do it.
https://codepen.io/anon/pen/BxLMKK
Note that for this demo I did a simple 2-column layout just to provide context, but the actual important part is just in the .textbox-mimic div.
html:
<div class="container">
<div>
<div class="textarea-mimic">
<span>
Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here.
</span>
<textarea>Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here. Here's some text that's already here.
</textarea>
</div>
</div>
<div>
Some things over here
</div>
</div>
CSS:
.container {
outline: 2px solid #000;
display: flex;
width: 500px;
height: 100%;
margin: 0 auto;
}
.container > div {
flex: 1;
outline: 1px solid #cc00cc;
padding: 8px;
}
.container > div > .textarea-mimic {
position: relative;
}
.container > div > .textarea-mimic > span {
visibility: hidden;
}
.container > div > .textarea-mimic > textarea {
width: 100%;
height: 100%;
overflow: hidden;
box-sizing: border-box;
padding: 0;
margin: 0;
position: absolute;
left: 0;
top: 0;
bottom: 0;
font: inherit;
overflow: hidden;
resize: none;
/* display: none; */
}
So basically what's happening here is that we're populating the content of the textarea and another sibling (span in this case) with the same content. The styling of the text area is updated to have the same font, padding, etc as the div. Depending on your specific needs, you just updated these as you see fit. But its critical they match so that the spacing and layout are identical.
Then we set some properties for the textarea to make it position absolute and to adopt the dimensions of the parent. Finally, the content of the .textarea-mimic > span is set to visibility: hidden. This allows the dimensions to be filled out while only showing the text area. Toggle the visibility property off and the display: none of the textarea to see it in action.
Also note that if you would like this to update in realtime, some simple javascript that updates the content of the hidden text based on the textarea should make it dynamic.

Make popup have smart positioning

I am working on a piece of legacy code for a table. In certain cells, I'm adding a notice icon. When you hover over the icon a <span> is made visible displaying some information. I would like to be able to make this <span> smart about its positioning but can't figure out a good method. I can statically position it but depending on which cell in the table it is in it gets lost against the edge of the page. I have done a JsFiddle here demonstrating the issue. Unfortunately, I am not allowed to use anything but HTML, CSS and vanilla JS.
The title attribute to most tags is pretty smart about its position. I have added a title to one of the cells in the table in the jsFiddle (cell containing "Hello"). Is there any way to make my span exhibit the same smart behaviour?
A pop-up can be added before any element by putting the popup html code inside a 'div' with 'position:absolute; overflow:visible; width:0; height:0'.
When these events: 'onmouseenter', 'onmouseleave' are fired on the element, just toggle the popup css attribute 'display' between 'none' and 'block' of the element.
Example on jsfiddle:
https://jsfiddle.net/johnlowvale/mfLhw266/
HTML and JS:
<div class="popup-holder">
<div class="popup" id="popup-box">Some content</div>
</div>
Some link
<script>
function show_popup() {
var e = $("#popup-box");
e.css("display", "block");
}
function hide_popup() {
var e = $("#popup-box");
e.css("display", "none");
}
</script>
CSS:
.popup-holder {
position: absolute;
overflow: visible;
width: 0;
height: 0;
}
.popup {
background-color: white;
border: 1px solid black;
padding: 10px;
border-radius: 10px;
position: relative;
top: 20px;
width: 300px;
display: none;
}

Identical elements have different scrollHeights when overflowed. What is the cause, and how can I fix it?

I have a plugin that creates and, on an interval, populates a <p> with the content of a <textarea>. The plugin positions the <p> underneath the <textarea>, and styles the elements so that their "boxes" are identical. Additionally, the background and text of the <textarea> are defined as transparent so that the content of the <p> can be seen.
Ideally, the elements and their contents will mirror one another at all times. And in most cases, they do. However, when both elements are made to be scrollable, the dynamic breaks; this is due to a difference in the scrollHeight of the two elements (the scrollHeight of <textArea> is larger than that of the <p>)
Here is the code:
var $shadowParagraphObj = $("#shadowParagraph");
var $contentTextAreaObj = $("#contentTextArea").scroll(scrollShadowParagraph);
function scrollShadowParagraph(event)
{
var textAreaScrollLeft = $contentTextAreaObj.scrollLeft();
var textAreaScrollTop = $contentTextAreaObj.scrollTop();
if($shadowParagraphObj.scrollLeft() != textAreaScrollLeft)
$shadowParagraphObj.scrollLeft(textAreaScrollLeft)
if($shadowParagraphObj.scrollTop() != textAreaScrollTop)
$shadowParagraphObj.scrollTop(textAreaScrollTop)
}
var intervalId = setInterval(function(){$shadowParagraphObj.html($contentTextAreaObj.val())}, 100);
#containerDiv {
position: relative;
left: 50%;
margin-left: -250px;
width: 510px;
height: 200px;
}
#shadowParagraph, #contentTextArea {
width: inherit;
height: inherit;
overflow: scroll !important;
padding: 4px;
border : none;
outline: none;
margin: 0px;
white-space: pre-wrap;
word-wrap: pre-wrap;
font: 1em Arial, sans-serif;
}
#shadowParagraph {
position: absolute;
z-index: 0;
background: white;
color: blue;
}
#contentTextArea {
position: relative;
z-index: 1;
background: transparent;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='containerDiv'>
<p id='shadowParagraph'></p>
<textarea id='contentTextArea'></textarea>
</div>
Overflowing the <textarea> should produce the issue (the text of the <textarea> has been given color to make the issue easy to see).
Have I forgot to declare some properties that are causing this discrepancy between scrollHeight values? If so, what are they and how should I declare them? If not, is there any way to ensure that the scrollHeight of the two elements is equal at all times?
Okay so using .replace(/\n\r?g, '<br />') to convert updated values, your line breaks will be converted into html line breaks. Additionally, html tends to ignore lone <br /> line breaks, so you will want to add an additional <br /> to the value to ensure the last line break is rendered.
Put together this would look something like:
var textAreaHTML = $myTextArea.val().replace(/\n\r?g, '<br />')+'<br />';
Additionally, I would recommend updating your textarea values AND scroll position on the .keyup() event, .keypress() event, or both events using .on('keyup keypress', function() {...}).
To see this in action check out this jsFiddle example

Set value of Textarea after jquery.colorfy

I use jquery.colorfy https://github.com/cheunghy/jquery.colorfy to change the key word color in the textarea.
I can set value use $('#textarea').text("value"); to change my textarea value.
The problem is: After the code $('#textarea').colorfy("markdown");, the command: $('#textarea').text("value"); is dead.
Could someone tell me what happened? Thanks a lot.
Try like this:
$(document).ready(function(){
$('#area').colorfy("markdown");
$('#area').text("value");//will be hidden you can see by inspecting the html
$('.area').html("value");// will be visible to you
});
Note: What i see from the example is it sets display:none to the textarea but creates a div with the same class which is the class of text area and applies it's own css on these.
$(document).ready(function(){
$('#area').colorfy("markdown");
$("#click").click(function(){
$('.area').html("value");// will be visible to you
});
});
.area {
float: auto;
margin-left: auto;
margin-right: auto;
width: 200px;
max-width: 200px;
height: 200px;
border-color: black;
border-width: 2px;
border-style: solid;
padding: 8px;
font-size: 15px;
text-align: left;
}
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="http://cheunghy.github.io/jquery.colorfy/jquery.colorfy.js"></script>
<script type="text/javascript" src="http://cheunghy.github.io/jquery.colorfy/jquery.colorfy.markdown.js"></script>
<textarea id="area" class="area">
hi
</textarea>
<button id="click">click!</button>
Do operate first on text of textarea before applying colorfy or else post applying manage with span it adds with class
After you write $('#textarea').colorfy("markdown"); it applies color ie. custom css by modifying the textarea text by adding span and class. Tested this plugin please see the screenshot below.
Quick Note: Please dubug more as per your need.

Categories

Resources