I have a textarea with limited characters per line. Its function fine.
function limitRow(){
var count = 1;
var charsPerLine = row; // 30 characters
var maxLines = 20;
$('.AD_Text_textarea').keydown(function (e) {
var v = $(this).val(),
vl = v.replace(/(\r\n|\n|\r)/gm, '').length,
lineCount = $(this).val().split("\n").length;
if (parseInt(vl / count) >= charsPerLine) {
if (lineCount >= maxLines) {
return false;
}
$(this).val(v + "\n");
count += 1;
}
});
}
My question is, if Iam going to line 1, after typing for example 4 rows text and type on for example cursor position 4 some text, then the line counter counts of the beginning and breaks the line after 60 characters and jumps on the end of line 4.
How can I resolve this problem?
I hope, it was clear. (Iam sorry for my english)
try this
var count = 1;
var charsPerLine = 30; // 30 characters
var maxLines = 2;
$('.AD_Text_textarea').keydown(function (e) {
var this_input = $(this);
var value = this_input.val().split('\n');
if (value.length < maxLines) {
if (value[parseInt(value.length) - 1].toString().length > charsPerLine) {
alert(value.length.toString());
this_input.val(this_input.val() + '\n');
}
}
else {
return false;
}
});
Related
I have a function that wraps textboxes in FabricJS so that they don't become too wide, (it is automatically line breaking when the the maximum width is reached). However it is causing the text cursor to get pushed behind by 1 character every time it adds a new line.
Look at this gif to fully see the problem in play a gif
I am using the following function to automatically line break the text box. To give some context, it checks if the length of a textLine exceeds the maxWidth, and if it is the case with the last word included but doesn't exceed if the last word is not included, then it adds a new line by entering \n and somewhere here it causes the problem.
function wrapCanvasText(t, canvas, maxW, maxH) {
let initialFormatted = t.text
if (typeof maxH === "undefined") {
maxH = 0;
}
var words = t.text.split(" ")
var formatted = '';
// clear newlines
var sansBreaks = t.text.replace(/(\r\n|\n|\r)/gm, "");
// calc line height
var lineHeight = new fabric.Text(sansBreaks, {
fontFamily: t.fontFamily,
fontSize: t.fontSize
}).height;
// adjust for vertical offset
var maxHAdjusted = maxH > 0 ? maxH - lineHeight : 0;
var context = canvas.getContext("2d");
context.font = t.fontSize + "px " + t.fontFamily;
var currentLine = "";
var breakLineCount = 0;
for (var n = 0; n < words.length; n++) {
console.log(words[n])
var isNewLine = currentLine == " ";
var testOverlap = currentLine + ' ' + words[n] + ' ';
// are we over width?
var w = context.measureText(testOverlap).width;
if (w < maxW) { // if not, keep adding words
currentLine += words[n] + ' ';
formatted += words[n] += ' ';
} else {
// if this hits, we got a word that need to be hypenated
if (isNewLine) {
var wordOverlap = "";
// test word length until its over maxW
for (var i = 0; i < words[n].length; ++i) {
wordOverlap += words[n].charAt(i);
var withHypeh = wordOverlap + "-";
if (context.measureText(withHypeh).width >= maxW) {
// add hyphen when splitting a word
withHypeh = wordOverlap.substr(0, wordOverlap.length - 2) + "-";
// update current word with remainder
words[n] = words[n].substr(wordOverlap.length - 1, words[n].length);
formatted += withHypeh; // add hypenated word
break;
}
}
}
n--; // restart cycle
if (words[n+1] !== '') {
formatted += '\n';
breakLineCount++;
}
currentLine = "";
}
if (maxHAdjusted > 0 && (breakLineCount * lineHeight) > maxHAdjusted) {
// add ... at the end indicating text was cutoff
formatted = formatted.substr(0, formatted.length - 3) + "...\n";
break;
}
}
// get rid of empy newline at the end
formatted = formatted.substr(0, formatted.length - 1);
return formatted;
}
You can try out this snippet it is an approximate version of what I have, most importantly, it does have the same cursor problem. To try out the problem, edit the text directly in the canvas after initialization.
var canvas = new fabric.Canvas('c');
canvas.backgroundColor = "#F5F5F5";
var textArea = document.getElementById('addNote');
function checkForChange() {
var activeObject = canvas.getActiveObject();
let formatted1 = wrapCanvasText(activeObject, canvas, 400, 2000);
activeObject.text = formatted1;
}
function wrapCanvasText(t, canvas, maxW, maxH) {
let initialFormatted = t.text
if (typeof maxH === "undefined") {
maxH = 0;
}
var words = t.text.split(" ")
var formatted = '';
// clear newlines
var sansBreaks = t.text.replace(/(\r\n|\n|\r)/gm, "");
// calc line height
var lineHeight = new fabric.Textbox(sansBreaks, {
fontFamily: t.fontFamily,
fontSize: t.fontSize
}).height;
// adjust for vertical offset
var maxHAdjusted = maxH > 0 ? maxH - lineHeight : 0;
var context = canvas.getContext("2d");
context.font = t.fontSize + "px " + t.fontFamily;
var currentLine = "";
var breakLineCount = 0;
for (var n = 0; n < words.length; n++) {
console.log(words[n])
var isNewLine = currentLine == " ";
var testOverlap = currentLine + ' ' + words[n] + ' ';
// are we over width?
var w = context.measureText(testOverlap).width;
if (w < maxW) { // if not, keep adding words
currentLine += words[n] + ' ';
formatted += words[n] += ' ';
} else {
// if this hits, we got a word that need to be hypenated
if (isNewLine) {
var wordOverlap = "";
// test word length until its over maxW
for (var i = 0; i < words[n].length; ++i) {
wordOverlap += words[n].charAt(i);
var withHypeh = wordOverlap + "-";
if (context.measureText(withHypeh).width >= maxW) {
// add hyphen when splitting a word
withHypeh = wordOverlap.substr(0, wordOverlap.length - 2) + "-";
// update current word with remainder
words[n] = words[n].substr(wordOverlap.length - 1, words[n].length);
formatted += withHypeh; // add hypenated word
break;
}
}
}
n--; // restart cycle
if (words[n + 1] !== '') {
formatted += '\n';
breakLineCount++;
}
currentLine = "";
}
if (maxHAdjusted > 0 && (breakLineCount * lineHeight) > maxHAdjusted) {
// add ... at the end indicating text was cutoff
formatted = formatted.substr(0, formatted.length - 3) + "...\n";
break;
}
}
// get rid of empy newline at the end
formatted = formatted.substr(0, formatted.length - 1);
return formatted;
}
$("#addNote").keyup(function(e) {
var activeObject = canvas.getActiveObject();
if (activeObject && activeObject.type == 'textbox') {
activeObject.text = textArea.value
let formatted1 = wrapCanvasText(activeObject, canvas, 400, 2000);
activeObject.text = formatted1;
while (activeObject.textLines.length > 1 && canvas.getWidth() * 0.8 >= activeObject.width) {
activeObject.set({
width: activeObject.getScaledWidth() + 1
})
}
canvas.renderAll();
} else {
var textSample = new fabric.Textbox(textArea.value, {});
textSample.left = 0
textSample.splitByGrapheme = true
textSample.lockRotation = true
textSample.editable = true
textSample.perPixelTargetFind = false
textSample.hasControls = true
textSample.width = canvas.getWidth() * 0.8
textSample.height = canvas.getHeight() * 0.8
textSample.maxWidth = canvas.getWidth() * 0.8
textSample.maxHeight = canvas.getHeight() * 3
canvas.add(textSample);
canvas.setActiveObject(textSample);
canvas.renderAll();
}
canvas.on('text:changed', checkForChange)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js"></script>
<textarea id="addNote"></textarea>
<canvas id="c" width="400" height="400"></canvas>
How can i apply bullets in this below mentioned code after line break. I mean when i break line, i need next line to start with the bullet. Also please apply css animation on this code. Also apply timing i-e when i run code, i can control after how many milliseconds the typing starts and when typing ends, i can control after how many milliseconds it starts again. Thanks
var typeString = ['I\'m Mr. Frits and I love Pakistan...:)'];
var i = 0;
var count = 0
var selectedText = '';
var text = '';
(function type() {
if (count == typeString.length) {
count = 0;
}
selectedText = typeString[count];
text = selectedText.slice(0, ++i);
document.getElementById('typing').innerHTML = text.fontsize(6);
document.getElementById('typing').style.fontFamily = "monospace";
document.getElementById("typing").style.color = "black";
document.getElementById("typing").style.fontWeight = "normal";
if (text.length === selectedText.length) {
count++;
i = 0;
}
setTimeout(type, 300);
}());
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
<pre id="typing" class="typing"></pre>
Just add \n and the unicode •
var typeString = ['• I\'m Mr. Frits\n• and I love Pakistan...:)'];
var i = 0;
var count = 0
var selectedText = '';
var text = '';
(function type() {
if (count == typeString.length) {
count = 0;
}
selectedText = typeString[count];
text = selectedText.slice(0, ++i);
document.getElementById('typing').innerHTML = text.fontsize(6);
document.getElementById('typing').style.fontFamily = "monospace";
document.getElementById("typing").style.color = "black";
document.getElementById("typing").style.fontWeight = "normal";
if (text.length === selectedText.length) {
count++;
i = 0;
}
setTimeout(type, 300);
}());
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
<pre id="typing" class="typing"></pre>
use • for the bullet character when generating the text variable
text = '• '+ selectedText.slice(0, ++i);
In JS i need to add span as wrapper on the entire document text words.using below code i can able to add wrapper
function walk(root)
{
if (root.nodeType == 3) // text node
{
doReplace(root);
return;
}
var children = root.childNodes;
for (var i = 0;i<children.length ;i++)
{
walk(children[i]);
}
}
function doReplace(text)
{
var start = counter;
counter = counter+text.nodeValue.length;
var div = document.createElement("div");
var string = text.nodeValue;
var len = string.trim();
if(len.length == 0){
return;
}
var nespan = string.replace(/\b(\w+)\b/g,function myFunction(match, contents, offset, s){
var end = start + contents.length;
var id = start+"_"+end;
start = end;
return "<span class='isparent' id='"+id+"'>"+contents+"</span>";
});
div.innerHTML = nespan;
var parent = text.parentNode;
var children = div.childNodes;
for (var i = children.length - 1 ; i >= 0 ; i--)
{
parent.insertBefore(children[i], text.nextSibling);
}
parent.removeChild(text);
}
using above code ill get below result
input :
Stackoverflow is good
out put:
<span>Stackoverflow</span> <span>is</span> <span>good</span>
expecting result:
<span>Stackoverflow </span><span>is </span><span>good</span>
Add optional space character to your regex after the word but before the second word boundary: \b(\w+\s*)\b
EDIT: If anyone, ever need this script for some reason, i made a cleaner fully working version: https://jsfiddle.net/qmgob1d5/3/
I have a jquery script that is supposed to highlight elements in a from-to manner. It should work backwards as well.
Here is working fiddle: https://jsfiddle.net/qmgob1d5/
It works fine, until I select zero (first box) as second element. Then the var Start = Math.min(ClickOne, ClickTwo || 16); doesn't seems to work as expected. What went wrong?
Here is the script:
var FirstClick;
var ClickOne;
var ClickTwo;
$('.ColorPreview').on('click',function() {
var ColorId = $(this).attr('id');
ColorId = Number(ColorId.split('_')[1]);
if (!FirstClick) {
//reset function
for (var i = 0; i < 16; i++) {
$('#Color_' + i).removeClass('SelectColor'); }
var ClickTwo;
ClickOne = ColorId;
FirstClick = true;
}
else {
ClickTwo = ColorId;
FirstClick = false; }
console.log('ClickOne ' + ClickOne)
console.log('Clicktwo ' + ClickTwo)
var Start = Math.min(ClickOne, ClickTwo || 16);
var End = Math.max(ClickOne, ClickTwo || 0);
console.log('start ' + Start)
console.log('end ' + End)
for (var i = Start; i <= End; i++) {
$('#Color_' + i).addClass('SelectColor'); }
});
When ClickTwo is 0, the expression ClickTwo || 16 will evaluate to 16.
Try
var Start = Math.min(ClickOne, ClickTwo == null ? 16 : ClickTwo);
Or else initialize ClickTwo to 16 at the beginning of the function.
I have used a code that show the line number from textarea and it works with me.But i would like to show a string beside that so the output will be:
Line number: 3
here is the code that I have used:
http://jsfiddle.net/S2yn3/1/
and the function is:
$(function() {
$('#test').keyup(function() {
var pos = 0;
if (this.selectionStart)
pos = this.selectionStart;
} else if (document.selection) {
this.focus();
var r = document.selection.createRange();
if (r == null) {
pos = 0;
} else {
var re = this.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
pos = rc.text.length;
}
}
$('#c').html(this.value.substr(0, pos).split("\n").length);
});
});
Thanks guys
Your code is counting the number of '\n' characters from the first character to the cursor. If you're looking for the total number of linebreaks, change...
$('#c').html(this.value.substr(0, pos).split("\n").length);
to
$('#c').html('Line no. ' + this.value.split("\n").length);