Given this code:
<textarea rows="4" cols="50"></textarea>
There are 4 rows to type.
However, how would you apply CSS to disable another row when a user presses enter or when the text overflows to the 5th row?
Given this code:
<textarea rows="4" cols="50"></textarea>
There are 4 rows to type.
However, how would you apply CSS to disable another row when a user presses enter or when the text overflows to the 5th row?
Share Improve this question edited Jul 25, 2022 at 20:38 Ry-♦ 225k56 gold badges492 silver badges499 bronze badges asked Jul 19, 2014 at 23:56 user1631224user1631224 4093 gold badges6 silver badges13 bronze badges 05 Answers
Reset to default 4To limit rows (lines) use JavaScript. You will need to do this by the input
event,
and to split the lines in an array you can use the String.prototype.split()
, after that the limit can be controlled with Array.prototype.slice(start, end)
, being start
must have the 0
, which will be the first line obtained, and end
being the maximum number of lines desired. Finally, we concatenate the array into a string.
See example:
Note that I used
setTimeout
to avoid multiple executions in case the user holds any key interruptly.
function limitText(textarea, limit) {
function limitLines() {
// split lines
var lines = textarea.value.split("\n");
if (lines.length > limit) {
textarea.value = lines.slice(0, limit).join("\n");
}
}
// Limite on add event
limitLines();
var timeout;
textarea.addEventListener("input", function () {
clearTimeout(timeout);
timeout = setTimeout(limitLines, 1);
});
}
limitText(document.getElementById("txtField1"), 4);
limitText(document.getElementById("txtField2"), 4);
<textarea rows="4" cols="50" id="txtField1">1
2
3
4</textarea>
<textarea rows="4" cols="50" id="txtField2">a
b
c
d</textarea>
Using a textarea
Too limit rows and characters in a textarea you can use my script I just made:
JAVASCRIPT:
function textarealimit(textarea, rows, chars, rowsleft_id, charsleft_id) {
var newValue;
var valueSegments = textarea.value.split('\n');
if(rows != undefined && valueSegments.length > rows) { // too many rows
newValue = valueSegments.slice(0, rows).join("\n");
}
if(chars != undefined && textarea.value.length > chars) { // too many chars
if(newValue != undefined)
newValue = newValue.substring(0, chars);
else
newValue = textarea.value.substring(0, chars);
}
if(newValue != undefined) textarea.value = newValue;
if(rowsleft_id != undefined) {
if(textarea.value == "") document.getElementById(rowsleft_id).innerHTML = rows;
else if(rows - valueSegments.length >= 0) document.getElementById(rowsleft_id).innerHTML = rows - valueSegments.length;
}
if(charsleft_id != undefined) {
if(chars != undefined) document.getElementById(charsleft_id).innerHTML = chars - textarea.value.length;
}
}
HTML:
<textarea onkeydown="textarealimit(this, 4, 43, 'textarea_rowsleft', 'textarea_charsleft');"
onkeyup="textarealimit(this, 4, 43, 'textarea_rowsleft', 'textarea_charsleft');"
onpaste="textarealimit(this, 4, 43, 'textarea_rowsleft', 'textarea_charsleft');"
rows="4" style="overflow: hidden; resize: none;">
</textarea>
<div>
Rows left: <span id="textarea_rowsleft">4</span>
Characters left: <span id="textarea_charsleft">43</span>
</div>
If you use HTML5 you can even limit the characters by the maxlength
attribute on the textarea control.
If you do not want to show the rows or chars left, just use onkey....="textarealimit(this, 4, 43);"
. You can even only limit the rows by using onkey....="textarealimit(this, 4);"
.
Here is a demo for you: http://jsfiddle/AmFnA/9/
The only limitation appears when the user gets new rows by auto line breaks due to the width limitation, so without pressing ENTER, because it will NOT count as new row. Also, you have to use keydown (when the user presses and holds this fires all the time), keyup (when the user releases, fires even when pressing ENTER) and onpaste (for richtclick -> paste), always.
Thanks to Guilherme for reminding me on the paste part with his shorter version of that solution.
Using multiple input fields
Now there is another alternative Jukka mentioned. You can use an input field for each row. This will prevent the user to get line breaks automatically. Here you can even listen up the keys to send the cursor to the next or previous box on the right conditions.
Build up your rows with input fields in your HTML:
<div class="rowfield_collection">
<input id="rowfield1" class="rowfield top" onkeydown="rowfieldkeynav(event, undefined, 'rowfield2');" type="text" size="35" maxlength="30" />
<input id="rowfield2" class="rowfield middle" onkeydown="rowfieldkeynav(event, 'rowfield1', 'rowfield3');" type="text" size="35" maxlength="30" />
<input id="rowfield3" class="rowfield middle" onkeydown="rowfieldkeynav(event, 'rowfield2', 'rowfield4');" type="text" size="35" maxlength="30" />
<input id="rowfield4" class="rowfield bottom" onkeydown="rowfieldkeynav(event, 'rowfield3', undefined);" type="text" size="35" maxlength="30" />
</div>
As you see, every input field got its own ID and you refer previous and next input field in the rowfieldkeynav call.
To style it and look it like a textarea you can use this CSS:
.rowfield {
margin: 0 0 -1px 0;
display: block;
}
.rowfield.top {
border-bottom: 0;
}
.rowfield.middle {
border-top: 0;
border-bottom: 0;
}
.rowfield.bottom {
border-top: 0;
}
And finally the JAVASCRIPT function:
function rowfieldkeynav(e, before_id, after_id) {
var evtobj = window.event ? event : e //distinguish between IE's explicit event object (window.event) and Firefox's implicit.
var unicode = evtobj.charCode ? evtobj.charCode : evtobj.keyCode;
if(before_id != undefined && e.currentTarget.value.length == 0 && unicode == 08) { // BACKSPACE
document.getElementById(before_id).focus();
}
else if(after_id != undefined && unicode == 13 || e.currentTarget.value.length >= e.currentTarget.maxLength) { // ENTER or end of row reached
document.getElementById(after_id).focus();
}
}
It will jump to the previous input field when the current input field is empty and you press BACKSPACE. It will jump to the next input field when you press ENTER or reach the maxlength length.
And again, here a demo for you: http://jsfiddle/6KVMS/2/
The only few downsides on this method are:
- It will jump into a new line in the middle of a word, so it will not take the current word with you into the new input field.
- You cannot select more than one row when using your mouse.
- You can jump in the next rows by clicking there
- If you remove a row above another filled row, the text will not go up
- IE8 and perhabs lower cries a bit: It will not skip to the next field when the row is full
You could do something like this in CSS:
textarea {
overflow:hidden;
resize:none;
}
This will turn off the possibility of resizing the textarea and hides everything except the number of rows specified.
Additionally you may wish to restrict the amount of characters for the textarea via maxlength
(Spec) which is possible since HTML5.
You cannot set such restrictions in CSS. You can set a maximum number of characters in HTML, but that’s not the same thing. You can use JavaScript that counts the lines and imposes restrictictions.
Normally, the best approach would seem to be to avoid the problem: instead of a textarea
element, use four input
elements. The downside is that the user needs to tab to the next field instead of just pressing Enter.
The HTML maxlength
attribute could be used, but HTML, CSS, and JavaScript can be hacked. Do a Sever side check to be sure. Client side should also be used, but won't prevent a potential issue.