Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

filter works in-line but not as a function

Status
Not open for further replies.

jaschulz

Programmer
May 20, 2005
89
0
0
FR
In the example below, exactly the same code works in IE, Opera and FF when it is called from the HTML, but it fails in FF (only) when it is called as a function. What's going on?

thanks,

JAS

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"
<html>
<head>
<title>Untitled</title>

<script type="text/javascript">

function filterKeys() {
if(event.keyCode){if ((event.keyCode > 32 && event.keyCode < 48) ||
(event.keyCode > 57 && event.keyCode < 65) ||
(event.keyCode > 90 && event.keyCode < 97)) {event.returnValue = false;}
}else{
if ((event.which > 32 && event.which < 48) ||
(event.which > 57 && event.which < 65) ||
(event.which > 90 && event.which < 97)) {return false;}
}
}

</script>

</head>

<body>

Filters: !@#$%^&* (works in both IE, Opera and FF)<br>
<br>
<textarea rows=2 cols=20 id="ta2" onKeypress="
if(event.keyCode){if ((event.keyCode > 32 && event.keyCode < 48) ||
(event.keyCode > 57 && event.keyCode < 65) ||
(event.keyCode > 90 && event.keyCode < 97)) {event.returnValue = false;}
}else{
if ((event.which > 32 && event.which < 48) ||
(event.which > 57 && event.which < 65) ||
(event.which > 90 && event.which < 97)) {return false;}
}
"></textarea><br>
<br>
Filters: !@#$%^&* (works in IE and Opera, but NOT FF!)<br>
<br>
<textarea rows=2 cols=20 id="ta1" onKeypress="filterKeys();">
</textarea>
<br>

</body>
<html>
 
In [tt]filterKeys[/tt] try setting [tt]event.returnValue[/tt] to [tt]true[/tt] or [tt]return[/tt]ing [tt]true[/tt]. As it stands at the moment, [tt]filterKeys[/tt] has an [tt]undefined[/tt] return value, which is treated as [tt]false[/tt].

[tt]_______________________________________
Roger [pc2]
The Eileens are out there[/tt]
 
So now filterKeys() looks like this:

function filterKeys() {
if(event.keyCode){if ((event.keyCode > 32 && event.keyCode < 48) ||
(event.keyCode > 57 && event.keyCode < 65) ||
(event.keyCode > 90 && event.keyCode < 97)) {event.returnValue = false;} else {event.returnValue = true;}
}else{
if ((event.which > 32 && event.which < 48) ||
(event.which > 57 && event.which < 65) ||
(event.which > 90 && event.which < 97)) {return false;} else {return true;}
}
}

but it doesn't fix the problem.

JAS
 
OK, it was just an idea because that's the only difference really. The other thing you might try is:
[code<textarea rows=2 cols=20 id="ta1" onKeypress="filterKeys(); return true;">[/code]
but I'm not certain this will make much difference.

[tt]_______________________________________
Roger [pc2]
The Eileens are out there[/tt]
 
No, alas, that didn't help either. This is making me crazy!

JAS
 
I had this problem about 6 months ago, and I'm sure it was something to do with the return value. Don't have the code here at the moment. Maybe someone else will be able to help as I can't get the details until Monday.
Sorry I couldn't be more help.

[tt]_______________________________________
Roger [pc2]
The Eileens are out there[/tt]
 
This is because in moz, you have to pass the event object to the handler explicitly in "most" case as an argument. And also capture the return too. The change is this.
[tt]
<textarea rows=2 cols=20 id="ta1" onKeypress="[red]return [/red] filterKeys([blue]event[/blue]);">
</textarea>
[/tt]
With the functions so modified...
[tt]
function filterKeys([blue]evt[/blue]) {

[blue]var event=(evt)?evt:window.event;[/blue]

if(event.keyCode){if ((event.keyCode > 32 && event.keyCode < 48) ||
(event.keyCode > 57 && event.keyCode < 65) ||
(event.keyCode > 90 && event.keyCode < 97)) {event.returnValue = false;}
}else{
if ((event.which > 32 && event.which < 48) ||
(event.which > 57 && event.which < 65) ||
(event.which > 90 && event.which < 97)) {return false;}
}
}
[/tt]
 
Yes, that works. Thanks. Is there a reference where I might have been able to find this information myself?

JAS
 
Whoops! I was too quick. Your fix works as I said, but it breaks another function fakeKeyPress() (shown below). I need both (and I need to get fakeKeyPress to to work for Opera and IE-- at the moment, without your fix for filterKeys, it works only in FF).

Can you help?

JAS

function fakeKeyPress(elementID, thisKeyCode){
var thisTarget = document.getElementById(elementID);
thisTarget.focus();
if( window.KeyEvent ) {
var evObj = document.createEvent('KeyEvents');
evObj.initKeyEvent( 'keypress', true, true, window, false, false, true, false, 0, thisKeyCode );
} else {
var evObj = document.createEvent('UIEvents');
evObj.initUIEvent( 'keypress', true, true, window, 1 );
evObj.keyCode = 0x50;
}
thisTarget.dispatchEvent(evObj);
doFocus();
}
 
Wrong! I must be sleepy! Your fix for filterKeys does NOT break fakeKeyPress (though it still won't work for IE or Opera). Thanks again.

JAS
 
>Your fix for filterKeys does NOT break fakeKeyPress (though it still won't work for IE or Opera)

What is the real message? Does it fix or not fix filterKeys functionality? Why don't you make the message simple and definite on this?

>though it still won't work for IE or Opera
What is the "it"? You mean filterKeys or fakeKeyPress. If you mean fakeKeyPress, why on earth should the fix for filterKeys fix fakeKeyPress which we never see---or, even that we saw it, should the fix fix it at the same time?

So what is your real message to the forum?
 
Sorry. Your fix for filterKeys does work. It does NOT break fakeKeyPress. (I apologize. I must have been very sleepy this morning when I wrote those earlier messages.) Thanks again for your help.

My problem with fakeKeyPress is entirely separate, and I posted it in a separate thread. I should not have confused the issue here.

Again, my apologies.

JAS
 
Okay, thanks for the clarification JAS. I appreciate it because keyboard event emulation is not an easy thing. A confusing feedback can bare me from thinking straight. The problem mostly stems from the targeting recepient of the event and positioning of the output. I'll take a look of your fakKeyPress.
 
This is a realization where filter functions cross-browser ie/moz/op and emulation of keypress functions cross-browser ie/moz. (My opera is 7.23 only, so maybe it support dispatchEvent dom-2 at later version.) Your ie part gakeKeyPress is not correct. Even corrected some method calls, it won't function as yet the way of dom-2 dispatchEvent without a hack.
[tt]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"<html xmlns="<head>
<title>Untitled</title>
<script type="text/javascript">
<![CDATA[
function filterKeys(evt) {
var event=(evt)?evt:window.event;
if (event.keyCode) {
if ((event.keyCode > 32 && event.keyCode < 48) ||
(event.keyCode > 57 && event.keyCode < 65) ||
(event.keyCode > 90 && event.keyCode < 97)) {
event.returnValue = false;
return false;
} else {
if ((!window.opera && event.clientX && event.clientY)|| window.opera) {
event.srcElement.value+=String.fromCharCode(event.keyCode);
event.returnValue = false;
} else {
event.returnValue = true;
}
return true;
}
} else if (event.which) {
if ((event.which > 32 && event.which < 48) ||
(event.which > 57 && event.which < 65) ||
(event.which > 90 && event.which < 97)) {
return false;
} else {
return true;
}
}
}

function fakeKeyPress(elementID, thisKeyCode){
var thisTarget = document.getElementById(elementID);
thisTarget.focus();
if( window.KeyEvent||window.opera ) { //moz and op; op 7.23 not yet operating
var evObj = document.createEvent('KeyEvents');
evObj.initKeyEvent( 'keypress', true, true, window, false, false, true, false, 0, thisKeyCode );
thisTarget.dispatchEvent(evObj);
} else { //ie
var evObj = document.createEventObject();
evObj.keyCode = thisKeyCode;
evObj.type="keypress";
thisTarget.fireEvent("onkeypress",evObj);
}
//doFocus(); //this is not shown, what is it?
}
]]>
</script>
</head>
<body>
<form onsubmit="return false">
<div>Filters: !@#$%^&* (works in IE and Opera, and FF!)</div>
<textarea rows="2" cols="20" id="ta1" onKeypress="return filterKeys(event);"></textarea><br />
<input size="1" maxlength="1" name="char_send" id="char_send" value="a" />
<input type="button" id="btn" onclick="fakeKeyPress('ta1',this.form.char_send.value.charCodeAt(0))" value="key this character to textarea-ta1 [ff/ie]" />
</form>
</body>
</html>
[/tt]
 
Thanks again. Your fix does work for IE (but still not for Opera 8.4). However, to get it to work, I had to remove the <![CDATA[ ]]> wrapper. I don't understand what that wrapper is, or how it works, but once I removed it, fakeKeyPress worked for IE6.

BTW, sorry about the doFocus() line. It should not have been there. The app I am working on is a sort of calculator. The user presses a button which calls fakeKeyPress to insert a special character in an Input. My doFocus simply returns the focus from the button in question to the Input area.

I have one other question (if you're not out of patience). Is it possible to put a chracter to (or clear a character from) a specific row/column position in a text area? If so, how is this done?

Thanks for all your help,

JAS



}
 
It turns out there is a problem. The latest changes to filterKeys result in the caret position being ignored. That is the new character is always added to the end of the current string (rather than being inserted at the caret position).

JAS
 
[1] Shed the xhtml artifacts
I had a typo in the default namespace (xhtml[highlight]1[/highlight], 1 should not be there.) Since your original was tempting to use xhtml-strict, after reflecting, it seems I need to change quite a bit to have a consistently valid xhtml doc, maybe just use very loose html that I feel happy enough for developing. I do not like to change much for nothing. Sorry for the confusion...
[tt]
<html>
<head>
<title>Untitled</title>
<script type="text/javascript">
function filterKeys(evt) {
var event=(evt)?evt:window.event;
if (event.keyCode) {
if ((event.keyCode > 32 && event.keyCode < 48) ||
(event.keyCode > 57 && event.keyCode < 65) ||
(event.keyCode > 90 && event.keyCode < 97)) {
event.returnValue = false;
return false;
} else {
if ((!window.opera && event.clientX && event.clientY)|| window.opera) {
event.srcElement.value+=String.fromCharCode(event.keyCode);
event.returnValue = false;
} else {
event.returnValue = true;
}
return true;
}
} else if (event.which) {
if ((event.which > 32 && event.which < 48) ||
(event.which > 57 && event.which < 65) ||
(event.which > 90 && event.which < 97)) {
return false;
} else {
return true;
}
}
}

function fakeKeyPress(elementID, thisKeyCode){
var thisTarget = document.getElementById(elementID);
thisTarget.focus();
if( window.KeyEvent||window.opera ) { //moz and op; op 7.23 not yet operating
var evObj = document.createEvent('KeyEvents');
evObj.initKeyEvent( 'keypress', true, true, window, false, false, true, false, 0, thisKeyCode );
thisTarget.dispatchEvent(evObj);
} else { //ie
var evObj = document.createEventObject();
evObj.keyCode = thisKeyCode;
evObj.type="keypress";
thisTarget.fireEvent("onkeypress",evObj);
}
//doFocus(); //to uncomment
}
</script>
</head>
<body>
<form onsubmit="return false">
<div>Filters: !@#$%^&* (works in IE and Opera, and FF!)</div>
<textarea rows="2" cols="20" id="ta1" onkeypress="return filterKeys(event);"></textarea><br />
<input size="1" maxlength="1" name="char_send" id="char_send" value="a" />
<input type="button" id="btn" onclick="fakeKeyPress('ta1',this.form.char_send.value.charCodeAt(0))" value="key this character to textarea-ta1 [ff/ie]" />
</form>
</body>
</html>
[/tt]
[2]>Is it possible to put a chracter to (or clear a character from) a specific row/column position in a text area? If so, how is this done?
To clear, there is no need to have keyboard event. Just use simple function to get the value of the textarea and perform a simple match (the character in question) and replace (replace it with empty string). If you cannot find how to do it, feel free to ask in a new thread and I'm sure many would come forward to help.
 
>It turns out there is a problem. The latest changes to filterKeys result in the caret position being ignored. That is the new character is always added to the end of the current string (rather than being inserted at the caret position).

You just have to insert it at the caret position. The simple way is shown here.
Replace the line which is of nature of a hack:
[tt] event.srcElement.value+=String.fromCharCode(event.keyCode);[/tt]
by info on the position to insert.

But looking at your original question with .focus(), I don't think it is an element in the original setting. In any case, you will find more trouble ahead as all the major browsers behave quite differently. (Look at how opera's cursor move, it moves differently from moz.) There is an area particular good for the moz/op fans to talk empty.
 
There are still problems. A new character is always added to the end of the current string even when the caret position is elsewhere. The arrow keys work (as do Home and End), but Delete doesn't work at all, and Backspace works but appends a little rectangle (undisplayable character) to the end of the string.

JAS
 
JAS,

Why not install a JavaScript debugger and see if you can narrow down the problem a bit. The free debuggers available for noth IE and FF are pretty good - you can step through the code with no problem.

Dan

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top