[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    Konqueror and Autosuggest boxes
From:       Neill Jones <neilljones () yahoo ! co ! uk>
Date:       2007-02-14 21:48:47
Message-ID: 45D383BF.10300 () yahoo ! co ! uk
[Download RAW message or body]

Hi all,

I hope this is the right forum for this question ... I've included a 
sample page
which demonstrates the problem.

I am trying to implement an autosuggest drop down box and have built one up
from an example on the web. It works in IE, Firefox, Ephiphany and to an 
extent
in Opera. Unfortunately in Konqueror, the drop down box does not appear. 
Does
anyone have any experience of writing these for Konqueror, or know of 
any pitfalls
that one needs to be aware of? When I've tested what keyCodes are 
returned when
pressing keys in the input, it comes back with 0 each time in Konqueror 
but the
expected keys on the other browsers, so I suspect it is the way the 
keyCodes are
being picked up that is the problem.

The keypresses on the text input are registered to the autoSuggest 
object using
                this.textbox.onkeydown = function (oEvent) {
                    if (!oEvent) oEvent = window.event;
                    oThis.handleKeyDown(oEvent);
                };
(where oThis is a reference to an AutoSuggestControl object) etc for 
other key presses,
and the autoSuggest object handles these as ...
              AutoSuggestControl.prototype.handleKeyUp = function (oEvent) {
                var iKeyCode = oEvent.keyCode;
// alert(iKeyCode);
                if (iKeyCode == 8 || iKeyCode == 46)
                    this.provider.requestSuggestions(this, false);
                if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode <= 46) 
|| (iKeyCode >= 112 && iKeyCode <= 123)) {
                    //ignore
                } else {
                    this.provider.requestSuggestions(this);
                }
            };
When I check the keyCodes here they are 0 in Konqueror.

How can you extract the keys from events in Konqueror and on what elements?
Does anyone have any good sources for event programming on Konqueror, in 
particular picking
up key presses?

Thank in advance for any pointers

Regards

Neill Jones


["autosuggest.html" (text/html)]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" \
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" \
url="/whosUp4/systemPrototype/presentationLayer/web/public/anon/tests/forms/autoSuggest">
  <head>
		<style>
			div.suggestions {
				border: 1px solid black;
				position: absolute;
			}
			
			div.suggestions div {
				cursor: default;
				padding: 0px 3px;
			}
			
			div.suggestions div.current {
				background-color: #3366cc;
				color: white;
			}
		</style>
		<script>
			// Autosuggestion Form Element Client Side
			// 
			// Copyright and source: http://www.webreference.com/programming/javascript/ncz/
			// 
			// This code is taken pretty much verbatim from Nicholas's series of articles
			// and so many thanks to Nicholas C. Zakas for an excellent tutorial!
			
			//
			// AutoSuggest Control Class 
			//
			// constructor
			function AutoSuggestControl(oTextbox, oProvider) {
				this.cur = -1;
				this.layer = null;
				this.provider = oProvider;
				this.textbox = oTextbox;
				this.init();
			};
			
			// initialise this object and assign it to the textbox
			// that we are going to put the information into.
			AutoSuggestControl.prototype.init = function () {
				var oThis = this;
				this.textbox.onkeyup = function (oEvent) {
					if (!oEvent) oEvent = window.event;
					oThis.handleKeyUp(oEvent);
				};
				this.textbox.onkeydown = function (oEvent) {
					if (!oEvent) oEvent = window.event;
					oThis.handleKeyDown(oEvent);
				};
				this.textbox.onblur = function () {
					oThis.hideSuggestions();
				};
				this.createDropDown();
			};
				
			// select the range of added information in the text box
			AutoSuggestControl.prototype.selectRange = function (iStart, iLength) {
				if (this.textbox.createTextRange) { // internet explorer
					var oRange = this.textbox.createTextRange();
					oRange.moveStart("character", iStart);
					oRange.moveEnd("character", iLength - this.textbox.value.length);
					oRange.select();
				} else if (this.textbox.setSelectionRange) { // mozilla
					this.textbox.setSelectionRange(iStart, iLength);
				}
				this.textbox.focus();
			};
			
			// add suggestions in only if selectRange is supported by the browser
			// by typing ahead the first of the suggestions and changing it as
			// they type in more of the possibility
			AutoSuggestControl.prototype.typeAhead = function (sSuggestion) {
				if (this.textbox.createTextRange || this.textbox.setSelectionRange) {
					var iLen = this.textbox.value.length;
					this.textbox.value = sSuggestion;
					this.selectRange(iLen, sSuggestion.length);
				}
			};
			
			// the method which triggers the type ahead and hence selectRange
			// methods - this is called by the provider with the returned suggestions
			AutoSuggestControl.prototype.autosuggest = function (aSuggestions, bTypeAhead) {
				if (aSuggestions.length > 0) {
					if (bTypeAhead) {
							this.typeAhead(aSuggestions[0]);
					}
					this.showSuggestions(aSuggestions);
				} else {
					this.hideSuggestions();
				}
			};
			// handling key presses on the textbox this is attached to
			// make sure they are within the range of normal characters
			// (assuming that people are typing in English only
			AutoSuggestControl.prototype.handleKeyUp = function (oEvent) {
				var iKeyCode = oEvent.keyCode;
				if (iKeyCode == 8 || iKeyCode == 46)
					this.provider.requestSuggestions(this, false);
				if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode <= 46) || (iKeyCode >= 112 && \
iKeyCode <= 123)) {  //ignore
				} else {
					this.provider.requestSuggestions(this);
				}
			};
					
			// hide the suggestions dropdown box
			AutoSuggestControl.prototype.hideSuggestions = function () {
				this.layer.style.visibility = "hidden";
			};
			
			// select the suggestion they have highlighted
			AutoSuggestControl.prototype.highlightSuggestion = function (oSuggestionNode) {
				for (var i=0; i < this.layer.childNodes.length; i++) {
					var oNode = this.layer.childNodes[i];
					if (oNode == oSuggestionNode) {
						oNode.className = "current"
					} else if (oNode.className == "current") {
						oNode.className = "";
					}
				}
			};
			
			// create the dropdown suggest box below the textbox
			AutoSuggestControl.prototype.createDropDown = function () {
				this.layer = document.createElement("div");
				this.layer.className = "suggestions";
				this.layer.style.visibility = "hidden";
				this.layer.style.width = this.textbox.offsetWidth;
				document.body.appendChild(this.layer);
				
				// now to assign the event handlers (keyboard presses are handled separately)
				var oThis = this;
				this.layer.onmousedown = this.layer.onmouseup =
				this.layer.onmouseover = function (oEvent) {
					oEvent = oEvent || window.event;
					oTarget = oEvent.target || oEvent.srcElement;
					if (oEvent.type == "mousedown") {
							oThis.textbox.value = oTarget.firstChild.nodeValue;
							oThis.hideSuggestions();
					} else if (oEvent.type == "mouseover") {
							oThis.highlightSuggestion(oTarget);
					} else {
							oThis.textbox.focus();
					}
				};
			};
			
			// find out where the left hand side of the element is
			AutoSuggestControl.prototype.getLeft = function () {
				var oNode = this.textbox;
				var iLeft = 0;
				while(oNode.tagName != "BODY") {
					iLeft += oNode.offsetLeft;
					oNode = oNode.offsetParent;
				}
				return iLeft;
			};
			
			// find out where the top of the element is
			AutoSuggestControl.prototype.getTop = function () {
				var oNode = this.textbox;
				var iTop = 0;
				while(oNode.tagName != "BODY") {
					iTop += oNode.offsetTop;
					oNode = oNode.offsetParent;
				}
				return iTop;
			};
			
			// populate the dropdown box with the suggestions
			AutoSuggestControl.prototype.showSuggestions = function (aSuggestions) {
				var oDiv = null;
				this.layer.innerHTML = "";
				for (var i=0; i < aSuggestions.length; i++) {
					oDiv = document.createElement("div");
					oDiv.appendChild(document.createTextNode(aSuggestions[i]));
					this.layer.appendChild(oDiv);
				}
				this.layer.style.left = this.getLeft() + "px";
				this.layer.style.top = (this.getTop()+this.textbox.offsetHeight) + "px";
				this.layer.style.visibility = "visible";
			};
			
			// highlight the next suggestion
			AutoSuggestControl.prototype.nextSuggestion = function () {
				var cSuggestionNodes = this.layer.childNodes;
				if (cSuggestionNodes.length > 0 && this.cur < cSuggestionNodes.length-1) {
					var oNode = cSuggestionNodes[++this.cur];
					this.highlightSuggestion(oNode);
					this.textbox.value = oNode.firstChild.nodeValue;
				}
			};
			
			// highlight the previous suggestion
			AutoSuggestControl.prototype.previousSuggestion = function () {
				var cSuggestionNodes = this.layer.childNodes;
				if (cSuggestionNodes.length > 0 && this.cur > 0) {
					var oNode = cSuggestionNodes[--this.cur];
					this.highlightSuggestion(oNode);
					this.textbox.value = oNode.firstChild.nodeValue;
				}
			};
			
			// handle when a user pushes a key down for up, down and enter buttons
			AutoSuggestControl.prototype.handleKeyDown = function (oEvent) {
					switch(oEvent.keyCode) {
							case 38: //up arrow
									this.previousSuggestion();
									break;
							case 40: //down arrow
									this.nextSuggestion();
									break;
							case 13: //enter
									this.hideSuggestions();
									break;
					}
			};
			
			
			//
			// Suggestion Provider Class
			//
			
			// dummy suggestions array
			function StateSuggestions() {
				this.states = [
					"Alabama", "Alaska", "Arizona", "Arkansas",
					"California", "Colorado", "Connecticut",
					"Delaware", "Florida", "Georgia", "Hawaii",
					"Idaho", "Illinois", "Indiana", "Iowa",
					"Kansas", "Kentucky", "Louisiana",
					"Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota",
					"Mississippi", "Missouri", "Montana",
					"Nebraska", "Nevada", "New Hampshire", "New Mexico", "New York",
					"North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon",
					"Pennsylvania", "Rhode Island", "South Carolina", "South Dakota",
					"Tennessee", "Texas", "Utah", "Vermont", "Virginia",
					"Washington", "West Virginia", "Wisconsin", "Wyoming"
				];
			};
			StateSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl, \
bTypeAhead) {  var aSuggestions = [];
				var sTextboxValue = oAutoSuggestControl.textbox.value;
				if (sTextboxValue.length > 0) {
					var sTextboxValueLC = sTextboxValue.toLowerCase();
					for (var i=0; i < this.states.length; i++) {
						var sStateLC = this.states[i].toLowerCase();
						if (sStateLC.indexOf(sTextboxValueLC) == 0) {
								aSuggestions.push(sTextboxValue + \
this.states[i].substring(sTextboxValue.length));  }
					}
					oAutoSuggestControl.autosuggest(aSuggestions, bTypeAhead);
				}
			};
		</script>
		<script type="text/javascript">
		{
			window.onload = function () {
				var oTextbox = new AutoSuggestControl(document.getElementById("txt1"), new \
StateSuggestions());  }
		}
		</script>
	</head>
	<body>
		<p>In Konqueror, the key presses for up down and enter arrows are not registered \
(all key presses come  back with a keyCode of 0). Is this because Konqueror only \
registers keyCodes on text inputs (and the key  presses are on the divs of the \
drop-down box)? Does anyone know of any other methods that also work with  Konqueror? \
(Tested on Konqueror 3.5.4).  <div>
			<p>Type in M to see autocompletion for US States in Firefox but not \
Konqueror.<input autocomplete="off" type="text" id="txt1" /></p>  </div>
	</body>
</html>


___________________________________________________________ 
Try the all-new Yahoo! Mail. "The New Version is radically easier to use"  The Wall Street Journal
http://uk.docs.yahoo.com/nowyoucan.html

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic