views:

779

answers:

6

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.

A: 

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.

beggs
The above code perfectly replaces the variants of 'and' with 'AND \n'. However, due to 'onKeyUp' event, the replace function is called on each key press and new lines ('\n') keeps on adding.
Pratyush
what's up with the down vote? Did I make a mistake?
beggs
A: 

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

Jared
+1  A: 

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');
}
Bialecki
you need to add 2x .value in your 2nd code eg
pstanton
The above code perfectly replaces the variants of 'and' with 'AND \n'. However, due to 'onKeyUp' event, the replace function is called on each key press and new lines ('\n') keeps on adding.
Pratyush
+1  A: 

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.

Álvaro G. Vicario
A: 

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');
Ramezanpour
replace only replaces the first occurrence by default. so the code you posted would only replace the first instance of "and" with "AND \n"
Jared
Absolutely! You're right.
Ramezanpour
+1  A: 

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.

Pratyush