kbd handler

J

J. J. Cale

Hi
The code below worked fine in IE5. I changed to IE6 and I can trap the
'enter' key but I can't add a line feed to the text in the div. Also what
other browser should I be testing with and where can I download it? I intend
to write a full blown kbd handler that will also trap the backspace and tab
etc. I can use all the help I can get. BTW I tried doing this with a
textarea but I need to write directly to the divide. The intention here is
to have a letter that can have different borders clipart etc and the ability
to select text and change the various css properties or use exec Command to
toggle them. If anyone has this working or knows of someone or a site that
has I'll be ecstatic.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>kbd handler</TITLE>
<script type="text/javascript">
document.onkeypress = function (evt) {
var el = document.all?letter:document.getElementById('letter');
var evt = evt || window.event;
var keyCode = evt.keyCode || evt.which;
// alert(keyCode);
if(keyCode == 27) return;
if(keyCode == 13) {
el.firstChild.data += '\n';
el.innerText += '\n';
el.innerHTML += '<br>';
return;
}
var str = String.fromCharCode(keyCode);
// el.firstChild.data += str;
el.innerText += str;
}
</script></HEAD>
<BODY>
<div id="letter"
style="width:300px;padding:4px;margin-left:4px;height:450px;background-color
:#ffffcc;"></div>
</BODY></HTML>
TIA
Jimbo
 
Y

Yann-Erwan Perio

J. J. Cale said:
Also what
other browser should I be testing with and where can I download it?

There are plenty of browsers to test with, legacy browsers and exotic
browsers to ensure clean degradation, and modern browsers to ensure your
script works correctly (check Mozilla and Opera).
I intend
to write a full blown kbd handler that will also trap the backspace and tab
etc. I can use all the help I can get. BTW I tried doing this with a
textarea but I need to write directly to the divide.

Then you'll have to handle key events, which unfortunately haven't been
much standardised; this means you can expect different behaviors across
user agents, all the more you'll be dealing with built-in key behaviors,
like navigation, search etc which will of course differ between the
browsers you'll test your script in:)
If anyone has this working or knows of someone or a site that
has I'll be ecstatic.

Nope but it's been time since I haven't done some javascript, here's
some lines for you. Tested IE5, IE6, Mozilla and Opera 7.5. HTH.


<head>
<style type="text/css">
html, body {background:#000; color:#9f0;}
</style>
</head>

<body>
<script type="text/javascript">
// kbd
function Screen(screenId){
document.write("<div id=\""+screenId+"\">_<\/div>");
this.html=document.getElementById(screenId);
}

Screen.prototype.insertLineBreak=function() {
this.html.insertBefore(
document.createElement("br"),
this.html.lastChild
);
}

Screen.prototype.insertChar=function(c) {
this.html.insertBefore(
document.createTextNode(c),
this.html.lastChild
);
}

Screen.prototype.deleteChar=function() {
var childToRemove=this.html.lastChild &&
this.html.lastChild.previousSibling;
if(childToRemove)
this.html.removeChild(childToRemove);
}

Screen.prototype.setDefaultOutput=function() {
var screenObj=this;
var doKeyPress=true;
var keyPressReturnValue=false;

// primary key controller
// used to manage browsers' default action and secondary controller
document.onkeydown=function(evt){
var key,returnValue;

evt=evt||window.event;
key=evt.keyCode||evt.which;

returnValue=true;
doKeyPress=true;
keyPressReturnValue=false;

switch(key) {
case 8: //DEL
document.onkeypress({keyCode:8}); //special IE!
doKeyPress=false; //already done
keyPressReturnValue=false; // prevent default
returnValue=false; // prevent default
break;

case 116: //refresh
doKeyPress=false; //don't print anything
keyPressReturnValue=true; //permit the refresh
returnValue=true; //permit the refresh
break;
}

return returnValue;
}

// secondary key controller
// used to handle regular keystrokes
document.onkeypress = function(evt) {
var key;
evt=evt||window.event;
key=evt.keyCode||evt.which;

if(doKeyPress) {
switch(key) {
case 0 : //undefined
case 16: //SHIFT
case 17: //CTRL
case 18: //ALTGR
break;

case 13: //ENTER
screenObj.insertLineBreak();
break;

case 8: //DEL
screenObj.deleteChar();
break;

default:
screenObj.insertChar(String.fromCharCode(key));
break;
}
}

return keyPressReturnValue;
}
}

// main
if(document.getElementById &&
document.createTextNode &&
document.createElement &&
document.body &&
document.body.appendChild &&
document.body.removeChild &&
document.body.insertBefore
){

(new Screen("screen")).setDefaultOutput();

} else {
document.write("<p>System failure /<\/p>");
}
</script>
<noscript><p>System failure /</p></noscript>
</body>
 
J

J. J. Cale

Thank you! Youv'e saved me a lot of work. I can plug this straight into my
project and tweak it to my needs.

Actually I was hoping to do this without the DOM. I already did most of this
with the textarea for input and assignment via the DOM. Your code is tighter
and much more elegant!!

In IE5 the appending of the charachter '\n' to the objects data attribute
(or to innerText) gave me the line feed but this disappeared when I upgraded
to IE6. I did my homework on the different ways that browsers handle events.
Can you change my original code to append the '\n' or if necessary '\r\n'
and have the cursor 'move' to the next line?(no DOM).

If not I thank you again for your excellent solution and your time. Be
thrice blessed.

Jimbo
 
Y

Yann-Erwan Perio

J. J. Cale wrote:

Hi Jimbo,
Thank you! Youv'e saved me a lot of work. I can plug this straight into my
project and tweak it to my needs.

Glad that helped:)
Actually I was hoping to do this without the DOM.

I cannot really comment about this, a script conception depends on the
context, if you can tell us what you're exactly trying to achieve then I
(or others) might provide you with some more information on how to
tackle the problem at a global level.
In IE5 the appending of the charachter '\n' to the objects data attribute
(or to innerText) gave me the line feed but this disappeared when I upgraded
to IE6.

I cannot see this, to me the behavior is the same in IE5 and IE6 - could
you post a simple test case?
Can you change my original code to append the '\n' or if necessary '\r\n'
and have the cursor 'move' to the next line?(no DOM).

I'm afraid not, to me inserting a line break won't work, you have to
insert a BR element, using DOM methods or innerHTML with some dummy text
(innerHTML="<br>" does nothing AFAICS).

Also note that mixing innerHTML and innerText might provide unwanted
side-effects, since reading a BR via innerText, and writing innerText
afterwards, transforms the BR into CR/LF, which will render differently
on the screen.


Regards,
Yep.
 
Y

Yann-Erwan Perio

Yann-Erwan Perio said:
(innerHTML="<br>" does nothing AFAICS).

I've just reviewed my test case, it's faulty - innerHTML works fine of
course, it's just that I also tested for innerText and got unexpected
results with it (I'm not used to innerText) - sorry for the confusion!


<div id="foo">&nbsp;</div>
<script type="text/javascript">
function L() {alert(foo.innerText.length)};

foo.innerHTML="<br>"; L(); //0
foo.innerHTML="<br>1"; L(); //3
foo.innerHTML="<br> <br>"; L(); //0
foo.innerHTML="<br>1 "; L(); //4
foo.innerHTML="<br> 1"; L(); //3
foo.innerHTML="<br>1 <br>"; L(); //4
foo.innerHTML="<br> 1<br>"; L(); //3
</script>
 
J

J. J. Cale

YEP Sorry about the email. Hit the reply instead of group reply. Thanks for
staying with me.
if you can tell us what you're exactly trying to achieve then I
(or others) might provide you with some more information on how to
tackle the problem at a global level.

from original post -
"The intention here is to have a letter" (letterhead) "that can have
different borders clipart etc and the ability to select text and change the
various css properties or use exec Command to toggle them."
Also note that mixing innerHTML and innerText might provide unwanted
side-effects, since reading a BR via innerText, and writing innerText
afterwards, transforms the BR into CR/LF, which will render differently
on the screen.

Definately! I only used innerText to see if I got the same result as
obj.firstChild.data and didn't use it for assignment. I've been checking
both the DOM possibilities and innerHTML. Both have their challenges. AFAIK
innerText is not as widely supported as innerHTML and the DOM is fairly
safe.

Does Mozilla have the event object limitations of Netscape's DOM?
Does it support the createTextRange or createRange or createControlRange
methods?
Have you any ideas how to emulate IE execCommand in Mozilla?

Your code has another advantage in that it creates a separate textNode for
each character. I read that text nodes can be the target/srcElement of the
event object. Does the DOM have a separate event model? I am confused
probably about this.

Here is the basis of my last project. Sorry IE only.
in my original project changeSelection() is called from a controller with
options for bold, italic, underline, family, size, justification and color.
It is passed a parameter: changeSelection('Bold') which I switch in the
original function and pass to execCommand or another function.
e.g.
<a href="#" onclick = "changeSelection('Bold'); return false;"><b>B</b></a>
<a href="#" onclick = "changeSelection('Italic'); return
false;"><i>I</i></a>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD> <TITLE>Stationary Project Handlers</TITLE>
<style type=text/css>
<!--
#letter {
position:absolute;
top:20px;
width:45%;
height:90%;
background-color:#ffffcc;
color:navy;
padding:15px;
border:1px black solid;
}
-->
</style>
<script language="JavaScript">
function handleKey() {
if(event.keyCode == 8) {
letter.innerHTML =
letter.innerHTML.substring(0,letter.innerHTML.length-2) + '_';
event.returnValue = false;
}
if(event.keyCode == 13) {
letter.innerHTML =
letter.innerHTML.substring(0,letter.innerHTML.length-1);
letter.innerHTML += '<br>_';
event.returnValue = false;
}
}
function keyPress(){
letter.innerHTML =
letter.innerHTML.substring(0,letter.innerHTML.length-1);
var a = String.fromCharCode(event.keyCode);
if(!a) {alert("NO");return;}
letter.innerHTML += (a + '_');
}
function changeSelection() { // primitive just for example
// alert(letter.innerHTML); return; // for debugging
var range = document.selection.createRange();
var str=range.text;
range=document.body.createTextRange();
range.findText(str);
range.execCommand('Bold');
document.selection.empty();
}
document.onkeydown = handleKey;
document.onkeypress = keyPress;
document.onmouseup=changeSelection;
</script></HEAD>
<BODY><div id="letter">_</div></BODY></HTML>
Thanks again Jimbo
 
Y

Yann-Erwan Perio

J. J. Cale said:
from original post -
"The intention here is to have a letter" (letterhead) "that can have
different borders clipart etc and the ability to select text and change the
various css properties or use exec Command to toggle them."

You're right sorry, I read it too fast. The best cross-browser way is to
use a textarea and have the content parsed server-side, but if you can
afford reducing your browsers' range then give a look to
designMode-based editors.
Does Mozilla have the event object limitations of Netscape's DOM?

Argh. What event object limitation? Mozilla, as Netscape 7+, follows the
W3C's event model, which is much more powerful than IE's event model
(event capture, custom events...).

<URL:http://www.brainjar.com/dhtml/events/>
<URL:http://www.w3.org/TR/DOM-Level-3-Events/>

The tutorial is quite old, but remains instructive; the reference is a
bit hard, though certainly worth a long study.
Does it support the createTextRange or createRange or createControlRange
methods?

Not as IE proprietary methods:) However, Mozilla implements the W3C
Ranges specification, also adding some proprietary things.

Have you any ideas how to emulate IE execCommand in Mozilla?

It depends on the command being executed. If it's related to style, then
you can emulate it using DOM ranges and heavy DOM nodes manipulation.
I've posted a way to emulate the "Bold" command some while ago.

<URL:http://groups.google.com/[email protected]>

The approach to emulate italic, underline and forecolor at the same time
would be a bit different, though. I believe that the best way would be
to use SPAN elements with multiple CSS classes; not an easy coding task.
I read that text nodes can be the target/srcElement of the
event object.

And where did you read that:) In IE events only go to elements, and in
Mozilla it depends on the version. Basically don't count on events for
text nodes.

However using a textNode per char should prove useful since you can
design string-like methods (a node is a char).


Cheers,
Yep.
 

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,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top