textarea with limited lines and char limits - javascript

i need functionaliy which will have TextArea with
1) maximum total lines- 6 and
2) in each line there must be maximum of 16 chars
3) if user enters 17th character the cursor should go to the next line
and user will type in there (the line will be counted)
4) if user reaches to the 7th line it will not allow user to write
5) if user type e.g "Hello, I Love StackOverflow and its features" (counting
from 1st Char 'H', the 16th char is 't' but it is whole word 'StackOverflow',
it shouldn't break and continue to next line e.g.
Hello, I Love St
ackOverflow
now the whole word should come to next line like:
Hello, I Love
StackOverflow
and its features
here is the link what i have done so far
http://jsfiddle.net/nqjQ2/2/
sometimes some of the functionality work, some times not, and facing browser issues for onKeyUp and onKeyDown
can anyone help me with it ?

I think this is mostly what you want:
<textarea id="splitLines"></textarea>
JavaScript:
var textarea = document.getElementById("splitLines");
textarea.onkeyup = function() {
var lines = textarea.value.split("\n");
for (var i = 0; i < lines.length; i++) {
if (lines[i].length <= 16) continue;
var j = 0; space = 16;
while (j++ <= 16) {
if (lines[i].charAt(j) === " ") space = j;
}
lines[i + 1] = lines[i].substring(space + 1) + (lines[i + 1] || "");
lines[i] = lines[i].substring(0, space);
}
textarea.value = lines.slice(0, 6).join("\n");
};
See the fiddle in action.

In Jquery
$(function () {
var limit = function (event) {
var linha = $(this).attr("limit").split(",")[0];
var coluna = $(this).attr("limit").split(",")[1];
var array = $(this)
.val()
.split("\n");
$.each(array, function (i, value) {
array[i] = value.slice(0, linha);
});
if (array.length >= coluna) {
array = array.slice(0, coluna);
}
$(this).val(array.join("\n"))
}
$("textarea[limit]")
.keydown(limit)
.keyup(limit);
})
<textarea limit='10,5' cols=10 rows=5 ></textarea>
http://jsfiddle.net/PVv6c/

Related

How to retain spaces in input strings of Caesar Cipher for javascript?

This project is in javascript. I need to make sure the output retains spaces found in the string that is inputted into the function. The test I am trying to pass is calling the function for the term "hello world" with a shift of 13 letters. From this code, the result is "uryybjbeyq" and "uryyb jbeyq" is expected. I have identified I need an if statement which I have included already, but not sure what command I should include before the continue keyword that will insert the space needed. I am a beginner and this is only my 3rd project so any assistance would be appreciated. Please find the corresponding code below.
function caesarCypher(string, num){
// line below is the encrypted string we will return from the function
const letters = 'abcdefghijklmnopqrstuvwxyz';
let encryptStr = ""
// loop through every character in the inputted string
for(let i = 0; i < string.length; i++){
// line below will look up index of char in alphabet
let char = string[i];
/* if statement below is attempting to identify the space in the original string and then add a command that will add a space to the encrypted string then continue to work through the rest of the input */
if (char === " ") {
//need something to put on this line to insert space;
continue;
}
let index = letters.indexOf(char);
// index + num below will give us the letter 7 spots over
let newIndex = index + num;
// if statement below makes the function loop back around
if (newIndex > 26) {
newIndex = newIndex - 26;
}
let newChar = letters[newIndex];
encryptStr += newChar;
}
return encryptStr;
}
/* invoke the function with these parameters to pass the test-- expected result is 'uryyb jbeyq'*/
caesarCypher("hello world", 13)
You can add the white space like this:
encryptStr += " ";
I tried your code and I ran into an error... All letters were the same. Here is how I did it:
function caesarCypher(string, num){
let encryptStr = "";
for(let i = 0; i < string.length; i++){
let char = string[i];
if (char === " ") {
encryptStr += " "; //This adds a white space.
continue;
}
// If you want to keep the case of a letter, skip the
// "toLowerCase()" and extend the condition below.
let asciiCode = string.toLowerCase().charCodeAt(i) + num;
if(asciiCode > 122) {
asciiCode -= 26;
}
encryptStr += String.fromCharCode(asciiCode);
}
return encryptStr;
}

Removing duplicate spaces from input

<textarea id="check" cols="50" rows="20"></textarea>
<script>
var text = document.getElementById("check").value;
var lengthA = text;
for (var i = 0; i < lengthA.length; i++) {
var space = " ";
if (lengthA[i] === space) {
var next = lengthA[i] + 1;
if (next === space) {
lengthA.replace(lengthA[i], "");
}
}
}
var length3 = lengthA.length - length2;
var words = length3 + 1;
</script>
Alright bois, me got a problemo! Im attempting to make a word counter through the law that each space equals a word (1:1). Im not sure why it is not working, it makes sense to me in my mind. I have attempted several alternatives and dwelled hours upon trying to fix this chunk. Thank you in advance to anyone that answers, even if it doesn't work! :)
EDIT: Regular expressions did the trick and replaced the incorrectly used for loop and if statements. Thanks
How about just the below -
var text = document.getElementById("check").value.replace (/ +/g, " ");
Not sure, why you would need a for loop to begin with.
/ +/ will more than 1 space
g will do all the changes throughout the text
To remove the duplicate space, the following code
lengthA.replace(lengthA[i], "");
should be
lengthA = lengthA.substring(0, i) + lengthA.substring(i + 1);
// i should not increase
i--;
continue;
You misunderstand the usage of replace.
Use str.replace() of JavaScript to do this. This will remove not only space but also work for tabs, newlines etc.
Usage:
var string = string.replace(/\s\s+/g, ' ');
So change below code:
var lengthA = text;
for (var i = 0; i < lengthA.length; i++) {
var space = " ";
if (lengthA[i] === space) {
var next = lengthA[i] + 1;
if (next === space) {
lengthA.replace(lengthA[i], "");
}
}
}
To this:
var lengthA = text.replace(/\s\s+/g, ' ');
Reference here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace

Use two inputs to look like textarea

I've tried to solve this by my own but I've been struggling a lot.
I've got 5 inputs that are stick together (they actually look like a textarea), and what I'm trying to do, is to fix a limit of the number of characters in each input, and when we reach the char limit, the cursor automatically focus on the next input and paste the last word that we couldn't entirely write in the last input before and if we erase few characters of this word, its goes back to the previous input (only if the characters limits isn't reached).
Here's what I tried to do:
function passage(enCours, suivant, limite){
if (enCours.value.length == limite)
{
$('#cmzTextLines'+suivant).focus();
}
}
function test(now, suivant){
var text = $('#cmzTextLines'+now).val();
var textSuivant = $('#cmzTextLines'+suivant).val();
//var lines = text.split("\n");
for (var i = 0; i < text.length; i++) {
if (text[i].length <= maxLength) continue;
var j = 0; space = maxLength;
while (j++ <= maxLength) {
if (text[i].charAt(j) === " ") space = j;
}
textSuivant = text[i].substring(space + 1) + (textSuivant || "");
text[i] = text[i].substring(0, space);
}
}
The HTML:
<input type="text" class="form-control" id="cmzTextLines1" name="cmzTextLines1" onkeyup="passage(this, 2, 30); test(1, 2);">
<input type="text" class="form-control" id="cmzTextLines2" name="cmzTextLines2"
onkeyup="passage(this, 3, 30); test(2, 3);">
JSFiddle: https://jsfiddle.net/fumm44f3/2/
var replacedval = rawval.substring(0, rawval.length - lastwordlength);
$(this).val(replacedval);
$(this).next(".form-control").val(lastword);
It'd be simple enough from here to check to see if an input has 0 characters on backspace as it already checks for backspace, and then go to prev input if so.

Limiting number of lines and letters in single line in textarea

Problem:
I am trying to limit number of lines AND letters in each line in a textbox.
What i got so far:
So far i managed to limit lines count using this:
var text = $(this).val();
var lines = text.split("\n");
if(e.keyCode == 13 && lines.length >= $(this).attr('rows')) {
return false;
}
This won't allow user to push return key (keyCode 13) if the limit of lines is reached.
The problem:
Now i am trying to limit number of letters in a single line too, because if i reach end of my textarea (with return key) i still can hold a letter/write tons of text, and it will jump to another line when it reaches end of line. That way this limitation can be "cheated" and i am looking for a solution for that.
My ideas, not solving the problem:
else{
for(var i = 0; i < lines.length && e.keyCode != 13; i++) {
if(lines[i].length >= $(this).attr('cols')) {
return false; // prevent characters from appearing
}
}
}
I tried this to limit number of letters. That works, but it got flaws. If i reach max letters in one line (ANY), i CANT TYPE IN ANY LINE anymore.
I have no idea how to check only line i am typing in RIGHT NOW.
Tested in chrome :
http://jsfiddle.net/3e3EH/1/
$(document).ready(function(){
var textArea = $('#foo');
var maxRows = textArea.attr('rows');
var maxChars = textArea.attr('cols');
textArea.keypress(function(e){
var text = textArea.val();
var lines = text.split('\n');
if (e.keyCode == 13){
return lines.length < maxRows;
}
else{
var caret = textArea.get(0).selectionStart;
console.log(caret);
var line = 0;
var charCount = 0;
$.each(lines, function(i,e){
charCount += e.length;
if (caret <= charCount){
line = i;
return false;
}
//\n count for 1 char;
charCount += 1;
});
var theLine = lines[line];
return theLine.length < maxChars;
}
});
});​
Edit
As jbabey pointed out, ctrl+v or right-click -> paste can be an issue. right click can easily be prevented. for ctrl+v, you probable can detect it too...
Just disabling javascript will obviously break the thing, too.
Anyways, as any client-side validation, you have to double check on server-side.
Here's what I came up with. Fairly clean and seems to work for all the tests I can give it.
JavaScript:
$(function () {
$('textarea').on('keypress', function (event) {
var text = $('textarea').val();
var lines = text.split("\n");
var currentLine = this.value.substr(0, this.selectionStart).split("\n").length;
console.log(lines);
console.log(currentLine);
console.log(lines[currentLine - 1]);
if (event.keyCode == 13) {
if (lines.length >= $(this).attr('rows')) return false;
} else {
if (lines[currentLine - 1].length >= $(this).attr('cols')) {
return false; // prevent characters from appearing
}
}
});
});
HTML:
<textarea rows="10" cols="15"></textarea>
DEMO
Instead of looping over each line get the current line number of your cursor and check only the character length of that line. See this SO answer for implementation details.
Then change your else statement to look like this:
else{
var currLine = getLineNumber();
if (lines[currLine].length >= $(this.attr('cols')) {
return false; // prevent characters from appearing
}
}
A little late, but i made this plugin https://github.com/luisdalmolin/jquery-limitLines.
Can be usefull sometimes.

Extract keyphrases from text (1-4 word ngrams)

What's the best way to extract keyphrases from a block of text? I'm writing a tool to do keyword extraction: something like this. I've found a few libraries for Python and Perl to extract n-grams, but I'm writing this in Node so I need a JavaScript solution. If there aren't any existing JavaScript libraries, could someone explain how to do this so I can just write it myself?
I like the idea, so I've implemented it: See below (descriptive comments are included).
Preview at: https://jsfiddle.net/WsKMx
/*#author Rob W, created on 16-17 September 2011, on request for Stackoverflow (http://stackoverflow.com/q/7085454/938089)
* Modified on 17 juli 2012, fixed IE bug by replacing [,] with [null]
* This script will calculate words. For the simplicity and efficiency,
* there's only one loop through a block of text.
* A 100% accuracy requires much more computing power, which is usually unnecessary
**/
var text = "A quick brown fox jumps over the lazy old bartender who said 'Hi!' as a response to the visitor who presumably assaulted the maid's brother, because he didn't pay his debts in time. In time in time does really mean in time. Too late is too early? Nonsense! 'Too late is too early' does not make any sense.";
var atLeast = 2; // Show results with at least .. occurrences
var numWords = 5; // Show statistics for one to .. words
var ignoreCase = true; // Case-sensitivity
var REallowedChars = /[^a-zA-Z'\-]+/g;
// RE pattern to select valid characters. Invalid characters are replaced with a whitespace
var i, j, k, textlen, len, s;
// Prepare key hash
var keys = [null]; //"keys[0] = null", a word boundary with length zero is empty
var results = [];
numWords++; //for human logic, we start counting at 1 instead of 0
for (i=1; i<=numWords; i++) {
keys.push({});
}
// Remove all irrelevant characters
text = text.replace(REallowedChars, " ").replace(/^\s+/,"").replace(/\s+$/,"");
// Create a hash
if (ignoreCase) text = text.toLowerCase();
text = text.split(/\s+/);
for (i=0, textlen=text.length; i<textlen; i++) {
s = text[i];
keys[1][s] = (keys[1][s] || 0) + 1;
for (j=2; j<=numWords; j++) {
if(i+j <= textlen) {
s += " " + text[i+j-1];
keys[j][s] = (keys[j][s] || 0) + 1;
} else break;
}
}
// Prepares results for advanced analysis
for (var k=1; k<=numWords; k++) {
results[k] = [];
var key = keys[k];
for (var i in key) {
if(key[i] >= atLeast) results[k].push({"word":i, "count":key[i]});
}
}
// Result parsing
var outputHTML = []; // Buffer data. This data is used to create a table using `.innerHTML`
var f_sortAscending = function(x,y) {return y.count - x.count;};
for (k=1; k<numWords; k++) {
results[k].sort(f_sortAscending);//sorts results
// Customize your output. For example:
var words = results[k];
if (words.length) outputHTML.push('<td colSpan="3" class="num-words-header">'+k+' word'+(k==1?"":"s")+'</td>');
for (i=0,len=words.length; i<len; i++) {
//Characters have been validated. No fear for XSS
outputHTML.push("<td>" + words[i].word + "</td><td>" +
words[i].count + "</td><td>" +
Math.round(words[i].count/textlen*10000)/100 + "%</td>");
// textlen defined at the top
// The relative occurence has a precision of 2 digits.
}
}
outputHTML = '<table id="wordAnalysis"><thead><tr>' +
'<td>Phrase</td><td>Count</td><td>Relativity</td></tr>' +
'</thead><tbody><tr>' +outputHTML.join("</tr><tr>")+
"</tr></tbody></table>";
document.getElementById("RobW-sample").innerHTML = outputHTML;
/*
CSS:
#wordAnalysis td{padding:1px 3px 1px 5px}
.num-words-header{font-weight:bold;border-top:1px solid #000}
HTML:
<div id="#RobW-sample"></div>
*/
I do not know such a library in JavaScript but the logic is
split text into array
then sort and count
alternatively
split into array
create a secondary array
traversing each item of the 1st array
check whether current item exists in secondary array
if not exists
push it as a item's key
else
increase value having a key = to item sought.
HTH
Ivo Stoykov
function ngrams(seq, n) {
to_return = []
for (let i=0; i<seq.length-(n-1); i++) {
let cur = []
for (let j=i; j<seq.length && j<=i+(n-1); j++) {
cur.push(seq[j])
}
to_return.push(cur.join(''))
}
return to_return
}
> ngrams(['a', 'b', 'c'], 2)
['ab', 'bc']

Categories