Replace text (change case) in a textbox using Javascript - javascript

I am trying to build a sort of intelli-sense text input box, where as the user types, the 'and' is replaced by 'AND \n' (i.e. on each 'and', the 'and' is capitalized and user goes to new line).
The Javascript I used for this is:
function Validate()
{
document.getElementById("search").value = document.getElementById("search").value.replace("and","AND \n"); //new line for AND
}
The HTML part is like this:
< textarea type="text" name="q" id="search" spellcheck="false" onkeyup='Validate();'>< /textarea>
Though the above script works well on Firefox and Chrome, it sort-of misbehaves on Internet Explorer (brings the cursor to the end of the text on each 'KeyUp').
Also the above code doesn't work for the other variants of 'and' like 'And', 'anD' or even 'AND' itself.

I think the actual answer here is a mix of the two previous:
onkeyup="this.value = this.value.replace(/\band\b/ig, ' AND\n')"
You need the i to make the search case insensitive and the g to make sure you replace all occurrences. This is not very efficient, as it'll replace previous matches with itself, but it'll work.
To make it a separate function:
function validate() {
document.getElementById('search') = document.getElementById('search').replace(/\band\b/ig, ' AND\n');
}

If you alter the textarea contents while the user is typing the caret will always move to the end, even in Firefox and Chrome. Just try to edit something you already wrote and you'll understand me. You have to move the caret to the exact position where the users expects it, which also implies you have to detect text selections (it's a standard behaviour that typing when you have a selection removes the selected text).
You can find here some sample code. You might be able to use the doGetCaretPosition(), setCaretPosition() functions.

I tried to work around the problem and solved by using the following javascript:
function Validate() {
if( document.getElementById("search").value.search(/\band$(?!\n)/i) >= 0 ){ // for maintaining cursor position
document.getElementById("search").value = document.getElementById("search").value.replace(/\band$(?!\n)/i,"AND\n"); //new line for AND
}
}
Thin slicing the above problem and solution:
1) The function was being called on each key up, thus earlier "AND\n" was being repeated on each key up, thus inserting a blank line on each key press. I avoided the above by using the regex:
/\band$(?!\n)/i
\b = Like Word (to avoid SAND)
$ = End of line (as "and" will be replaced by "AND\n" thus it will always be end of line)
(?!\n) = Not followed by new line (to prevent repeatedly replacing "AND\n" on each key press)
i = To cover all variants of "and" including "And","anD" etc.
2) Internet Explorer was misbehaving and the cursor position was not maintained (moved to end) when the input was re-edited. This was caused (as hinted by Alvaro above) due to the replace function.
Thus I inserted an "if" statement to call replace function only when it is needed, i.e. only when there is some "and" needing replacement.
Thanks everyone for the help.

try using the following replace() statement:
replace(/\band(?!$)/ig, "And\n")
since this is being called repeatedly against the altered string you have to make sure that the "and" is not followed by a line break.
example (uses a loop and function to simulate the user typing the letters in):
function onkeyup() {
var str = this;
return this.replace(/\band(?!$)/ig, "And\n");
};
var expected = "this is some sample text And\n is separated by more text And\n stuff";
var text = "this is some sample text and is separated by more text and stuff";
var input = "";
var output = "";
for(var i = 0, len = text.length; i < len; i++ ) {
input += text.substr(i,1);
output = onkeyup.call(input);
}
var result = expected == output;
alert(result);
if( !result ) {
alert("expected: " + expected);
alert("actual: " + output);
}
you can test this out here: http://bit.ly/8kWLtr

You need to write a JS code that run in both IE and FireFox. I think this is what you need:
var s = document.getElementbyId('Search');
s.value = s.value.replace('and', 'AND \n');

I think you want your replace call to look like this:
replace(/\band\b/i,"AND \n") (see below)
That way it is not case sensitive (/i), and only takes single words that match and, so 'sand' and similar words that contain 'and' don't match, only 'and' on it's own.
EDIT: I played around with it based on the comments and I think this working example is what is wanted.
Replace the onKeyUp event with onBlur:
<textarea type="text" name="q" id="search" spellcheck="false" onblur='Validate();'></textarea></body>
So that the validate function is only run when the user leaves the text box. You could also run it onSubmit.
I also added a global switch (g) and optional trailing whitespace (\s?) to the regex:
replace(/\band\b\s?/ig,"AND \n")
This causes input like this:
sand and clay and water
to be transformed into this when you leave the text box:
sand AND
clay AND
water
You should probably test this against a bunch more cases.

Related

JavaScript not removing text when a uppercase letter involved

So I have a text box on my website and I have coded this to prevent certain words from being used.
window.onload = function() {
var banned = ['MMM', 'XXX'];
document.getElementById('input_1_17').addEventListener('keyup', function(e) {
var text = document.getElementById('input_1_17').value;
for (var x = 0; x < banned.length; x++) {
if (text.toLowerCase().search(banned[x]) !== -1) {
alert(banned[x] + ' is not allowed!');
}
var regExp = new RegExp(banned[x]);
text = text.replace(regExp, '');
}
document.getElementById('input_1_17').value = text;
}, false);
}
The code works perfectly and removes the text from the text box when all the letters typed are lowercase. The problem is when the text contained an uppercase letter it will give the error but the word will not be removed from the text box.
The RegExp is a good direction, just you need some flags (to make it case-insensitive, and global - so replace all occurrences):
var text="Under the xxx\nUnder the XXx\nDarling it's MMM\nDown where it's mmM\nTake it from me";
console.log("Obscene:",text);
var banned=["XXX","MMM"];
banned.forEach(nastiness=>{
text=text.replace(new RegExp(nastiness,"gi"),"");
});
console.log("Okay:",text);
Normally you should use .toLowerCase() with both sides when comparing the strings so they can logically be matched.
But the problem actually comes from the Regex you are using, where you are ignoring case sensitivity, you just need to add the i flag to it:
var regExp = new RegExp(banned[x], 'gi');
text = text.replace(regExp, '');
Note:
Note also that using an alert() in a loop is not recommended, you can change your logic to alert all the matched items in only one alert().
You seem to have been expecting something unreasonable. Lowercase strings will never match strings containing uppercase letters.
Either convert both for comparison or use lowercase banned strings. The former would be more reliable, taking future human error out of the process.
What you can do is actually convert both variables to either all caps or all lowercase.
if (text.toLowerCase().includes(banned[x].toLowerCase())) {
alert(banned[x] + ' is not allowed!');
}
Not tested but it should work. No need to use search since you don't need the index anyway. using includes is cleaner. includes docs

JavaScript: Replace certain occurrence of string depending on selection index

I've created my own autocomplete feature and I've come across a bug I'd like to fix. Here's an example of an incomplete sentence I might want to autocomplete the final word for:
let text = 'Hello there, I am her'
In my functionality the user clicks ctrl + enter and it autcompletes the word with a suggestion displayed on the page. In this case let's say the suggestion is 'here'. Also my controller knows where the user is based on the insertion cursor (so I have the index).
If I use replace like so:
text.replace(word, suggestion);
(Where word is 'her' and suggestion is 'here') it will replace the first occurrence. Obviously there are endless combinations of where this word might be in the text, how do I replace one at a certain index in text string? I know I can do it through some messy if conditions, but is there an elegant way to do this?
(If it is relevant I am using angular keydown/keyup for this)
EDIT>>>>>
This is not a duplicate on the question linked as in that case they are always replacing the last occurrence. If I did that then my program wouldn't support a user going back in their sentence and attempting to autocomplete a new word there
So, you have a position in a string and a number of characters to replace (=length of an incomplete word). In this case, would this work?
let text = 'appl and appl and appl'
function replaceAt(str, pos, len, replace) {
return str.slice(0, pos) + replace + str.slice(pos + len);
}
console.log(replaceAt(text, 0, 4, 'apple'))
console.log(replaceAt(text, 9, 4, 'apple'))
Gonna point you in a direction that should get you started.
let sentence = 'Hello lets replace all words like hello with Hi';
let fragments = sentence.split(' ');
for (let i=0; i<fragments.length; i++){
if(fragments[i].toLowerCase() == 'hello')
fragments[i] = 'Hi'
}
let formattedsentence = fragments.join(' ');
console.log(formattedsentence); //"Hi lets replace all words like Hi with Hi"

Special dot masked input HTML-JavaScript

I'm trying to achieve a special masked input in HTML using jQuery and themask plugin from Igor Escobar (http://igorescobar.github.io/jQuery-Mask-Plugin/)
I need write only numbers[0-9] and the following conversions:
input:
123456789
12345678
1234567
123456
desidered output:
123.456.789
12.345.678
1.234.567
123.456
Is possible achive this with that plugin?
Or exist another way to do it?
Thanks for reading :)
EDIT:
I did it using another plugin (Numeral.js):http://numeraljs.com/
This is my working code:
$("#myinput").blur(function()
{
this.value=numeral(this.value).format('0,0[.]00').replace(/\,/g, '.');
});
But I do not like to be validated at the end, ie (onblur), is there any way to do this on the fly? - That is, gradually validate (keypress).
You probably don't need a library for that. I kept jQuery but it's really used to select the input, so you definitely can ditch it quite easily.
$("#myinput").keyup(function(){
// prevent every character except numbers
if(!this.value.slice(-1).match(/^[0-9]+\.?[0-9]*$/) ){
this.value = this.value.slice(0, -1);
return;
}
// remove the dots, split the string and reverse it
var a = this.value.replace(/\./g, '').split('').reverse();
// start from 3 and as long as there's a number
// add a dot every three digits.
var pos = 3;
while(a[pos] !== undefined){
a.splice(pos,0,'.');
pos = pos + 4;
}
// reverse, join and reassign the value
this.value = a.reverse().join('');
});
You can try it yourself here and see if it does the job. Hope it helps.
EDIT: while the above code works it has some shortcomings, such as:
it does not work when copy/pasting
it does not allow moving with arrow keys
the cursor always goes to the end of the input, even when you are inserting a number in the middle.
As I needed it with full support for those cases I evolved it in a tiny script you can find on Github along with a demo and test spec.
$("#myinput").on('keyup keydown blur', function() {
this.value=numeral(this.value).format('0,0[.]00').replace(/\,/g, '.');
}

JavaScript remove ZERO WIDTH SPACE (unicode 8203) from string

I'm writing some javascript that processes website content. My efforts are being thwarted by SharePoint text editor's tendency to put the "zero width space" character in the text when the user presses backspace.
The character's unicode value is 8203, or B200 in hexadecimal. I've tried to use the default "replace" function to get rid of it. I've tried many variants, none of them worked:
var a = "o​m"; //the invisible character is between o and m
var b = a.replace(/\u8203/g,'');
= a.replace(/\uB200/g,'');
= a.replace("\\uB200",'');
and so on and so forth. I've tried quite a few variations on this theme. None of these expressions work (tested in Chrome and Firefox) The only thing that works is typing the actual character in the expression:
var b = a.replace("​",''); //it's there, believe me
This poses potential problems. The character is invisible so that line in itself doesn't make sense. I can get around that with comments. But if the code is ever reused, and the file is saved using non-Unicode encoding, (or when it's deployed to SharePoint, there's not guarantee it won't mess up encoding) it will stop working. Is there a way to write this using the unicode notation instead of the character itself?
[My ramblings about the character]
In case you haven't met this character, (and you probably haven't, seeing as it's invisible to the naked eye, unless it broke your code and you discovered it while trying to locate the bug) it's a real a-hole that will cause certain types of pattern matching to malfunction. I've caged the beast for you:
[​] <- careful, don't let it escape.
If you want to see it, copy those brackets into a text editor and then iterate your cursor through them. You'll notice you'll need three steps to pass what seems like 2 characters, and your cursor will skip a step in the middle.
The number in a unicode escape should be in hex, and the hex for 8203 is 200B (which is indeed a Unicode zero-width space), so:
var b = a.replace(/\u200B/g,'');
Live Example:
var a = "o​m"; //the invisible character is between o and m
var b = a.replace(/\u200B/g,'');
console.log("a.length = " + a.length); // 3
console.log("a === 'om'? " + (a === 'om')); // false
console.log("b.length = " + b.length); // 2
console.log("b === 'om'? " + (b === 'om')); // true
The accepted answer didn't work for my case.
But this one did:
text.replace(/(^[\s\u200b]*|[\s\u200b]*$)/g, '')

ASCII character not being recognized in if statement

I am trying to get a string from a html page with jquery and this is what I have.
var text = $(this).text();
var key = text.substring(0,1);
if(key == ' ' || key == ' ')
key = text.substring(1,2);
text is this  Home
And I want to skip the space and or the keycode above It appears this code does not work either. It only gets the text.substring(0,1); instead of text.substring(1,2); because the if statement is not catching.= and I am not sure why. Any help would be super awesome! Thanks!
There are several problems with the code in the question. First,   has no special meaning in JavaScript: it is a string literal with six characters. Second, text.substring(1,2) returns simply the second character of text, not all characters from the second one onwards.
Assuming that you wish to remove one leading SPACE or NO-BREAK SPACE (which is what   means in HTML; it is not an Ascii character, by the way), then the following code would work:
var first = text.substring(0, 1);
if(first === ' ' || first === '\u00A0') {
text = text.substring(1, text.length);
}
The notation \u00A0 is a JavaScript escape notation for NO-BREAK SPACE U+00A0.
Should you wish to remove multiple spaces at the start, and perhaps at the end too, some modifications are needed. In that case, using a replace operation with regular expression is probably best.
If you want remove spaces at the beginning (and end) of a string, you can use the trim function
var myvar = " home"
myVar.trim() // --> "home"
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim

Categories

Resources