'Find rendered newlines position with javascript in textarea
I have this textarea:
<textarea id="ifade" rows="6" cols="66" placeholder="...Start Writing in Arabic"></textarea>
and I have trying to do find character at both normal newline ('\n') and rendered newlines(or if I can insert the '\n' character to rendered newlines but I cannot do that also...)
var remainedPlace;
var inputValue = $("#textarea").val();
for (var j = 0; j < inputValue.length; j++) // from start of the textarea to the end of textarea ...
{
// I cannot detect rendered newlines below..:
for (var k = j; inputValue.charAt(k) != '\r\n' && inputValue.charAt(k) != '\r' && inputValue.charAt(k) != '\n'; k++) // from start of that line to the end of that line ...
{
/* doing some un-important stuff here:
for(var l = 0; l < selections.length; l++) // from selected letters
{
if(inputValue.charAt(k) == selections[l]) // every selected letters
lineSums[line]++; // increment as count in that line
remainedPlace = k;
}
*/
}
line++;
j = ++remainedPlace;
}
I want to find out width-size dynamic line break indexes of line break characters means that when we resize textarea horizontally it should render line breaks again and so our calculated rendered new line break indexes also should change
This textarea has less 2 rendered line-breaks:<br>
<textarea rows="3" cols="66">this text will broke/render new line breaks according to textarea width even though I have never used '\n' in it character, I want to find out that rendered line break indexes created according to textarea width</textarea>
<br><br>This textarea has less 6 rendered line-breaks:<br>
<textarea rows="7" cols="23">this text will broke/render new line breaks according to textarea width even though I have never used '\n' in it character, I want to find out that rendered line break indexes created according to textarea width</textarea>
This ( Find rendered line breaks with javascript ) question seems similar but it is not working for textarea hence I have not enough points I cannot asked in comments and so I have opened this new question.
Solution 1:[1]
With ALLAH's will I have fixed my problem with copying textarea value to new position fixed div then calculate rendered line-breaks in that div and much more(return rendered every line as a string in an array of strings) like this with some help of other stackoverflow reply thanks to them also... But their approach is not good for texts which has both right to left and left to right content like I have in MuqattaCounter.github.io so I have changed it little bit and now it looks from up to bottom in order to find new rendered lines and doesn't affect from rtl or ltr texts, it can handle both of them together
In order to see true console.log results first click "running code snippet" and then click "make it full page" and then resize the page
$(window).resize(function(){
console.log(getLineBreaks(document.querySelector('.copiedText')));
});
function getLineBreaks(elem) {
// our Range object form which we'll get the characters positions
const range = document.createRange();
// here we'll store all our lines
const lines = [];
const nodes = grabTextNodes(elem);
let bottom = 0;
// initial position
let prevBottom = null;
let lineText = "";
let startRange = null;
for (const node of nodes) {
let nodeText = node.textContent;
const textLength = nodeText.length;
let rangeIndex = 0;
let textIndex = 0;
while (rangeIndex <= textLength) {
range.setStart(node, rangeIndex);
if (rangeIndex < textLength - 1) {
range.setEnd(node, rangeIndex + 1); // wrap the range (for Chrome...)
}
bottom = range.getBoundingClientRect().bottom;
if (prevBottom === null) { // first pass
prevBottom = bottom;
startRange = range.cloneRange();
}
else if (bottom > prevBottom) { // line break
// store the current line content
lineText += nodeText.slice(0, textIndex);
startRange.setEnd(range.endContainer, range.endOffset);
const { bottom } = startRange.getBoundingClientRect();
lines.push(lineText);
// start a new line
prevBottom = bottom;
lineText = "";
nodeText = nodeText.slice(textIndex);
textIndex = 0;
startRange = range.cloneRange();
}
rangeIndex++;
textIndex++;
prevBottom = bottom;
}
// add the remaining text from this node into the current line content
lineText += nodeText;
}
// push the last line
startRange.setEnd(range.endContainer, range.endOffset);
//const { bottom } = startRange.getBoundingClientRect();
lines.push(lineText);
return lines;
}
function grabTextNodes(elem) {
const walker = document.createTreeWalker(elem, NodeFilter.SHOW_TEXT, null);
const nodes = [];
while (walker.nextNode()) {
nodes.push(walker.currentNode);
}
return nodes;
}
#copyText{
display:inline-block;
width: 361 px !important;
white-space: pre-wrap !important;
word-wrap: break-word !important;
position: fixed;
overflow: hidden !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="copyText" class="copiedText">13:0 ??? ???? ?????? ??????
13:1 ???? ??? ???? ????? ????? ???? ???? ?? ??? ???? ???? ???? ????? ?? ??????
13:2 ???? ???? ??? ?????? ???? ??? ?????? ?? ????? ??? ????? ???? ????? ?????? ?? ???? ???? ???? ???? ????? ???? ?????? ????? ????? ???? ??????
13:3 ??? ???? ?? ????? ???? ???? ???? ?????? ??? ?? ?????? ??? ???? ????? ????? ???? ???? ?????? ?? ?? ??? ????? ???? ???????
13:4 ??? ????? ??? ?????? ???? ?? ???? ???? ????? ???? ???? ???? ???? ???? ???? ????? ????? ??? ??? ?? ????? ?? ?? ??? ????? ???? ??????
13:5 ??? ???? ???? ????? ???? ??? ???? ???? ??? ??? ???? ????? ????? ????? ????? ?????? ?????? ?? ?????? ?????? ???? ????? ?? ???? ?????
13:6 ?????????? ??????? ??? ?????? ??? ??? ?? ????? ?????? ??? ??? ??? ????? ????? ??? ????? ??? ??? ????? ??????
13:7 ????? ????? ????? ???? ???? ???? ???? ?? ??? ???? ??? ???? ???? ??? ???
13:8 ???? ???? ?? ???? ?? ???? ??? ???? ??????? ??? ????? ??? ??? ???? ??????
13:9 ??? ????? ??????? ?????? ???????
13:10 ???? ???? ?? ??? ????? ??? ??? ?? ??? ?? ????? ????? ????? ???????
13:11 ?? ????? ?? ??? ???? ??? ???? ??????? ?? ??? ???? ?? ???? ?? ???? ?? ???? ??? ?????? ?? ??????? ???? ???? ???? ???? ???? ??? ??? ?? ??? ??? ?? ???? ?? ???
13:12 ?? ???? ????? ????? ???? ????? ????? ?????? ??????
13:13 ????? ????? ????? ???????? ?? ????? ????? ?????? ????? ??? ?? ???? ??? ?????? ?? ???? ??? ???? ??????
13:14 ?? ???? ???? ?????? ????? ?? ???? ?? ???????? ??? ???? ??? ???? ???? ??? ????? ????? ??? ??? ?? ????? ??? ???? ??????? ??? ?? ???
13:15 ???? ???? ?? ?? ?????? ?????? ???? ????? ?????? ?????? ????????
13:16 ?? ?? ?? ?????? ?????? ?? ???? ?? ???????? ?? ???? ?????? ?? ?????? ??????? ???? ??? ??? ?? ?? ????? ?????? ??????? ?? ?? ????? ?????? ?????? ?? ????? ??? ????? ????? ????? ????? ????? ????? ?? ???? ??? ?? ??? ??? ???? ?????
13:17 ???? ?? ?????? ??? ????? ????? ?????? ?????? ????? ???? ????? ???? ?????? ???? ?? ????? ?????? ???? ?? ??? ??? ???? ???? ???? ???? ???? ?????? ???? ????? ????? ???? ???? ?? ???? ????? ????? ?? ????? ???? ???? ???? ??????
13:18 ????? ???????? ????? ?????? ?????? ?? ???????? ?? ?? ?? ??? ?? ?? ????? ????? ????? ??? ??????? ?? ????? ??? ??? ?????? ??????? ???? ???? ??????
13:19 ???? ???? ???? ???? ???? ?? ??? ???? ??? ?? ???? ???? ????? ????? ??????
13:20 ????? ????? ???? ???? ??? ?????? ??????
13:21 ?????? ????? ?? ??? ???? ?? ?? ???? ?????? ???? ??????? ??? ??????
13:22 ?????? ????? ?????? ??? ???? ??????? ?????? ??????? ??? ?????? ??? ??????? ??????? ??????? ?????? ????? ??? ???? ?????
13:23 ??? ??? ???????? ??? ??? ?? ??????? ??????? ??????? ???????? ?????? ????? ?? ?? ???
13:24 ??? ????? ??? ????? ???? ???? ?????
13:25 ?????? ?????? ??? ???? ?? ??? ????? ??????? ?? ??? ???? ?? ?? ???? ??????? ?? ????? ????? ??? ?????? ???? ??? ?????
13:26 ???? ???? ????? ??? ???? ????? ?????? ??????? ?????? ??? ?????? ?????? ?? ??????? ??? ???
13:27 ????? ????? ????? ???? ???? ???? ???? ?? ??? ?? ?? ???? ??? ?? ???? ????? ???? ?? ????
13:28 ????? ?????? ?????? ?????? ???? ???? ??? ???? ???? ????? ??????
13:29 ????? ?????? ?????? ?????? ???? ??? ???? ????
13:30 ???? ?????? ?? ??? ?? ??? ?? ????? ??? ?????? ????? ???? ?????? ???? ??? ?????? ??????? ?? ?? ??? ?? ??? ??? ?? ???? ????? ????? ????
13:31 ??? ?? ?????? ???? ?? ?????? ?? ???? ?? ????? ?? ??? ?? ?????? ?? ??? ????? ????? ???? ????? ????? ?????? ?? ?? ???? ???? ???? ????? ????? ??? ???? ????? ????? ?????? ??? ????? ????? ?? ??? ????? ?? ????? ??? ???? ??? ???? ?? ???? ?? ???? ???????
13:32 ???? ?????? ???? ?? ???? ?????? ????? ????? ?? ?????? ???? ??? ????
13:33 ???? ?? ???? ??? ?? ??? ??? ???? ?????? ??? ????? ?? ????? ?? ??????? ??? ?? ???? ?? ????? ?? ???? ?? ????? ?? ??? ????? ????? ????? ????? ?? ?????? ??? ???? ???? ??? ?? ?? ???
13:34 ??? ???? ?? ?????? ?????? ?????? ??????? ??? ??? ??? ?? ???? ?? ???
13:35 ??? ????? ???? ??? ??????? ???? ?? ????? ?????? ????? ???? ????? ??? ???? ????? ????? ????? ??????? ?????
13:36 ?????? ??????? ????? ?????? ??? ???? ???? ??? ??????? ?? ???? ???? ?? ???? ???? ?? ???? ???? ??? ???? ?? ???? ????? ????? ????
13:37 ????? ?????? ???? ????? ???? ????? ??????? ??? ?? ???? ?? ????? ?? ?? ?? ???? ?? ??? ??? ???
13:38 ???? ?????? ???? ?? ???? ?????? ??? ????? ????? ??? ??? ????? ?? ???? ????? ??? ???? ???? ??? ??? ????
13:39 ????? ???? ?? ???? ????? ????? ?? ?????
13:40 ??? ?? ????? ??? ???? ????? ?? ??????? ????? ???? ????? ?????? ??????
13:41 ???? ???? ??? ???? ????? ?????? ?? ??????? ????? ???? ?? ???? ????? ??? ???? ??????
13:42 ??? ??? ????? ?? ????? ???? ????? ????? ???? ?? ???? ?? ??? ?????? ????? ??? ???? ?????
13:43 ????? ????? ????? ??? ????? ?? ??? ????? ????? ???? ?????? ??? ???? ??? ?????
</div>
Solution 2:[2]
Not 100% sure what exactly you needed as a return -- I assume it's the index of each line break. If not, comment my answer to let me know.
Details are commented in example below
// Get the text via HTMLFormElement interface
let txt = document.forms[0].elements[0].value;
// Create a RegExp object to match new lines
const rgx = new RegExp(/\n/, 'g');
/*
Run .matchAll() which returns an object
Wrap it in array brackets and apply the
...spread operator in order to access it.
Run the array through .map() and return
each match's .index value.
*/
let matches = [...txt.matchAll(rgx)];
matches = matches.map(match => match.index);
console.log(matches);
.as-console-row::after { width: 0; font-size: 0; }
.as-console-row-code { width: 100%; word-break: break-word; }
.as-console-wrapper { min-height: 100% !important; max-width: 30%; margin-left: 70%; }
<form>
<textarea rows='10' cols='50'>
Alan Rails, ladies and gentlemen. After his parents' tragic death in a railroad accident, he gained the power to summon ghost trains. It's not all bad though, they were spared having to see their grown son wear a whistle.
They're not infinite universes left in sync with the show.
Are you hungry for apples? ARE YOU HUNGRY FOR APPLESSS!?
Wha, me irresponsible ?! All I wanted you to do was to hand me a screwdriver, Morty!
</textarea>
</form>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | zer00ne |