how to give auto scroll to textarea - javascript

I have written an HTML form with a text area, text box and a button. Whatever I have typed on the textbox will be appended to the textarea when the button is clicked. Now, my problem is when the text area is completely filled, the newly arriving text appears at the bottom and I have to scroll down manually to view this text. Is there any method in javascript to make the arriving text to be visible always without scrolling down...Please help

I'm not really sure if this is what you want but have a look this:
http://jsfiddle.net/yV76p/
var textarea = document.getElementById("textarea");
textarea.onkeyup = function(evt) {
this.scrollTop = this.scrollHeight;
}
You can find the details on it here: Auto resizing textarea link down jquery

This example increases the size of the textarea as the content text is added;
Example
Javascript
var txt = $('#comments'),
hiddenDiv = $(document.createElement('div')),
content = null;
txt.addClass('txtstuff');
hiddenDiv.addClass('hiddendiv common');
$('body').append(hiddenDiv);
txt.on('input', function () {
content = $(this).val();
content = content.replace(/\n/g, '<br>');
hiddenDiv.html(content + '<br class="lbr">');
$(this).css('height', hiddenDiv.height());
});
txt.trigger('input');
CSS
body {
margin: 20px;
}
p {
margin-bottom: 14px;
}
textarea {
color: #444;
padding: 5px;
}
.txtstuff {
resize: none; /* remove this if you want the user to be able to resize it in modern browsers */
overflow: hidden;
}
.hiddendiv {
display: none;
white-space: pre-wrap;
word-wrap: break-word;
overflow-wrap: break-word; /* future version of deprecated 'word-wrap' */
}
/* the styles for 'commmon' are applied to both the textarea and the hidden clone */
/* these must be the same for both */
.common {
width: 500px;
min-height: 50px;
font-family: Arial, sans-serif;
font-size: 13px;
overflow: hidden;
}
.lbr {
line-height: 3px;
}

For having auto scrolling feature for textarea add this piece of code at the end of where ever you are trying to attend the content from textbox:
var console = $('#area');
console.scrollTop(
console[0].scrollHeight - console.height());
DEMO
Hope this helps :)

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 height: auto and line breaks

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/

Creating a textarea that resizes with volume of text (vanilla JS, no JQuery)

Server-side dev here, looking to dabble in a bit of vanilla JS to learn the ropes.
This question is about creating a form where textareas are initially hidden behind button clicks, and which also resize as the text entered into them grows larger. It's a challenging problem for someone at my level, and I'm trying to code it myself for learning purposes.
Here's what I've done so far.
Imagine a forum where users submit textual content. Each submission has a "reply" button under it. Pressing that opens a simple textarea that one can type their response into. I wrote simple JS to accomplish this:
var replyBtns = document.querySelectorAll('[id=rep]');
for(var i = 0; i < replyBtns.length; i++) {
replyBtns[i].addEventListener('click', function(e) {
e.preventDefault();
var textarea = document.getElementById("reply-message");
if (textarea) { textarea.parentNode.removeChild(textarea); }
var replyBox = document.createElement('textarea');
replyBox.setAttribute('id', 'reply-message');
replyBox.setAttribute('placeholder', 'Reply');
this.parentNode.insertAdjacentElement('beforeend', replyBox);
}, false);
}
As you can see, this JS creates a text area and adds it in the HTML. The CSS to go with it is:
textarea#reply-message {
display: block;
border: none;
color:#306654;
font-size:120%;
padding: 5px 10px;
line-height: 20px;
width:550px;
height: 20px;
border-radius: 6px;
overflow: hidden;
resize: none;
}
This works well.
My next endeavour was to make this textarea resize as the text starts overflowing. For that, I'm taking this route:
Grab the content loaded into the textarea
Create an invisible clone div
Give the clone the same width and typographical properties as the textarea
Place the content into the clone
Get the height of the clone
Apply the height of the clone to the height of the textarea
This strategy uses the property that any div element naturally stretches to fit the height of its content (assuming no floats or absolutely positioned elements). I owe this technique to this blog post.
Here's the JS for implementing the aforementioned technique:
let txt = document.getElementById('reply-message'),
hiddenDiv = document.createElement('div'),
content = null;
hiddenDiv.classList.add('hiddendiv');
document.body.appendChild(hiddenDiv);
txt.addEventListener('keyup', function () {
content = this.value;
hiddenDiv.innerHTML = content + '\n\n';
this.style.height = hiddenDiv.getBoundingClientRect().height + 'px';
}, false);
Where hiddendiv is:
.hiddendiv {
position: absolute;
left: -9999px;
visibility: hidden;
white-space: pre-wrap;
width: 550px;
height: 20px;
font-size: 120%;
padding: 5px 10px;
word-wrap: break-word;
overflow-wrap: break-word;
}
But thing is, I need this JS snippet to run only once the textarea actually exists.
Currently, I have it running on page load, where it's unable to have any effect since textareas don't yet exist. How do I ensure it only runs once they've been created? Being a newbie in JS, this is totally eluding me. Please advise.
This isn't exactly answering your question, but restructuring your code a bit to achieve the same result.
You should add the event listener to your textarea when you create it, before you add it to the page.
Insert code like this in your first glob of javascript:
replyBox.setAttribute('placeholder', 'Reply');
replyBox.addEventListener('keyup', function () {
/* do event handling here */
}, false);
A cleaner way to handle all of this would be to move all of the code pertaining to setting up your textareas into a separate function.
function setUpReplyBox(replyBox) {
replyBox.setAttribute('id', 'reply-message');
replyBox.setAttribute('placeholder', 'Reply');
hiddendiv.createElement('div');
content = null;
hiddendiv.classList.add('hiddendiv');
document.body.appendChild(hiddenDiv);
replyBox.addEventListener('keyup', function () {
content = this.value;
hiddenDiv.innerHTML = content + '\n\n';
this.style.height = hiddenDiv.getBoundingClientRect().height + 'px';
}, false);
}
Call this right after you create the item, at
var replyBox = document.createElement('textarea');
setUpReplyBox(replyBox);
this.parentNode.insertAdjacentElement('beforeend', replyBox);
Listen for the domContentLoaded Event
document.addEventListener("DOMContentLoaded", function(event) {
console.log("DOM fully loaded and parsed");
});
Reference Link
https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Maybe using a div with contenteditable instead of a textarea would make your life a bit easier.
#textarea {
-moz-appearance: textfield-multiline;
-webkit-appearance: textarea;
border: 1px solid gray;
padding: 2px;
width: 400px;
}
<div id="textarea" contenteditable>dummy textarea</div>
There is plugin for that autosize
Check the src at github, you will get idea on how to do it.
If your code is working in page load and not in text update, you need to call your resize function in every keyup, resize and input events.
window.addEventListener('resize', yourFunc);
textarea.addEventListener('paste', yourFunc);
textarea.addEventListener('keyup', yourFunc);
There is simpler method here
function auto_grow(element) {
element.style.height = "5px";
element.style.height = (element.scrollHeight)+"px";
}
textarea {
resize: none;
overflow: hidden;
min-height: 50px;
}
<textarea onkeyup="auto_grow(this)"></textarea>

Dynamically expand height of input type "text" based on number of characters typed into field

Similar to the below JSFiddle (which I bookmarked and do not know from where the original question emerged):
http://jsfiddle.net/mJMpw/6/
<input type="text" value="" placeholder="Autosize" data-autosize-input='{ "space": 10 }' />
input {
width: 200px;
min-width: 200px;
max-width: 300px;
transition: width 0.25s;
}
Is there a way to fix the width of a text field to, for example 200px only, and have the height of the text field grow if a user adds more text than the 200px is able to contain? I would like more rows to be added, if a user needs more room to type... so I need the height, not the width, to resize dynamically.
Thanks!
UPDATED[2]:
As scrollHeight is always equal to height, we have to set height to '1' before scrollHeight, then when we delete characters the <textarea> autofit:
$('textarea').on('keydown', function(e){
if(e.which == 13) {e.preventDefault();}
}).on('input', function(){
$(this).height(1);
var totalHeight = $(this).prop('scrollHeight') - parseInt($(this).css('padding-top')) - parseInt($(this).css('padding-bottom'));
$(this).height(totalHeight);
});
Fiddle:
http://jsfiddle.net/mJMpw/551/
UPDATED:
As friends said, <input type="text"/> has no line breaks. My suggest using <textarea> is:
$('textarea').on({input: function(){
var totalHeight = $(this).prop('scrollHeight') - parseInt($(this).css('padding-top')) - parseInt($(this).css('padding-bottom'));
$(this).css({'height':totalHeight});
}
});
Fiddle:
http://jsfiddle.net/mJMpw/548/
ORIGINAL ANSWER:
this is very ugly but you could do it like this:
$('input[type="text"]').on('keyup',function(){
var text = $(this).val();
var getWidth = $('<span class="getWidth" style="white-space:nowrap; width:auto;">' + text + '</span>').insertAfter(this);
$(this).css({'width':getWidth.outerWidth()}).next('.getWidth').remove();
});
You have to specify the same fonts/padding property to .getWidth and you input:
input, .getWidth {
font-family:arial;
font-size:12px;
font-weight:normal;
letter-spacing:normal;
padding:3px;
}
Fiddle:
http://jsfiddle.net/9SMRf/
As others explained, input field can't have multiline text, you should use textarea to mimic an input field, and jQuery to make it auto resize vertically (with fixed width).
JS:
//This span is used to measure the size of the textarea
//it should have the same font and text with the textarea and should be hidden
var span = $('<span>').css('display','inline-block')
.css('word-break','break-all')
.appendTo('body').css('visibility','hidden');
function initSpan(textarea){
span.text(textarea.text())
.width(textarea.width())
.css('font',textarea.css('font'));
}
$('textarea').on({
input: function(){
var text = $(this).val();
span.text(text);
$(this).height(text ? span.height() : '1.1em');
},
focus: function(){
initSpan($(this));
},
keypress: function(e){
//cancel the Enter keystroke, otherwise a new line will be created
//This ensures the correct behavior when user types Enter
//into an input field
if(e.which == 13) e.preventDefault();
}
});
CSS:
textarea {
width:200px;
resize:none;
overflow:hidden;
font-size:18px;
height:1.1em;
padding:2px;
}
Demo.
Updated Demo:
This new updated demo has some bugs fixed and it also supports Enter key, max-height limit, the width does not need to be set fixedly at first (instead we can set its min-width). It's much more full-featured.
Updated Demo
Not mine but works great:
CSS
textarea {
color: #444;
padding: 5px;
}
.txtstuff {
resize: none;
overflow: hidden;
}
.hiddendiv {
display: none;
white-space: pre-wrap;
word-wrap: break-word;
overflow-wrap: break-word
}
.common {
width: 500px;
min-height: 50px;
font-family: Arial, sans-serif;
font-size: 13px;
overflow: hidden;
}
.lbr {
line-height: 3px;
}
HTML
<textarea id="comments" placeholder="Type many lines of texts in here and you will see magic stuff" class="common"></textarea>
SCRIPT
let txt = $('#comments'),
txt.addClass('txtstuff');
let hiddenDiv = $(document.createElement('div')),
hiddenDiv.addClass('hiddendiv common');
let content = null;
$('body').append(hiddenDiv);
txt.on('keyup', function () {
content = $(this).val();
content = content.replace(/\n/g, '<br>');
hiddenDiv.html(content + '<br class="lbr">');
$(this).css('height', hiddenDiv.height());
});
FIDDLE

Div and textarea behave the same except in Firefox - what to do?

I want to create a textarea which highlights the text beyond a character limit (like the twitter one).
My attempt is here: http://jsfiddle.net/X7d8H/1/
HTML
<div class="wrapper">
<div class="highlighter" id="overflowText"></div>
<textarea id="textarea1" maxlength="200"></textarea>
</div>
<div id="counter">Letters remaining: 140</div>
<input type="Button" value="Done" id="doneButton"></input>
CSS
* {
font-family: sans-serif;
font-size: 10pt;
font-weight: normal;
}
.wrapper {
position: relative;
width: 400px;
height: 100px;
}
.wrapper > * {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
padding: 0;
margin: 0;
border: 0;
overflow: hidden;
resize: none;
white-space: pre-wrap; /* CSS3 */
white-space: -moz-pre-wrap; /* Firefox */
white-space: -pre-wrap; /* Opera below 7 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* IE */
}
.highlighter {
background-color: #eee;
color: #f0f;
}
.highlight {
background-color: #fd8;
color: #f0f;
}
textarea {
background-color: transparent;
color:#000;
}
JAVASCRIPT
function limitTextSize(e) {
var max = 140
var txt = $("#textarea1").val();
var left = txt.substring(0, max);
var right = txt.substring(max);
var html = left + '<span class="highlight">' + right + "</span>";
$("#overflowText").html(html);
$("#counter").html("Letters remaining: " + (max - txt.length));
$("#doneButton").attr("disabled", txt.length > max);
}
function maxLength(el) {
if (!('maxLength' in el)) {
var max = el.attributes.maxLength.value;
el.onkeypress = function () {
if (this.value.length >= max) return false;
};
}
}
$(document).ready(function() {
$("#textarea1").bind('input propertychange', limitTextSize)
maxLength($("#textarea1"));
});
It uses JQuery
It works except on firefox. To see the bug, paste this into the textarea:
fjdf hkj hfj hdfkjsd hfllll sdfl sdlflldsf lsdlf flsdlf lsdf lsdf llsdfls dlfs ldflsd f
Which exposes the small difference in formatting between div and textarea (in firefox only). I've made the 'hidden' text purple so you can see the word wrap difference.
I've looked here: How to force Firefox to render textarea padding the same as in a div?
And here: Wrapping the text the same way in a div as in a textarea
And here: Firefox textarea sizing bug?
But none of those seem to apply...
I thought about trying to make it a contenteditable div but getting the change events looks like a minefield.
Has anyone here done this successfully?
I think you are running into an issue where Firefox adds 1.5px of padding inside textarea elements.
Firefox has had quite some issues with paddings in combination with textareas in the past, I think you might not be able to get rid of these additional 1.5px of padding.
I was able to fix your wrapping issue by setting some vendor specific prefixed CSS properties on div.highlighter. Here's a jsFiddle.
.highlighter {
background-color: #eee;
color: #f0f;
-moz-box-sizing: border-box;
-moz-padding-end: 1.5px;
-moz-padding-start: 1.5px;
}
Setting these properties ensures that
In Firefox, the padding set on the div does not increase the width of the div, and
that, in Firefox, 1.5px of padding will be set on both the right and the left hand side of the div.
Update
After some time of using 2px and still very occasionally experiencing some wrapping inconsistencies, I decided to give 1.5px a go, and for now that seems to have ironed out the occasional inconsistencies.
This has to do with the font size being used. Since the unit used is point (pt), the size calculated is different enough in the browsers to cause the incorrect line wrap.
Try these styles instead:
* {
font-family: sans-serif;
font-size: 12px;
font-weight: normal;
}
body {
font-size: 1em;
}
JSFiddle
You might have to make changes in the container sizes to accomodate the change in font-size.
Okay, couple of things going on here. Generally, the safest cross-browser displayed element you'll find is the pre tag. It assumes that what you're feeding it is "pre-formatted," hence the name. This will benefit us in a couple ways:
As far as I know, there is no default styling done by any major browser done on the pre element.
The pre element will retain leading/trailing whitespace, tabs and other special characters in a box.
Replace the span.highlighter with pre.highlighter
That'll get us started. The second thing we'll want to look at is the overlaid colors creating some rather bizarre stacking effects in Firefox. The text looks out of focus in FF20, and I can only imagine that letting a browser decide how that looks would be a catastrophe going forward.
Set the color of the textarea to transparent.
Now we're there. I'm seeing consistent wrapping in IE10/9, FF20, and Chrome 26.
Here's an example jsFiddle

Categories

Resources