JSFiddle - React, Tailwind, and code Playground
by ngoctuan001
HTML
<textarea type="text" class="inactive" rows="1" id="flexibleInputField" onInput="formatTextAsRequired()" placeholder="Your input"></textarea>
CSS
textarea{width: 343px; font-size: 14px; resize: none;outline: none; margin:0; border:none;border-radius:0px;}
textarea::placeholder {color:#ccc;}
textarea.active {border-bottom:2px solid #c69311; transition: border-width 0.1s ease-out;}
textarea.inactive{border-bottom:1px solid #666666; transition: border-width 0.1s ease-out;}
JavaScript
var charactersPerLine=12;
var maxLines=3;
var textOutput="";
function formatTextAsRequired() {
/*
This function handles two aspects:
1. (a) READ VALUE from the textarea, (b) DETECT IF TEXT PER LINE IS TOO LONG as required by the length restrictions, (c) PUSH OVERFLOWING TEXT from a line to the next line and (d) WRITE VALUE back to the textarea.
2. (a) READ THE CURSOR POSITION to store the cursor position, and (b) POSITION THE CURSOR where a user would expect it after WRITE DATA.
*/
var textInput=document.getElementById("flexibleInputField").value;//1a: READ VALUE
var inputAsRows=textInput.split("\n");// create array from input => each element contains one row of the textarea
var inputAsOneLine=textInput.replace(/(\r\n\t|\n|\r\t)/gm,"");//remove all line-breaks
var cursorPositionOnInput=document.getElementById("flexibleInputField").selectionStart;//2a: READ CURSOR POSITION
var cursorOffsetAfterOutput=0;//set default value for cursor offset. cursor offset is needed when re-posiotioning the cursor after WRITE DATA
var totalRows=inputAsRows.length; //don't put inputAsRows.length in the for statement, as the array is growing in the loop which results in an infinite loop
var row;
var lineBreakCount=0;
var characterCount=0;
for (row = 0; row < totalRows; ++row) {
if(inputAsRows[row].length>charactersPerLine){ //1b DETECT IF TEXT PER LINE IS TOO LONG
if (inputAsRows[row+1] === undefined) {
inputAsRows[row+1]="";// the row did not exist
totalRows++;
}
//1c PUSH OVERFLOWING TEXT: move text that is too long for this row to the next row:
inputAsRows[row+1]=inputAsRows[row].substring(charactersPerLine)+inputAsRows[row+1];
inputAsRows[row]=inputAsRows[row].substring(0,charactersPerLine);
//determine, if cursor was at the end of the line that got a line-break:
var newOutput=inputAsRows.join("\n");
if(newOutput.substr(cursorPositionOnInput-1,1)=="\n"){
...