Firefox error? Workaround?

  • Thread starter Paul Gorodyansky
  • Start date
P

Paul Gorodyansky

Hi,

Ran into the problem today - in INPUT field Firefox executes
clean-yp of the content if a user presses Esc, _before_ control goes to
the code via onkeydown - and search showed that it's a known issue:

https://bugzilla.mozilla.org/show_bug.cgi?id=236628

The bug is closed due to the inactivity (I've just written to the
Submiter because apparently I don't have rights to re-Open)

For Internet Explorer there is a solition listed in the FAQ:
http://www.faqts.com/knowledge_base/view.phtml/aid/9008/fid/130

but Firefox... Regular ways do not work:
http://www.experts-exchange.com/Web/Web_Languages/JavaScript/Q_21064248.html

Any information or workaround?
 
R

RobG

Paul said:
Hi,

Ran into the problem today - in INPUT field Firefox executes
clean-yp of the content if a user presses Esc, _before_ control goes to
the code via onkeydown - and search showed that it's a known issue:

There appears to be a bug with Firefox and the keydown event related to
showing alerts:

<URL:https://bugzilla.mozilla.org/show_bug.cgi?id=326484>


But otherwise, the behaviour you describe does not happen for me
(Firefox 1.5). Try this:


<input type="text"
onkeydown="document.getElementById('xx').innerHTML = this.value;">
<div id="xx"
onclick="alert(document.getElementById('text-01').value);"

1. Press 'a', no change to 'xx'.
2. Press 'b', see 'a' in 'xx'.
3. Press 'c', see 'ab' in 'xx'.
4. Pres Esc, see 'abc' in 'xx'.
5. Press Esc again, input is cleared but 'abc' still shown in 'xx'.
6. Press Esc again (3rd time), '' shown in 'xx'.


I was using an alert but discovered the bug above when trying that.

[...]
 
R

RobG

RobG wrote:
[...]
<input type="text"
onkeydown="document.getElementById('xx').innerHTML = this.value;">

Ooops, crappy cut & paste:

<input type="text" id="text-01"
onkeydown="document.getElementById('xx').innerHTML = this.value;">
 
R

RobG

Paul said:
Hi,



It's what I reported - about _input being cleared_, that is a user
looses her/his input... Please see BugZilla entry listed in my 1st
message.

Ah, so what you are saying is that you can't prevent the clearing of the
input using JavaScript.

I thought you meant that the content was cleared before the keydown
event was called so you couldn't see what the value was.

I guess a clunky way might be to detect presses of the escape key, grab
the value then use setTimeout() to write it back into the input
(presumably setTimeout will let the escape action compete before putting
the content back in). Sample below:


<script type="text/javascript">
function isEsc(e)
{
var e = e || window.event;
var kCode = e.keyCode || e.which;
return (kCode && '27' == kCode);
}

function checkKey(e, el)
{
var val = el.value;
var e = e || window.event;
if (isEsc(e)){
setTimeout(function(){el.value=val;},10);
}
}
</script>

<input type="text" onkeydown="checkKey(event, this);">


Lightly tested in Firefox and IE, there may be issues with older
browsers (Some older browsers may not like functions as arguments to
setTimeout).
 
V

VK

Paul said:
Hi,

Unfortunately, The Bug filed and another link I provided -
at Experts forum - specify, that Firefox erases the content BEFORE
_any_ Javascript code based on OnKeyDown executes :(

I would screw on textbox and write my own widget using CSS and
contentEditable. A bit of one time hassle but nothing in comparison of
overriding default input behavior, believe me.
 
R

RobG

Paul said:
Hi,

Unfortunately, The Bug filed and another link I provided -
at Experts forum - specify, that Firefox erases the content BEFORE
_any_ Javascript code based on OnKeyDown executes :(

That's not what seems to happen for me, did you try the code I posted?
As far as I can tell, it works as you require.
 
P

Paul Gorodyansky

Hi,
That's not what seems to happen for me, did you try the code I posted?
As far as I can tell, it works as you require.

I did not try before - my mistake - because I _knew_ :) that Firefox
erases the text _before_ the functions linked to OnKeyDown is called,
but I did not pay attention that you _store_ the whole content -
so even if it's erased, you restore it from the variable.

Yes, your code works in _your_ variant - when onkeydown is used
in INPUT control itself. But it does not work in my code -
I have it - forgot for what reason - in a <form
tag and not in the <input tag.
So if I use your code in <form - does not wokr, content is erased -
see below. But may be I should move onkydown check to INPUT field...
Cannot remember why I have it in <form - may be long ago I used
some Web example or so...

Thanks! It's one of the possible work-arounds - using your code.

<html>
<head>
<title>abc</title>
<script type="text/javascript">
function isEsc(e)
{
var e = e || window.event;
var kCode = e.keyCode || e.which;
return (kCode && '27' == kCode);
}

function checkKey(e, el)
{
var val = el.value;
var e = e || window.event;
if (isEsc(e)){
setTimeout(function(){el.value=val;},10);
}
}
</script>
</head>
<body>
<form name = "my" onkeydown="checkKey(event, this);">
<INPUT TYPE="text" NAME="Subject" SIZE="45" MAXLENGTH="60">
</form>
</body>
</html>
 
R

RobG

Paul said:
Hi,



I did not try before - my mistake - because I _knew_ :) that Firefox
erases the text _before_ the functions linked to OnKeyDown is called,
but I did not pay attention that you _store_ the whole content -
so even if it's erased, you restore it from the variable.

Yes, your code works in _your_ variant - when onkeydown is used
in INPUT control itself. But it does not work in my code -
I have it - forgot for what reason - in a <form
tag and not in the <input tag.

I presume you did that so you only need to put one handler on the form
and also because in IE a double-escape clears the entire form, not just
the input that has focus (as in Firefox).

This gave me a brainstorm: for Gecko browsers use addEventListener and
stopPropagation in the capture phase. After trial and error to discover
that it doesn't work, I found that quirksmode also says that you can't
cancel the capture phase of an event, only the bubbling phase.

<URL:http://www.quirksmode.org/js/events_order.html>


I wonder why it's not possible for stopPropagation to take a single
boolean argument to determine whether to stop events on the capture or
bubble phases, just like addEventListener does to determine whether to
fire events on capture or bubble? The default could be on bubble
(false) for backward compatibility.

There is a stopImmediatePropagation in DOM 3, but it doesn't seem to be
implemented yet in Firefox:

<URL:http://www.w3.org/TR/DOM-Level-3-Events/events.html#Events-Event-stopImmediatePropagation>


Anyhow, figured the 'best' way is to add a single event handler to the
form. If addEventListener supported (Gecko /et al/), the setTimeout()
hack is added, if attachEvent supported (IE, others?) a simple 'return
false if escape is pressed' function is added.

The saving is that you can use script to put the handler on the handler
on the form and fire on the capture phase for Gecko browsers *before*
input is cleared, so you can effectively disable the Esc key for text
inputs in script-enabled browsers - sample below (lightly tested in
Firefox 1.5 and IE 6 only):


<script type="text/javascript">

function addEvt(elID, funcRef)
{
var el;
if ( !document.getElementById
|| !(el = document.getElementById(elID)) ){
return;
}

if (el.addEventListener){

// For Gecko, use the setTimeout hack
el.addEventListener('keydown', stopEsc, true);
} else if (el.attachEvent){

// For IE, just return false if Esc pressed
el.attachEvent('onkeydown', function(){
return !isEsc();
});
}
}

function isEsc(e)
{
var e = e || window.event;
var kCode = e.keyCode || e.which;
return kCode && '27' == kCode;
}

function stopEsc(e)
{
var e = e || window.event;
var tgt = e.target || e.srcElement;
var val;
if ('input' == tgt.nodeName.toLowerCase()
&& 'text' == tgt.type
&& (val = tgt.value)){
if (isEsc(e)){
setTimeout(function(){tgt.value=val;},10);
return false;
}
}
}

window.onload = function() {
addEvt('formA', stopEsc);
}

</script>

<form name="formA" id="formA" action="">
<div>
<!-- Dummy inputs for test -->
<input type="text">
<input type="text">
<input type="checkbox" name="cb-01">
<input type="checkbox" name="cb-02">
</div>
</form>
 
P

Paul Gorodyansky

Thanks, Rob,

it looks like a complete solution!
The only thing - productivity-wise - we store entire typed text each
time _any_ key is pressed... But it's probably not noticable,

This <INPUT situation arised only couple days ago - before that
I used my code only with <TEXTAREA - where Firefox does not have
such issue with Esc and IE could be ESC-safe in a regular way - as in
your example code.

It's good that the work-around has been found for <INPUT case!


Thanks,
Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top