I have a fairly simple CSS question. I have an input text field, and on page load i would like it to be 150px in width.
However, as the user enters some text, if the text is greater than 150px in width, then the width should auto adjust.
Here's a plunker:
http://plnkr.co/edit/ig0BQrJDiEtXKV8zJ2w2?p=preview
HTML:
<input class="input-class" type="text" placeholder="Placeholder">
CSS:
.input-class-2 {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
border-color: -moz-use-text-color -moz-use-text-color #ef8e80;
border-image: none;
border-style: none none dashed;
border-width: 0 0 1px;
color: #ef8e80;
cursor: pointer;
font-family: Gotham-Book;
font-size: 18px;
min-width: 150px;
}
I assumed min-width would do this.
There currently is no way to achieve this with pure CSS, perhaps once calc and attr can be used in combination, but not currently. So we have to fall back to JavaScript.
There isn't any real reason to use jQuery for this. You can argue that your "concerns should be separated" i.e. code should be separate from mark-up, but that is easy to do using addEventListener. However, if I'm dealing with one off small bits of JavaScript it tends to be faster — in terms of implementation, page render and even for those trying to track down what is making the input behave strangely — to use inline event listeners.
<input type="text"
style="min-width: 150px;"
onkeyup="this.size = Math.max(this.value.length, 1)"
/>
or:
<input type="text"
style="width: 150px;"
onkeyup="
this.style.width = '1px';
this.style.width = (
this.scrollWidth > 140
? this.scrollWidth + 10
: 150
)+'px';
"
/>
Disclaimer: Obviously if you are implementing many of these inputs it is far better to code a generalised function to handle them. Plus it is always far better to avoid inline style by using a stylesheet.
/**
* Directly setting the size attribute, with minWidth
*/
function autosize(elm, minWidth){
var keyup = function(e){
var t = e.target || e.srcElement;
var v = Math.max(t.value.length, 1);
t.setAttribute
? t.setAttribute('size', v)
: (t['size'] = v)
;
};
elm.style.minWidth = minWidth+'px';
elm.addEventListener
? elm.addEventListener('keyup', keyup)
: elm.attachEvent('onkeyup', keyup)
;
};
The size attribute is by far the most obvious choice, although you can directly set the width — if you prefer — using scrollWidth.
/**
* Directly setting width, with minWidth
*/
function autosize(elm, minWidth){
var keyup = function(e){
var t = e.target || e.srcElement;
t.style.width = '1px';
t.style.width = t.scrollWidth + 'px';
};
elm.style.minWidth = minWidth+'px';
elm.addEventListener
? elm.addEventListener('keyup', keyup)
: elm.attachEvent('onkeyup', keyup)
;
};
You can trigger either of these functions by passing your target element in as the first argument. There are a number of ways of finding your element, the easiest and most universal being getElementById. Although you will only be able to find your element if it has been parsed by the browser, so the script tag you use — to run the following code — will either have to be placed below the element in the mark-up i.e. bottom of <body> (preferable), or after waiting for window load, or DOM readiness.
autosize( document.getElementById('myinput'), 150 );
/**
* Directly setting width, with minWidth
*/
function autosize1(elm, minWidth){
var keyup = function(e){
var t = e.target || e.srcElement;
t.style.width = '1px';
t.style.width = t.scrollWidth + 'px';
};
elm.style.minWidth = minWidth+'px';
elm.addEventListener
? elm.addEventListener('keyup', keyup)
: elm.attachEvent('onkeyup', keyup)
;
};
/**
* Directly setting the size attribute, with minWidth
*/
function autosize2(elm, minWidth){
var keyup = function(e){
var t = e.target || e.srcElement;
var v = Math.max(t.value.length, 1);
t.setAttribute
? t.setAttribute('size', v)
: (t['size'] = v)
;
};
elm.style.minWidth = minWidth+'px';
elm.addEventListener
? elm.addEventListener('keyup', keyup)
: elm.attachEvent('onkeyup', keyup)
;
};
autosize1( document.getElementById('a'), 150 );
autosize2( document.getElementById('b'), 150 );
<p>Each input is using a different implementation:</p>
<input type="text"
style="min-width: 150px;"
onkeyup="this.size = Math.max(this.value.length, 1)"
/><br />
<input type="text"
style="width: 150px;"
onkeyup="
this.style.width = '1px';
this.style.width = (
this.scrollWidth > 140
? this.scrollWidth + 10
: 150
)+'px';
"
/><br />
<input type="text" id="a" /><br />
<input type="text" id="b" /><br />
You can try like this:
function resizeInput() {
$(this).attr('size', $(this).val().length);
}
$('input[type="text"]')
.keyup(resizeInput)
.each(resizeInput);
JSFIDDLE DEMO
There is one more alternative of using the
<span contenteditable="true">Some Text</span>
instead of using Input tags.
JSFIDDLE DEMO
You can try something like this
$('.input-class').keyup(function(){
var textlength=$('.input-class').val().length
$(this).width(textlength * 8)
})
.input-class{
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
border-color: -moz-use-text-color -moz-use-text-color #ef8e80;
border-image: none;
border-style: none none dashed;
border-width: 0 0 1px;
color: #ef8e80;
cursor: pointer;
font-family: Gotham-Book;
font-size: 18px;
min-width: 150px;
width:auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<input class="input-class" type="text" placeholder="Placeholder">
Tried to use pure JavaScript.
I hide a span element that's not shown (visibility:hidden;) to the user.
Then I calculate the span elements rendered width, and setting that to the container of the input.
And setting the input to be width:100%; makes it grow to the size of its parent.
var field = document.getElementById("grow");
field.oninput = function() {
var ruler = document.getElementById("ruler");
ruler.innerHTML = field.value.replace(/ /g," ");
var outer = document.getElementById("outer");
if (ruler.offsetWidth > 100) {
outer.setAttribute('style', "width:" + (ruler.offsetWidth + 5) + "px;");
} else {
outer.setAttribute('style', "");
}
};
#grow {
height: 100%;
width: 100%;
font-size: inherit;
font-family: inherit;
}
#outer {
width: 100px;
font-size: 1rem;
font-family: Serif, "Times New Roman", Georgia;
}
.hidden {
position: absolute;
display: inline;
visibility: hidden;
padding: 0;
font-size: inherit;
font-family: inherit;
white-space: nowrap;
}
<div id="outer">
<span id="ruler" class="hidden"></span>
<input id="grow" type="text/plain"/>
</div>
<p>+ Expands</p>
<p>+ shrinks</p>
<p>+ whitespace handling</p>
Related
I'm learning how to code javascript, please do not reply that this can be done by using someone else's code that already exists. I am doing this to learn.
I have a situation whereby the below CSS and HTML code:
CSS:
div.miniblock {
font-size: 12px;
background-color: #333333;
text-align: center;
vertical-align: middle;
border: thin dotted #CCCCCC;
color: #FFFFFF;
padding: 2px;
margin: 5px;
cursor: move;
position: relative;
}
div.miniblock_unsaved {
font-size: 12px;
background-color: #55AAAA;
text-align: center;
vertical-align: middle;
border: thin dotted #000;
color: #000;
padding: 2px;
margin: 5px;
cursor: move;
position: relative;
}
div.dropinto {
font-size: 12px;
background-color: #575757;
text-align: center;
vertical-align: middle;
border: thin dotted #AAAAAA;
color: #FFFFFF;
padding: 2px;
margin: 5px;
}
div.dropinto_over {
font-size: 12px;
background-color: #FFFFFF;
text-align: center;
vertical-align: middle;
border: thin dotted #000000;
color: #000000;
padding: 2px;
margin: 5px;
}
div.moving {
font-size: 12px;
background-color: #CCCCCC;
text-align: center;
vertical-align: middle;
border: thin dotted #000000;
color: #000000;
z-index:1;
height: 80px;
width: 80px;
opacity: 0.7;
padding: 5px;
cursor: move;
}
div.OPAQUE {
font-size: 12px;
background-color: #FFF;
text-align: center;
vertical-align: middle;
color: #000000;
opacity: 0.5;
}
HTML:
<INPUT TYPE="HIDDEN" NAME="block_side[3]" VALUE="" ID="block_side0">
<INPUT TYPE="HIDDEN" NAME="block_order[3]" VALUE="" ID="block_order0">
<INPUT TYPE="HIDDEN" NAME="block_side[4]" VALUE="" ID="block_side1">
<INPUT TYPE="HIDDEN" NAME="block_order[4]" VALUE="" ID="block_order1">
<INPUT TYPE="HIDDEN" NAME="block_side[5]" VALUE="" ID="block_side2">
<INPUT TYPE="HIDDEN" NAME="block_order[5]" VALUE="" ID="block_order2">
<INPUT TYPE="HIDDEN" NAME="block_side[6]" VALUE="" ID="block_side3">
<INPUT TYPE="HIDDEN" NAME="block_order[6]" VALUE="" ID="block_order3">
<INPUT TYPE="HIDDEN" NAME="block_side[2]" VALUE="L" ID="block_side=4">
<INPUT TYPE="HIDDEN" NAME="block_order[2]" VALUE="1" ID="block_order4">
<INPUT TYPE="HIDDEN" NAME="block_side[1]" VALUE="L" ID="block_side=5">
<INPUT TYPE="HIDDEN" NAME="block_order[1]" VALUE="2" ID="block_order5">
<DIV CLASS="OPAQUE" ID="instruct"></DIV>Set your preferences for the blocks of information and their display location here.<TABLE height="100%" width="100%"><TR ><TH COLSPAN="2">Assigned Blocks</TH></TR><TR ><TD COLSPAN="2">Here are the blocks that are currently displayed during your experience.</TD></TR><TR ><TD WIDTH="50%" VALIGN="TOP"><DIV CLASS="dropinto" ID="leftblocks" SLOT="L">Left Blocks<div onmousedown="grabobj(4)" onmousemove="dragobj(4)" onmouseup="dropobj(4)" id="4" name="2" class="miniblock">Quick Links [2]</div><div onmousedown="grabobj(5)" onmousemove="dragobj(5)" onmouseup="dropobj(5)" id="5" name="1" class="miniblock">Session Information [1]</div></DIV></TD><TD WIDTH="50%" VALIGN="TOP"><DIV CLASS="dropinto" ID="rightblocks" SLOT="L">Right Blocks</DIV></TD></TR><TR ><TH COLSPAN="2">Unassigned Blocks</TH></TR><TR ><TD COLSPAN="2" ID="unassigned_blocks">Here are the blocks that are not currently displayed during your experience.<div onmousedown="grabobj(0)" onmousemove="dragobj(0)" onmouseup="dropobj(0)" id="0" name="3" class="miniblock">Another Block [3]</div><div onmousedown="grabobj(1)" onmousemove="dragobj(1)" onmouseup="dropobj(1)" id="1" name="4" class="miniblock">And Another [4]</div><div onmousedown="grabobj(2)" onmousemove="dragobj(2)" onmouseup="dropobj(2)" id="2" name="5" class="miniblock">Poll Voting [5]</div><div onmousedown="grabobj(3)" onmousemove="dragobj(3)" onmouseup="dropobj(3)" id="3" name="6" class="miniblock">SysAdmin Block [6]</div></TD></TR></TABLE>
and the below Javascript:
window.instruct = function(id, instr){
var el = document.getElementById(id);
el.innerHTML = instr;
}
window.blockprefs = function(id, thisblock){
// determine which slot thisblock belongs to
s = id.getAttribute('SLOT');
// identify all the child nodes associated to this slot
c = id.childNodes;
for(var i=1;i < c.length; i++) { // I set i = 1 here because I don't care about the parent element at this time.
name = c[i].getAttribute('NAME');
// console.log(c.length,c[i]);
pos = document.getElementById('block_side'+name);
ord = document.getElementById('block_order'+name);
pos.setAttribute('VALUE',s);
ord.setAttribute('VALUE',i);
console.log(name,pos,ord,c[i]);
}
};
window.grabobj = function(id){
// console.log('moving object: '+id);
// console.log(document.getElementById(id));
// console.log(event.clientX+', '+event.clientY);
thisblock = document.getElementById(id);
thisblock.setAttribute('CLASS','moving');
thisblock.setAttribute('STATUS','click');
thisblock.style.position = 'absolute';
thisblock.style.left = event.pageX - 40;
thisblock.style.top = event.pageY - 20;
// id.addEventListener('mousemove',function(){console.log('moving mouse: x('+event.clientX)+') y('+event.clientY+')';},false);
};
window.drop = function(id, hit) {
id.setAttribute('STATUS','drop');
id.setAttribute('CLASS','miniblock_unsaved');
id.setAttribute('STYLE','');
instruct('instruct','You have unsaved changes, be sure to commit your changes below.');
};
window.dropobj = function(id){
thisblock = document.getElementById(id);
if(thisblock.getAttribute('STATUS') == 'drag' || thisblock.getAttribute('STATUS') == 'click'){
// determine if the block was dropped within one of the drop object targets
// if it was not, return it to the original location, otherwise, drop it into the new location
var left = document.getElementById("leftblocks"),
right = document.getElementById('rightblocks'),
leftbounds = left.getBoundingClientRect(),
rightbounds = right.getBoundingClientRect(),
t = window.pageYOffset || document.documentElement.scrollTop,
l = window.pageXOffset || document.documentElement.scrollLeft;
if(event.clientX >= leftbounds.left && event.clientX <= leftbounds.right && event.clientY >= leftbounds.top && event.clientY <= leftbounds.bottom){
// hit on the left blocks bounds, drop it into the left block
left.appendChild(thisblock);
//thisblock.insertBefore(left.firstchild);
drop(thisblock);
// now assign the hidden form element the correct values based on the current config in the left block then
// here is what I think will have to happen:
// identify all child nodes of the parent node
// identify all of the hidden form fields associated to those child nodes
// update all of the hidden form fields associated to those child nodes with
// the correct order and L / R flag.
// not sure how to complete those tasks at this time.
// console.log( document.getElementById('block_order' + thisblock.getAttribute('ID')));
// console.log( left.childElementCount );
blockprefs(left, thisblock);
} else if(event.clientX >= rightbounds.left && event.clientX <= rightbounds.right && event.clientY >= rightbounds.top && event.clientY <= rightbounds.bottom){
// hit on the right blocks bounds, drop it into the right block
right.appendChild(thisblock);
//thisblock.insertBefore(right.firstchild);
drop(thisblock);
// now assign the hidden form element the correct values based on the current config in the left block then
} else {
// user missed dropping into the left or right box, drop it back into unassigned.
var u = document.getElementById("unassigned_blocks");
u.appendChild(thisblock);
drop(thisblock);
}
}
};
window.dragobj = function(id){
thisblock = document.getElementById(id);
if(thisblock.getAttribute('STATUS') == 'click' || thisblock.getAttribute('STATUS') == 'drag'){
thisblock.style.left = event.pageX - 40;
thisblock.style.top = event.pageY - 20;
thisblock.setAttribute('STATUS','drag');
}
};
window.onload = function() {
// on mouseover change color of leftdiv or right div
var left = document.getElementById("leftblocks");
var right = document.getElementById('rightblocks');
console.log(left.nodeValue);
function block_over(block){ // set the attribute of the block on mouse over
// console.log('setting property of block: '+block);
block.setAttribute('CLASS','dropinto_over');
}
function block_out(block){ // set the attribute of the block on mouse out
block.setAttribute('CLASS','dropinto');
}
left.addEventListener('mouseover',function(){block_over(left); },true); // listener to set the left block's attributes
left.addEventListener('mouseout',function(){block_out(left); },true);
right.addEventListener('mouseover',function(){block_over(right); },true); // listener to set the right block's attributes
right.addEventListener('mouseout',function(){block_out(right); },true);
};
I attempted to put this into a JSFIDDLE https://jsfiddle.net/vt1hcLL6/ but the frames were throwing it off so it might have to just go into a flat html file sorry.
As a user, the intent of this code is to be able to pick up the blocks and move them into the slots (either the left or the right side) blocks, or remove them from those blocks.
After doing so, javascript will set some values in the hidden form fields so that upon saving the page php will grab those values.
Currently it's only setup to do so if you move a block into the left side and yes once I get this all nailed from a hardcoded perspective I will abstract it further, for now some of this is hard coded.
My problem is that upon the first instance of dropping a block into the Left Side Block, everything works fine all the HIDDEN form fields update correctly with the SLOT="L" Attribute and the ORDER="i" attribute (i being the number corresponding to the child iteration.
Great! It works! Now... once a second block is added to that set from down below, the code breaks and I can't figure out why.
The code that is performing this functionality is in the blockprefs( ) function where I iterate through all the child nodes of the Left block and attempt to bring in the hidden form elements belonging to each child. I get a:
divblock.js:33 Uncaught TypeError: Cannot read property 'setAttribute' of null
I'm trying to position a div immediately to the right of text being typed in a text input-field. To me, this seems as simple as taking the length of the input's val and positioning the div to that value. However, what is happening is that it is only right after the text when there is 1 character in the input-field. As more and more are typed, the offset becomes larger and larger.
What i'm trying to create is a suggestion box that will complete a word that is being typed.
How can I position this so that on each keyup it is to the right and right next to the input's value?
Here is a js fiddle: http://jsfiddle.net/ugkzdjsy/
And here is how I'm trying to position it on keyup:
$('input').on('keyup', function(){
$('#suggestion').css('left', $(this).val().length+'rem');
});
No matter what units I try, px, em, rem, I get similar results.
You'll have to calculate the width of the text and then set the left property.
Here's a JavaScript function that will do it.
This function creates a span tag gives it the same property as the input tag, appends the input text to the span, then appends the span tag to the DOM and get the width using .offsetWidth.
$('input').on('keyup', function() {
$('#suggestion').css('left', width($(this).val()) + 1 + 'px');
});
function width(text) {
var s = document.createElement('span');
var t = document.createTextNode(text)
s.appendChild(t);
s.id = 'length';
s.style.fontSize = '1.2rem';
s.style.visibily = 'hidden';
s.style.opacity = '0';
var m = document.getElementById('suggestion');
for (i = 0; i < m.children.length; i++) {
if (m.children[i].id == 'length') {
m.removeChild(m.children[i]);
}
}
m.appendChild(s);
return (s.offsetWidth * 0.935 > document.getElementById('inpt').offsetWidth) ? document.getElementById('inpt').offsetWidth : s.offsetWidth * 0.935;
};
html,
body {
font-size: 16px;
}
input {
height: 2.618rem;
font-size: 1.2rem;
}
#suggestion {
height: 1.5rem;
width: 1.5rem;
position: relative;
background: #66bb6a;
color: #000000;
color: rgb(0, 0, 0);
font-family: 'Myriad Pro', 'Open Sans', sans-serif;
top: -35px;
z-index: 2;
overflow: hidden;
transition: all 0.2s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="inpt" type="text" val="leonardo" />
<div id="suggestion"></div>
I wanted to implement a slider control that changes the brightness of the image, much like the one shown at this link :
http://camanjs.com/examples/
I am fairly new to javascript and this is proving to be rather difficult. So right now, I am using the CamanJS library but unfortunately am not able to replicate that. I tried reverse engineering the example, but gosh the example is very complicated and not at all readable! Anyways, heres the problem with my implementation :
//this is the event handler called when the slider value changes
function brightnessControl(e, ui) {
//mainImage is the id of the canvas that holds the image
Caman("#mainImage", function() {
this.brightness(ui.value);
this.render();
});
}
the original image is overwritten with a new image with the brightness settings. So eventually, I end up with just a plain white or black image. Any help would be greatly appreciated! Thanks in advance!
You can achieve the desired effect with a canvas element, CSS3 filter and pure JavaScript:
HTML
<input id="bri" type="text" value="1"/>
<canvas id="img"></canvas>
JavaScript
window.onload = function () {
var context = document.getElementById('img').getContext('2d');
/* Loading the image at first */
var base_image = new Image();
base_image.src = 'http://images.google.com/intl/fr_ALL/images/logos/images_logo_lg.gif';
context.drawImage(base_image, 0, 0);
/* Function trigerred when we leave the input */
document.getElementById('bri').onblur = function () {
var amount = this.value;
var img = document.getElementById('img');
/* We change the brightness of the canvas itself */
img.setAttribute('style', 'filter:brightness(' + amount + '); -webkit-filter:brightness(' + amount + '); -moz-filter:brightness(' + amount + ')');
}
};
Live Demo
To read full implementation check this website How to Create an Image Brightness Control Slider
rangeInput = document.getElementById('range');
container = document.getElementsByClassName('container')[0];
rangeInput.addEventListener("mousemove",function(){
container.style.filter = "brightness(" + rangeInput.value + "%)";
});
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container{
background: url(https://codingdebugging.com/wp-content/uploads/2020/07/include-how-to-create-an-image-brightness-control-slider.jpg) no-repeat center;
min-height: 100vh;
background-size: cover;
display: flex;
align-items: center;
justify-content: center;
}
.brightness-box{
width: 400px;
height: 60px;
background: #f9f9f9;
border-radius: 8px;
padding: 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.brightness-box i{
margin: 0 10px;
}
#range{
width: 100%;
-webkit-appearance: none;
background: #0a85ff;
height: 3px;
outline: none;
}
#range::-webkit-slider-thumb{
-webkit-appearance: none;
width: 22px;
height: 22px;
background: #333;
border-radius: 50%;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<title>Brightness Control - Coding Debugging</title>
<!-- Font Awesome Icon -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css">
</head>
<body>
<div class="container">
<div class="brightness-box">
<i class="far fa-sun"></i>
<input type="range" id="range" min="10" max="100" value="100">
<i class="fas fa-sun"></i>
</div>
</div>
</body>
</html>
//this is the event handler called when the slider value changes
function brightnessControl(e, ui) {
//mainImage is the id of the canvas that holds the image
Caman("#mainImage", function() {
this.style.filter='brightness(ui.value)';//like this: filter: brightness(0.4)
//this.brightness(ui.value);
// this.render(); i don/t know this is useful? you judge it by yourself
});
}
the brightness is from 0 to 1.
The following will work in CSS 2.1+. Please note that I have used HTML5 input type="range" only for ease of use in this example. Javascript fallback code is also implemented in this example for browsers that do not support this (input type will default to text).
Optimally a custom slider would be implemented, but I believe this question is about brightness control and not so much about the slider.
The way this works is by overlapping the image with some element of equal proportions and with opacity depending on the slider/text input value. The background color of this element will be white for values > 50, and black for values < 50.
Link to JS Fiddle
#HTML
<div id="container">
<div id="brightness"></div>
<img src="http://placehold.it/400x400" />
</div>
Brightness (0 - 100):<br />
<input type="range" id="controls" value="50" min="0" max="100" maxlength="3">
#Javascript
window.onload = function()
{
var brightness = document.getElementById('brightness');
controls = document.getElementById('controls');
controls.onkeyup = controls.onchange = function()
{
var brightness = document.getElementById('brightness'),
val = parseInt(this.value) - 50;
if (val > 50 || val < -50)
return false;
brightness.style.backgroundColor = val > 0 ? 'white' : 'black';
brightness.style.opacity = Math.abs(val/100) * 2;
}
}
#CSS
#container{
width:400px;
height:400px;
margin-bottom:10px;
border:1px solid rgb(127, 127, 127);
}
#brightness{
width:400px;
height:400px;
background:white;
position:absolute;
opacity:0;
}
#controls{
width:400px;
height:22px;
padding:0 5px;
}
I would like to have a text area which is always as big as the text in it. So the page can be scrolled and in the text area cannot be scrolled.
Here's what I did until now:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html, body {height: 100%;}
textarea {
border: none;
width: 100%;
height: 100%;
-webkit-box-sizing: border-box;
line-height: 44px;
font-family:Helvetica;
font-size: 17pt;
-webkit-tap-highlight-color: rgba(0,0,0,0);
background-image:url('linedBack#2x.png');
outline: none;
resize: none;
}
textarea.vert { resize:vertical; }
</style></head><body>
<textarea id="InputTextArea" placeholder="placeholder"></textarea>
</body></html>
Resizing TeaxArea based on the content line number. Here's a DEMO
JS
function resizeTextarea (id) {
var a = document.getElementById(id);
a.style.height = 'auto';
a.style.height = a.scrollHeight+'px';
}
function init() {
var a = document.getElementsByTagName('textarea');
for(var i=0,inb=a.length;i<inb;i++) {
if(a[i].getAttribute('data-resizable')=='true')
resizeTextarea(a[i].id);
}
}
addEventListener('DOMContentLoaded', init);
HTML
<textarea id="InputTextArea" placeholder="placeholder" onkeyup="resizeTextarea('InputTextArea')"></textarea>
If you are using AngularJS, you can do :
<textarea ng-keyup="ctl.handleTextAreaHeight($event)"></textarea>
With this in your controller :
this.handleTextAreaHeight = function (e) {
var element = e.target;
element.style.overflow = 'hidden';
element.style.height = 0;
element.style.height = element.scrollHeight + 'px';
};
In case anyone still needs this, for what it's worth, here's mine in pure js. But first, you may check this one:
Auto expand a textarea using jQuery
var textAreas = document.getElementsByTagName('textarea');
try {
taLength = textAreas.length;
for (i=0; i < taLength; i++) {
var taId = textAreas[i].id;
document.getElementById(taId).addEventListener('input', function(e) {
e.target.style.height = "auto";
//This makes your textarea back to its original size. So you can replace it with any size you want it to have e.g. "120px"
//You may need some logic if you have multiple taxtareas with different original sizes
e.target.style.height = e.target.scrollHeight+'px';
});
}
}
catch (err) {
window.alert(err);
}
I used shubhra's answer to build that one. It is smooth and the scrollbar won't appear.
If someone need a solution for Vue.js. Here is a vue directive to do a auto resizing text area. Just register directive globally once and you can use it for any textarea
Vue.directive('resizable', {
inserted: function (el) {
el.addEventListener('input', function(e) {
e.target.style.height = "auto";
e.target.style.height = e.target.scrollHeight + 'px';
});
}
});
html is easy, just put v-resizable attribute in textarea
<textarea v-resizable></textarea>
Special thanks to AniMir! I am using his input event handler.
Just setting height = scrollHeight misses the goal when box-sizing: border-box is set. Here is a solution with a fix for that and which allows the textarea to shrink again.
// auto resize the textareas
document.querySelectorAll("textarea").forEach(function (el) {
el.addEventListener("input", function () {
var cs = window.getComputedStyle(this);
// reset height to allow textarea to shrink again
this.style.height = "auto";
// when "box-sizing: border-box" we need to add vertical border size to scrollHeight
this.style.height = (this.scrollHeight + parseInt(cs.getPropertyValue("border-top-width")) + parseInt(cs.getPropertyValue("border-bottom-width"))) + "px";
});
});
// compat window.getComputedStyle: IE9
// compat NodeList.forEach: No IE (but not necessary here)
* { box-sizing: border-box; }
textarea { width: 20%; }
#a { padding: 1em; }
#b { padding: 0; }
#c { max-height: 7em; }
#d {
border-top: 10px solid blue;
border-bottom: 10px solid blue;
}
<textarea id="a">1em padding</textarea>
<textarea id="b">0 padding</textarea>
<textarea id="c">max-height: 7em</textarea>
<textarea id="d">10px vertical borders</textarea>
<textarea
id="newComm"
class="form-control"
name="comment"
placeholder="Some text"
cols="30"
:rows="rowsHeight"
wrap="soft"
v-model.trim="newCommText"
#input="changeRows"
:style="'resize: none; overflow: hidden; line-height: '+lineHeight+'px;'"
></textarea>
setup() {
const newCommText = ref(null)
const rowsHeightStart = ref(5)
const rowsHeight = ref(rowsHeightStart.value)
const lineHeight = ref(25)
function changeRows (event) {
rowsHeight.value = event.target.value.split("\n").length > rowsHeightStart.value ? event.target.value.split("\n").length : rowsHeightStart.value
}
return {
rowsHeight, lineHeight, newCommText,
changeRows
}
How can I change the font size using JavaScript on an input field depending on how many characters are typed. For instance, the default font size is 16px, but if I add more than 10 characters, the font size to become 12px.
HTML:
<div class="phone-input">
<input readonly="readonly" type="text" id="tocall" value="">
and css:
input#tocall {
width: 145px;
padding: 6px 3px;
color: #424242;
font-size: 16px;
border: 1px solid rgb(224, 224, 224);
font-weight: bold;
letter-spacing: 0.1em;
}
I am unfamiliar working with JavaScript so please help me.
You can do something like in the snippet below, if you just leave readonly out of your input, now you can't type anything into it.
var input = document.getElementById('tocall');
input.addEventListener('keyup', function (e) {
if (e.target.value.length > 10) {
e.target.style.fontSize = '12px';
} else {
e.target.style.fontSize = '16px';
}
return;
}, false);
Like this...
In JavaScript, access the text as
myInput = document.getElementById('tocall');
myText = myInput.value;
Then find the size of text as
len = myText.length
Now, check this value and use CSS to change font size.
if (len > 10) {
myInput.style.fontSize = "10px";
}