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"){
       ...