finding "line-breaks" in textarea that is word-wrapping ARABIC text
Here is a functionally-equivalent implementation of Shadow Wizard's solution that is much faster because it uses binary search instead of linear search to determine the length of each line:
function ApplyLineBreaks(strTextAreaId) {
var oTextarea = document.getElementById(strTextAreaId);
if (oTextarea.wrap) {
oTextarea.setAttribute("wrap", "off");
}
else {
oTextarea.setAttribute("wrap", "off");
var newArea = oTextarea.cloneNode(true);
newArea.value = oTextarea.value;
oTextarea.parentNode.replaceChild(newArea, oTextarea);
oTextarea = newArea;
}
var strRawValue = oTextarea.value;
oTextarea.value = "";
var nEmptyWidth = oTextarea.scrollWidth;
function testBreak(strTest) {
oTextarea.value = strTest;
return oTextarea.scrollWidth > nEmptyWidth;
}
function findNextBreakLength(strSource, nLeft, nRight) {
var nCurrent;
if(typeof(nLeft) == 'undefined') {
nLeft = 0;
nRight = -1;
nCurrent = 64;
}
else {
if (nRight == -1)
nCurrent = nLeft * 2;
else if (nRight - nLeft <= 1)
return Math.max(2, nRight);
else
nCurrent = nLeft + (nRight - nLeft) / 2;
}
var strTest = strSource.substr(0, nCurrent);
var bLonger = testBreak(strTest);
if(bLonger)
nRight = nCurrent;
else
{
if(nCurrent >= strSource.length)
return null;
nLeft = nCurrent;
}
return findNextBreakLength(strSource, nLeft, nRight);
}
var i = 0, j;
var strNewValue = "";
while (i < strRawValue.length) {
var breakOffset = findNextBreakLength(strRawValue.substr(i));
if (breakOffset === null) {
strNewValue += strRawValue.substr(i);
break;
}
var nLineLength = breakOffset - 1;
for (j = nLineLength - 1; j >= 0; j--) {
var curChar = strRawValue.charAt(i + j);
if (curChar == ' ' || curChar == '-' || curChar == '+') {
nLineLength = j + 1;
break;
}
}
strNewValue += strRawValue.substr(i, nLineLength) + "\n";
i += nLineLength;
}
oTextarea.value = strNewValue;
oTextarea.setAttribute("wrap", "");
}
Updated fiddle.
Well, instead of finding the line breaks (which is virtually impossible) you can force them into the textarea, using this function:
function ApplyLineBreaks(strTextAreaId) {
var oTextarea = document.getElementById(strTextAreaId);
if (oTextarea.wrap) {
oTextarea.setAttribute("wrap", "off");
}
else {
oTextarea.setAttribute("wrap", "off");
var newArea = oTextarea.cloneNode(true);
newArea.value = oTextarea.value;
oTextarea.parentNode.replaceChild(newArea, oTextarea);
oTextarea = newArea;
}
var strRawValue = oTextarea.value;
oTextarea.value = "";
var nEmptyWidth = oTextarea.scrollWidth;
var nLastWrappingIndex = -1;
for (var i = 0; i < strRawValue.length; i++) {
var curChar = strRawValue.charAt(i);
if (curChar == ' ' || curChar == '-' || curChar == '+')
nLastWrappingIndex = i;
oTextarea.value += curChar;
if (oTextarea.scrollWidth > nEmptyWidth) {
var buffer = "";
if (nLastWrappingIndex >= 0) {
for (var j = nLastWrappingIndex + 1; j < i; j++)
buffer += strRawValue.charAt(j);
nLastWrappingIndex = -1;
}
buffer += curChar;
oTextarea.value = oTextarea.value.substr(0, oTextarea.value.length - buffer.length);
oTextarea.value += "\n" + buffer;
}
}
oTextarea.setAttribute("wrap", "");
}
This function get ID of textarea and whenever there is word wrap, it push new line break into the textarea. Run the function in the form submit and you will get the text with proper line breaks in the server side code.
Tested successfully for IE, Chrome and Firefox feel free to see for yourself here: http://jsfiddle.net/yahavbr/pH79a/1/ (The preview will show the new lines)