|
 |
asp_web_howto thread: Combo Dropdown Typing
Message #1 by "Chris R. Thompson" <cthompson@n...> on Thu, 14 Mar 2002 10:39:32 -0700
|
|
This is a multi-part message in MIME format.
------_=_NextPart_001_01C1CB7F.3374ED1C
Content-Type: text/plain;
charset="US-ASCII"
Content-Transfer-Encoding: quoted-printable
In VB there are several types of combo boxes. In ASP there seems to be
only 1 type. The user can hit the first letter of the item in a box and
continue to hit the letter to scroll it within that character on the
drop down list. Is there any way to let the user type in what they want
on the list and have it drill down in the list. Under the current way,
it they typed in "DG" they would first jump to D's then jump to the G's.
I want to be able to jump to the "DG's" if they type "DG".
Any help would be much appreciated.
Chris
Message #2 by "Brian Lowe" <brian.lowe@i...> on Mon, 18 Mar 2002 20:50:31
|
|
> In VB there are several types of combo boxes. In ASP there seems to be
> only 1 type. The user can hit the first letter of the item in a box and
> continue to hit the letter to scroll it within that character on the
> drop down list. Is there any way to let the user type in what they want
> on the list and have it drill down in the list. Under the current way,
> it they typed in "DG" they would first jump to D's then jump to the G's.
> I want to be able to jump to the "DG's" if they type "DG".
Annoying isn't it?
I had exactly the same problem with users needing a drop-down of 2000
values and to quickly jump to one by starting to type in the string.
I used server-side ASP to generate a client-side JavaScript array filled
with the values, then used the onKeyUp() event on the client to kick off a
JavaScript function to filter the SELECT contents to only those entries
matching the string in the textbox.
With 2000 entires it's a bit slow, but it soon speeds up when the list is
filtered.
Brian Lowe
---------@
Message #3 by william.sze@s... on Mon, 18 Mar 2002 16:31:59 -0500
|
|
Hi Brian,
I'm very interested in the combobox, do you mind post the javascript code?
Thanks
William
"Brian Lowe"
<brian.lowe@i... To: "ASP Web HowTo" <asp_web_howto@p...>
odia.com> cc:
Subject: [asp_web_howto] Re: Combo Dropdown Typing
03/18/2002
03:50 PM
Please respond
to "ASP Web
HowTo"
> In VB there are several types of combo boxes. In ASP there seems to be
> only 1 type. The user can hit the first letter of the item in a box and
> continue to hit the letter to scroll it within that character on the
> drop down list. Is there any way to let the user type in what they want
> on the list and have it drill down in the list. Under the current way,
> it they typed in "DG" they would first jump to D's then jump to the G's.
> I want to be able to jump to the "DG's" if they type "DG".
Annoying isn't it?
I had exactly the same problem with users needing a drop-down of 2000
values and to quickly jump to one by starting to type in the string.
I used server-side ASP to generate a client-side JavaScript array filled
with the values, then used the onKeyUp() event on the client to kick off a
JavaScript function to filter the SELECT contents to only those entries
matching the string in the textbox.
With 2000 entires it's a bit slow, but it soon speeds up when the list is
filtered.
Brian Lowe
---------@
Message #4 by "Phil Frigo" <philfrigo@a...> on Mon, 18 Mar 2002 15:07:14 -0600
|
|
In my view, 2000 entries don't really belong in a drop down list. Waste
of dbase read time and memory. As far as drop down lists that use the
drill down with sequential lettering goes, I have found that a simple
keyboard error can really through the search algorithms out of wack,
leading to user frustration.
The defacto standard for these drop-down lists now seem to be;
* You want Indiana, type I for Idaho, Illinois and I again for
Indiana.
It's really not so bad.
Phil Frigo.
-----Original Message-----
From: Brian Lowe [mailto:brian.lowe@i...]
Sent: Monday, March 18, 2002 8:51 PM
To: ASP Web HowTo
Subject: [asp_web_howto] Re: Combo Dropdown Typing
> In VB there are several types of combo boxes. In ASP there seems to
be
> only 1 type. The user can hit the first letter of the item in a box
and
> continue to hit the letter to scroll it within that character on the
> drop down list. Is there any way to let the user type in what they
want
> on the list and have it drill down in the list. Under the current
way,
> it they typed in "DG" they would first jump to D's then jump to the
G's.
> I want to be able to jump to the "DG's" if they type "DG".
Annoying isn't it?
I had exactly the same problem with users needing a drop-down of 2000
values and to quickly jump to one by starting to type in the string.
I used server-side ASP to generate a client-side JavaScript array filled
with the values, then used the onKeyUp() event on the client to kick off
a
JavaScript function to filter the SELECT contents to only those entries
matching the string in the textbox.
With 2000 entires it's a bit slow, but it soon speeds up when the list
is
filtered.
Brian Lowe
---------@
Message #5 by "Brian Lowe" <brian.lowe@i...> on Tue, 19 Mar 2002 09:44:56
|
|
> I'm very interested in the combobox, do you mind post the javascript
JavaScript goes in the <HEAD> section of your HTML...
<script language="JavaScript1.2">
function findValue(v) {
selectedValue.innerText = 'Searching...';
filterSelect(v)
}
function reportValue(v) {
selectedValue.innerText = v;
}
function fillSelect() {
var oInput = document.getElementById("inputBox");
oInput.value = ''; // clear it out
var oSelect = document.getElementById("selectBox");
oSelect.innerHTML = ''; // clear it out
var oSelected = document.getElementById("selectedValue");
oSelected.innerText = 'None selected...';
for(var i = 0; i<aStrings.length;i++) {
var oOption = document.createElement("Option");
oOption.value = aStrings[i];
oOption.text = aStrings[i];
oSelect.add(oOption)
}
}
function filterSelect(s) {
var oSelect = document.getElementById("selectBox");
var iCount = 0;
var iSingle;
oSelect.innerHTML = ''; // clear it out
for(var i = 0; i<aStrings.length;i++) {
if (s.toLowerCase() == aStrings[i].substr(0,s.length).toLowerCase()) {
var oOption = document.createElement("Option");
oOption.value = aStrings[i];
oOption.text = aStrings[i];
oSelect.add(oOption);
iCount++;
iSingle = i
}
}
if (iCount == 1) {
oSelect.selectedIndex = 0;
reportValue('Selected value: ' + aStrings[iSingle])
} else if (iCount == 0) {
reportValue('No match found');
} else {
reportValue('Multiple matches found');
}
}
</script>
This goes in the <BODY> of your HTML
<form action="#">
<table>
<tr><td colspan=2>Excuse the delay while the page loads.<br>
It's pulling data from a SQL table.<br>
When it's got the data it sends the lot to the client as a JavaScript
array, then the client fills the select box with all the strings.<br>
As you type in the text box JavaScript watches.<br>
After each key stroke it applies the filter to the list.<br>
If it gets to exactly 1 record, then that's the selection.<br>
If it gets to 0 records you'll have to backspace to kick off the filter
mechanism again.<br>
You can also click the selected item when it comes into view.</td></tr>
<tr><td>
<input ID="inputBox" value="" onKeyUp="findValue(this.value)"></td>
<td>Choose...</td></tr>
<tr valign=top><td rowspan=2>
<select ID="selectBox" onChange="reportValue('Selected value: ' +
this.value)" size="15">
<option>Options will</option>
<option>be filled</option>
<option>by JavaScript</option>
<option>in the</option>
<option>onLoad() event.</option>
</select>
</td>
<td ID="selectedValue">None selected...</td></tr>
<tr><td><a href="javascript:fillSelect()">RESET</a><br>
<br>
Resetting causes the list box to be refilled<br>using the unfiltered
JavaScript array.<br>
It does not requery the server but still takes a while...</td></tr>
<tr><td colspan=2 class="brag"><a href="mailto:brian.lowe@i...?
subject=listSearch.asp">Brian Lowe</a> © Feb 2002</td></tr>
</table>
</form>
and this in your asp code after the body has been sent (so that the user
gets to see something before the delay while the code fills the array then
the select list)
<script language="JavaScript1.2">
var aStrings = Array(<%
Response.Write "'" & oRs("ListValue") & "'"
oRs.MoveNext
Do While NOT oRs.EOF
Response.Write ", '" & oRs("ListValue") & "'"
oRs.MoveNext
Loop %>);
</script>
No doubt someone will come up with a much more efficient and/or elegant
way to do this.
I had an immediate need and resolved it as quickly as I could. In real
life you probably want a key value and a different displayed string in the
list. This just needs a different recordsource and slight change to the
JavaScript array to be pairs of items rather than individuals.
I'd welcome any feedback to make this more streamlined, cross-browser, etc.
Brian Lowe
---------@
Message #6 by "Tim Morford" <tmorford@n...> on Tue, 19 Mar 2002 09:11:53 -0500
|
|
--------------html/asp code ---------------------------------------
<span size="20" name="Form_ID" style="behavior:url(combobox.htc)">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</span>
-------------------end --------------------------------------------
-----------combobox.htc-------------------------------------------
<PUBLIC:COMPONENT tagName="COMBOBOX">
<PUBLIC:property name="textfield" />
<PUBLIC:property name="popup" />
<PUBLIC:attach event="ondocumentready" handler="setUpComboBox" />
<SCRIPT language="JavaScript">
function setUpComboBox() {
if (null == popup) {
element.innerHTML="<select>" + element.innerHTML + "</select>";
popup = element.children(0);
element.appendChild(popup);
var prop;
for (prop in element) {
var val = element.getAttribute(prop,3);
if (val != null && val != "" && prop != "name" && prop != "size") {
popup.setAttribute(prop,val);
}
}
popup.id = element.name + "_popup";
popup.attachEvent("onchange", takeValueFromPopup);
popup.attachEvent("onfocus", popupfocus);
popup.attachEvent("onblur", popupblur);
}
if (null == textfield) {
textfield = document.createElement("INPUT");
textfield.id = element.name + '_text';
textfield.name = element.name;
textfield.associatedPopup = popup;
popup.textfield = textfield;
if (element.size != null && element.size > 0 && popup.currentStyle.width
== "auto") {
textfield.size=element.size;
} else {
textfield.style.posWidth=element.clientWidth-16;
}
textfield.attachEvent("onchange",takeValueFromTextfield);
textfield.attachEvent("onkeyup",completeTyping);
textfield.attachEvent("onkeydown",txtkeydown);
element.parentElement.insertBefore(textfield, element);
textfield.style.marginRight='16px';
takeValueFromPopupAt(popup);
}
popup.style.position="absolute";
popup.tabIndex=-1;
popup.style.setExpression("posWidth", "textfield.clientWidth+20",
"JavaScript");
popup.style.left = '1px';
popup.findLeftOffset=findLeftOffset;
popup.style.setExpression("posLeft", "findLeftOffset(textfield)",
"JavaScript");
popup.style.top = '1px';
popup.findTopOffset=findTopOffset;
popup.style.setExpression("posTop", "findTopOffset(textfield)",
"JavaScript");
popup.style.setExpression("posHeight", "textfield.clientHeight",
"JavaScript");
popup.style.setExpression("clip","'rect(auto auto auto
'+(textfield.clientWidth+2)+')'", "JavaScript");
popup.needsblur=false;
}
function takeValueFromPopup() {
takeValueFromPopupAt(event.srcElement);
}
function takeValueFromPopupAt(popup) {
var idx=popup.selectedIndex;
var textfield=popup.textfield;
if (idx != null && idx >= 0) {
textfield.value = popup.options[idx].text;
}
if (popup.needsblur) {
textfield.focus();
textfield.select();
}
}
function takeValueFromTextfield() {
var txt = event.srcElement;
var popup = txt.associatedPopup;
var idx;
for(idx=0;idx<popup.options.length;idx++) {
if (popup.options[idx].text == txt.value) {
popup.selectedIndex=idx;
return;
}
}
popup.selectedIndex=-1;
}
function popupblur() {
var popup = event.srcElement;
popup.needsblur=false;
}
function popupfocus() {
var popup = event.srcElement;
popup.needsblur=true;
}
function txtkeydown() {
if (event.keyCode == 40) {
if (popup.selectedIndex < popup.options.length-1)
popup.selectedIndex += 1;
takeValueFromPopupAt(popup);
}
// Up Arrow
if (event.keyCode == 38) {
if (popup.selectedIndex > 0)
popup.selectedIndex -= 1;
else if (popup.selectedIndex == -1)
popup.selectedIndex = popup.options.length-1;
takeValueFromPopupAt(popup);
}
}
function completeTyping() {
if (event.keyCode < 0x2f && event.keyCode != 32)
return;
var text = event.srcElement.value;
var popup = event.srcElement.associatedPopup;
var options = popup.options;
var i;
var utext = text.toUpperCase();
for(i=0;i<options.length;i++) {
var newtxt = options[i].text;
var uopt = newtxt.toUpperCase();
if (uopt != utext && 0 == uopt.indexOf(utext)) {
var txtrange = event.srcElement.createTextRange();
event.srcElement.value = text + newtxt.substr(text.length);
txtrange.moveStart("character", text.length);
txtrange.select();
takeValueFromTextfield();
break;
}
}
}
function findLeftOffset(elem) {
var left = 0;
while (elem.tagName != "BODY") {
left += elem.offsetLeft;
elem = elem.offsetParent;
}
return left;
}
function findTopOffset(elem) {
var top = 0;
while (elem.tagName != "BODY") {
top += elem.offsetTop;
elem = elem.offsetParent;
}
return top;
}
</SCRIPT>
</PUBLIC:COMPONENT>
---------------------------------end ---------------------------------------
-
Tim Morford
http://www.aspalliance.com/tmorford
> In VB there are several types of combo boxes. In ASP there seems to be
> only 1 type. The user can hit the first letter of the item in a box and
> continue to hit the letter to scroll it within that character on the
> drop down list. Is there any way to let the user type in what they want
> on the list and have it drill down in the list. Under the current way,
> it they typed in "DG" they would first jump to D's then jump to the G's.
> I want to be able to jump to the "DG's" if they type "DG".
|
|
 |