I'm trying to warning the user if he types a word that is not necessary in a textarea.
its just a little validation for some words.
i reach making something like this:
var words = "hello";
$("textarea").keyup(function(e){
var spliting = $("textarea").val().split(" ");
if(e.keyCode == 32){ // when the user hits space bar
if($.inArray(words, spliting) != -1){
$("span").css("background","red");
}else{
$("span").css("background","green");
}
}
});
is this the best way of doing this ?
and how can i migrate the variable words as a array, if i need to check more then one word?
Demo
To use an array, you will need to loop over each word in it and loop over each word in the split array. However, you can return on the first match:
var words = ["hello","goodbye"];
$("textarea").keyup(function(e){
var spliting = $("textarea").val().split(" ");
for (var i=0; i<words.length; i++) {
if($.inArray(words[i], spliting) != -1){
$("span").css("background","red");
// break on first match since there is no need to continue looping
// if it is already red.
break;
}else{
$("span").css("background","green");
}
}
});
I have removed the check for spaces. Even though it makes the function more efficient, you need to be wary of cases when someone goes back to correct spelling and ends up with an invalid word. The way you had it, those cases would never cause the flagged words to be found unless a space was typed later.
It would be advisable to call this function for onchange and blur events as well, since typing is not the only way users enter input into form inputs.
Here is the updated demo
You don't need to .split the input every time a key is pressed, this is a situation where a regular expression is to be preferred:
Check the updated fiddle
To generate the expression based on an array:
var blackList = ['hello','world'];
var expression = new RegExp('\\b(' + blackList.join('|') + ')\\b','i');
$("textarea").keyup(function(e)
{
//if (e.keyCode === 32)
//{in comment after reading the answer posted by Michael Berkowski
if ($(this).val().match(expression))
{
$("span").css("background","red");
return;
}
$("span").css("background","green");
//}
});
Related
I want my code to check if a variable has increased. For example, I have a function that looks for the letter A in a text box, which runs every time a key is pressed. Then it counts the number of A's it has found. Then I want to alert me everytime a new A is written. I thought I could do this easily by just checking if the var numberOfA has increased in an if statement, and if it has to alert me, but I can't figure it out. I have tried using ++ and =/== in my if statement, but it alerts me every single time a letter is typed, instead of only everytime an A has been typed. All help is appreciated, I'm pretty new at this.
function checkForA(){
var sentence = document.getElementById("userText").value.match(/a/g);
var numberOfA = sentence.length;
if (numberOfA = numberOfA +1) {
alert(" The letter A has been typed ");
}
}
Several problems.
When you write numberOfA = numberOfA + 1, you actually assign a value to numberOfA. Use a === b if you want to test equality.
Also, if you decide to use numberOfA to store the previous count, then you need to compare that with the current sentence.length value.
As a side note: if you are new, then invest time in learning how to use the debugger (e.g. in the browser dev tools). It will save you a lot of time and help you really understand what is happening.
You can not check numberOfA = numberOfA + 1 in your if statement. You can try this -
var numberOfA = 0;
function checkForA(){
var sentence = document.getElementById("userText").value.match(/a/g);
if (sentence.length > numberOfA) {
numberOfA = sentence.length;
alert("The letter A has been typed. In your sentence A has found "+numberOfA+" times.");
}
}
I am using Khan Academy's webpage in order to make a javascript project (which you can see here). I brought that up because I don't know if the problem is due to a subtlety of javascript, or if it is due to Khan Academy's system.
Here is a description of the problem:
var keyPressed = function() {
if (keyCode === BACKSPACE) {
debug(textBuffer.length);
debug(textBuffer);
textBuffer = textBuffer.slice(0,-1);
}
};
This code will, essentially, be run whenever I press the backspace key. When I invoke the code the first time, it works fine; the last character is removed from my global variable textBuffer. However, any subsequent calls to this code do nothing to my textBuffer string, unless textBuffer was changed in between calls. By using debug statements, I have noticed that the string length appears to be one too big.
I hope I have provided enough details for someone to sniff out the problem. Does anyone what is going on?
EDIT: Here is the source of the problem: although keyPressed is correctly registering the backspace, there is another function called keyTyped that was adding an invisible '\b' character into the string. This was how the string appeared to have only 2 characters but a length of 3.
When you press the backspace key, both the keyTyped and keyPressed functions are executed. keyPressed is executed first, which removes a character, and then keyTyped is executed, and adds a character to the string, the backspace character.
In JavaScript, this backspace character actually has an escape character for strings: '\b'.
To fix your problem, handle the backspace key in the keyTyped function, and don't let it append the toString value to the textBuffer.
var keyTyped = function() {
if (key.toString() === '\n') {
parse();
textBuffer = "";
}
if (key.toString() === '\b') {
textBuffer = textBuffer.slice(0, -1);
} else {
textBuffer = textBuffer + key.toString();
}
};
I know this seems a quite easy target. I have an input[type=text], and I want to detect the new added character(s) in it. The normal way is:
$selector.keypress(function(e) {
//do sth here
var newchar = String.fromCharCode(e.which);
});
But the above method not working properly for some browsers on android devices. Typing the android virtual keyboard will not fire the keypress.
Then I found the following method is better:
$selector.on('input', function(e){
//do sth here
});
It works fine for android devices, and also, it can detect cut/paste.
Now the question is, is there a way to know the new added character(s) to the input? Do I need to do the complicated string comparison during inputing each time, i.e. compare the previous string and the new string in the input box? I said it's complicated because you may not always type in char(s) at the end, you may insert some char(s) in the middle of the previous string. Think about this, the previous string in the input box is "abc", the new string after pasting is "abcxabc", how can we know the new pasted string is "abcx", or "xabc"?
The method from keypress is quite simple:
String.fromCharCode(e.which);
So, is there similar way to do this by the on('input') method?
After reading Yeldar Kurmangaliyev's answer, I dived into this issue for a while, and find this is really more complicated than my previous expectation. The key point here is that there's a way to get the cursor position by calling: selectionEnd.
As Yeldar Kurmangaliyev mentioned, his answer can't cover the situation:
it is not working is when you select text and paste another text with
replacing the original one.
Based on his answer, I modified the getInputedString function as following:
function getInputedString(prev, curr, selEnd) {
if (selEnd === 0) {
return "";
}
//note: substr(start,length) and substring(start,end) are different
var preLen = prev.length;
var curLen = curr.length;
var index = (preLen > selEnd) ? selEnd : preLen;
var subStrPrev;
var subStrCurr;
for(i=index; i > 0; i--){
subStrPrev = prev.substr(0, i);
subStrCurr = curr.substr(0, i);
if (subStrCurr === subStrPrev) {
var subInterval = selEnd - i;
var interval = curLen - preLen;
if (interval>subInterval) {
return curr.substring(i, selEnd+(interval-subInterval));
}
else{
return curr.substring(i, selEnd);
}
}
}
return curr.substring(0, selEnd);
}
The code is quite self explanation. The core idea is, no matter what character(s) were added(type or paste), the new content MUST be ended at the cursor position.
There's also one issue for my code, e.g. when the prev is abcabc|, you select them all, and paste abc, the return value from my code will be "". Actually, I think it's reasonable, because for my scenario, I think this is just the same with delete the abc from previous abcabc|.
Also, I changed the on('input') event to on('keyup'), the reason is, for some android browsers, the this.selectionEnd will not work in a same way, e.g., the previous text is abc|, now I paste de and the current string will be abcde|, but depending on different browsers, the this.selectionEnd inside on('input') may be 3, or 5. i.e. some browsers will report the cursor position before adding the input, some will report the cursor position after adding the input.
Eventually, I found on('keyup') worked in the same way for all the browsers I tested.
The whole demo is as following:
DEMO ON JSFIDDLE
Working on the cross-browser compatibility is always difficult, especially when you need to consider the touch screen ones. Hope this can help someone, and have fun.
Important notes:
when a user types in a character, the cursor stands after it
when a user pastes the text, the cursor is also located after the pasted text
Assuming this, we can try to suggest the inputed \ pasted string.
For example, when we have a string abc and it becomes abcx|abc (| is a cursor) - we know that actually he pasted "abcx", but not "xabc".
How do this algorithmically? Lets assume that we have the previous input abc and the current input: abcx|abc (cursor is after x).
The new one is of length 7, while the previous one is of length 4. It means that a user inputed 4 characters. Just return these four characters :)
The only case when it is not working is when you select text and paste another text with replacing the original one. I am sure you will come up with a solution for it yoruself :)
Here is the working snippet:
function getInputedString(prev, curr, selEnd) {
if (prev.length > curr.length) {
console.log("User has removed \ cut character(s)");
return "";
}
var lengthOfPasted = curr.length - prev.length;
if (curr.substr(0, selEnd - lengthOfPasted) + curr.substr(selEnd) === prev)
{
return curr.substr(selEnd - lengthOfPasted, lengthOfPasted);
} else {
console.log("The user has replaced a selection :(");
return "n\\a";
}
}
var prevText = "";
$("input").on('input', function() {
var lastInput = getInputedString(prevText, this.value, this.selectionEnd);
prevText = this.value;
$("#result").text("Last input: " + lastInput);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
<div id="result">Start inputing...</div>
Searching here, I found this tutorial and it is really helpful. I could easily do document.onkeypress to get the key pressed, and String.fromCharCode() to convert the keycode to a readable char. But I was wondering how can I be able to detect specific words?
Like:
var words; // something to store the latest 3 words for example
// then somehow concatenate each key pressed
// separating in the array based on the space key
var all = words[0]+" "+words[1]+" "+words[2];
var lastTwo = words[1]+" "+words[2];
if(all == "i love you"){
alert("I love you too :)");
}else if(lastTwo = "screw you"){
alert("You should not say something like this to me");
}
EDIT: What I am really interested in is how can I concatenate the keys recursively?
First you need to build your array elements into a string:
var phrase = words.join(" ");
Then see what's in there.
if(phrase.indexOf('sandwiches')>-1) {
alert("found sandwiches! let's eat.");
}
My only problem is that I am editing the html file directly on the server with nano, so I just commit some mistakes that I could not recognize.
Basically doing:
var word = "";
function dump(e){
var unicode = e.keyCode? e.keyCode : e.charCode;
var actualkey = String.fromCharCode(unicode);
word += actualkey;
alert(word);
}
document.onkeypress = dump
I am able to see the keys concatenating which was my main problem. After that I will just adjust the values to an array and join them neatly like #Diodeus suggested.
i am trying to validate text(Paragraph) in javascript for multiline Textbox.
After giving the text in textbox, the very first Letter should be changed to Capital letter, remaining have to remain as small letters.After full stop the first letter should be in Capital. I need to use textchange event also.
I am new to javascript, and i feel this Proper Case validation is very complex, i am not even getting any logic to start with.. Plz give some idea.
Thanks in advance.
Here's a possible answer, though to reiterate my comment, I don't actually think this is a very useful validation approach. You can see a working version here: http://jsfiddle.net/nrabinowitz/5TSK5/
// regex for a single sentence
var testRE = /^[A-Z][^A-Z]+$/;
var paragraphs = text.split('\n');
var pass, paragraph, sentences, sentence;
for (var x=0; x < paragraphs.length; x++) {
paragraph = paragraphs[x];
pass = true;
if (paragraph) {
sentences = paragraph.split(/\. +/);
for (var y=0; y < sentences.length; y++) {
sentence = sentences[y];
// test sentence for validity
if (sentence && !testRE.exec(sentence)) {
pass = false;
}
}
// pass is now either true or false for paragraph x
}
}
You might want to look for a plugin that already does grammar checking like After The Deadline.
#nrabinowitz is right, I wouldn't try to write a natural language grammar checker in javascript unless your stated goal of "capitalization should only occur after a full stop" is the full extent of what you want to do, you'd be attempting to parse a potentially non-context-free language.