From: Alan Gutierrez on
Wenguang Wang wrote:

> On Jul 23, 9:47 pm, Alan Gutierrez <a...(a)blogometer.com> wrote:
>> Wenguang Wang wrote:
>>> Hi,
>>> My web page has a dynamic combo box which contains some dynamic
>>> information queried from the database. Currently I am using php to
>>> generate such a page with the dynamic information.
>>> However, I want it to be more dynamic: when I click the combo box,
>>> before the combo box shows me all options, it should query the
>>> database and get the latest results. Otherwise, the user has to
>>> manually click the refresh button.
>>> Is there a way to achieve such thing using combo box? If not, what
>>> control and what technique should I use?

>> The select element has a DOM interface that allows you to add and remove
>> options. I assume you mean "SELECT" since there is no real combo box in
>> available in the DOM.
>>
>> https://developer.mozilla.org/en/DOM/select
>>
>> To get the information, your going to need to fetch it using XMLHttpRequest.
>>
>> http://www.w3.org/TR/XMLHttpRequest/
>>
>> Then you'd return JSON from your PHP script and evaluate the response.
>>
>> This would be the way to do it with raw JavaScript. A library like
>> Prototype or jQuery could also be very helpful, but people on this
>> newsgroup do not like them because they leak memory on older browsers.

> Very helpful! I used AJAX to send the query, and parsed the received
> JSON output generated by php, and got it working. Thank you very
> much!
>
> One thing is that I don't know what event of the select box I should
> use to trigger the ajax event. When I use the OnFocus event, it is
> acting funny that sometimes it does not refresh the list. So now I am
> using OnMouseOver. May not be very efficient, but it works. I hope I
> could get an event right before the drop down box is shown so I can
> fill the list in that event. Is this possible?

Please don't top post. A little nit. It is easier to keep the dialog
going from top to bottom.

You're now talking about auto-complete, which means you'll want to use
something besides the standard drop-down "SELECT" control. You really do
want a combo box.

Have a look at jQuery UI auto-complete.

http://jqueryui.com/demos/autocomplete/

There are other implementations of auto-complete, too. I've used this
one before to good effect.

The concept is that it will drop down a div beneath a text field with
options. You can populate this drop-down using AJAX and it will update
as the user types in characters.

--
Alan Gutierrez - alan(a)blogometer.com - http://twitter.com/bigeasy
From: David Mark on
On Jul 25, 2:57 am, Alan Gutierrez <a...(a)blogometer.com> wrote:
> Wenguang Wang wrote:
> > On Jul 23, 9:47 pm, Alan Gutierrez <a...(a)blogometer.com> wrote:
> >> Wenguang Wang wrote:
> >>> Hi,
> >>> My web page has a dynamic combo box which contains some dynamic
> >>> information queried from the database.  Currently I am using php to
> >>> generate such a page with the dynamic information.
> >>> However, I want it to be more dynamic: when I click the combo box,
> >>> before the combo box shows me all options, it should query the
> >>> database and get the latest results.  Otherwise, the user has to
> >>> manually click the refresh button.
> >>> Is there a way to achieve such thing using combo box?  If not, what
> >>> control and what technique should I use?
> >> The select element has a DOM interface that allows you to add and remove
> >> options. I assume you mean "SELECT" since there is no real combo box in
> >> available in the DOM.
>
> >>https://developer.mozilla.org/en/DOM/select
>
> >> To get the information, your going to need to fetch it using XMLHttpRequest.
>
> >>http://www.w3.org/TR/XMLHttpRequest/
>
> >> Then you'd return JSON from your PHP script and evaluate the response.
>
> >> This would be the way to do it with raw JavaScript. A library like
> >> Prototype or jQuery could also be very helpful, but people on this
> >> newsgroup do not like them because they leak memory on older browsers.
>
>  > Very helpful!  I used AJAX to send the query, and parsed the received
>  > JSON output generated by php, and got it working.  Thank you very
>  > much!
>  >
>  > One thing is that I don't know what event of the select box I should
>  > use to trigger the ajax event.  When I use the OnFocus event, it is
>  > acting funny that sometimes it does not refresh the list.  So now I am
>  > using OnMouseOver.  May not be very efficient, but it works.  I hope I
>  > could get an event right before the drop down box is shown so I can
>  > fill the list in that event.  Is this possible?
>
> Please don't top post. A little nit. It is easier to keep the dialog
> going from top to bottom.
>
> You're now talking about auto-complete, which means you'll want to use
> something besides the standard drop-down "SELECT" control. You really do
> want a combo box.

Well, there's no such thing. What he wants is a read-only text input,
a button and a list (a faux SELECT basically).

>
> Have a look at jQuery UI auto-complete.
>

[...]

Don't bother. Not only is it the wrong widget, but it requires
including a dubious 70K of jQuery to boot.

>
> There are other implementations of auto-complete, too.

Loads (most of them awful). But the OP is not after an auto-complete
widget.

> I've used this
> one before to good effect.

As you see it. Of course, it is piled on top of the shambles that is
jQuery, so...

>
> The concept is that it will drop down a div beneath a text field with
> options.

Options? That's an unfortunately confusing term in this context. You
drop down a list (perhaps wrapped in a DIV).

> You can populate this drop-down using AJAX and it will update
> as the user types in characters.
>

You populate the list with list items, much in the same way that you
populated the SELECT in the previous (aborted) example. Instead of
creating OPTION elements, you create LI's. You use
document.createElement to create them and the appendChild method of
the list to append them. When the list (or DIV) is first created, it
is styled to be invisible and absent from the layout (display:none).
When the user clicks the button, you set the display style of the list
to an empty string (""), which adds it to the layout and makes it
visible (the default display style will apply).

As for positioning, the textbox and button should be placed in a
relatively positioned DIV (position:relative) and the list (or
containing DIV) should be absolutely positioned with left/top styles
that put it just below the textbox and aligned to its left edge. If
elTextbox references the text input and elDiv references a DIV
containing the list:-

elDiv.style.left = elTextbox.offsetLeft + 'px';
elDiv.style.top = (elTextbox.offsetTop + elTextbox.offsetHeight) +
'px';

....then display it like this:-

elDiv.style.display = '';

It should be clear what to do when the user clicks the outer container
while the list is displayed. The target will either be a list item,
the text node contained in a list item or something else. If the
target node type is a text node (nodeType property), reference its
parent (parentNode property).

The first two cases set the value property of the text input to the
text contained by the list item (see innerText and textContent).
Regardless of the target, all clicks set the display style of the list
(or containing DIV) back to 'none'. One caveat to this, which is a
matter of taste, is that clicking the button while the list is
displayed may be treated as if it didn't happen (the list remains
displayed). Another is that you may want to attach the click handler
to the BODY element (or HTML element is the body has margins) so that
the list goes away on clicking anywhere in the document.

As for cross-browser compatibility; it should hopefully go without
saying in this case, but don't put a border on the outer container as
some browser's offsetLeft/Top properties include the border width
(which is obviously unwanted here). In fact, explicitly set the
border style to 'none' (or set the border-width to '0') in the
*script* (the inline style will be less likely to be stepped on by
user style sheets or future developers twiddling with the
presentation).

For the purposes of progressive enhancement, you should start with a
standard SELECT and then replace it with a newly created DIV as
prescribed above (but only after appropriate feature detection, of
course). That way the input will work when scripting is disabled and
for browsers/configurations that do not support the required features.

Once you get the basic concept working, save the script and style
sheet for future use. Repeat for other types of widgets as needed and
eventually you will have a nice "toolkit". If something goes wrong
with one of them, you'll know exactly where to look. And if you can't
figure it out, you can post the dependency-free "plain old Javascript"
to a forum such as this one and have some hope of getting a timely
answer.

That's about it and it's not nearly as complicated as it might sound.
An experienced developer should be able to put together a working and
aesthetically pleasing rendition, including the XHR bit, in an hour
(at most). That's why most experienced developers demand relatively
exorbitant rates. ;)

Of course, the average jQuery user will take that long to download the
UI library and wade through the documentation for an inappropriate
widget. Then they will display an unnecessarily complex "creation"
that is not their own and therefore bound to the whims of the jQuery/
jQueryUI developers (who necessarily do not have any concept of the
specific project's context).

And take my word for it, they are a very whimsical bunch. All it
takes is one "wouldn't it be cool if..." suggestion that they think
can be easily implemented and it's off to the races adding more
complexity that may never be needed by the project at hand and that
may well cause problems on the next download (I've seen it happen a
thousand times over the years).

You will likely write more at the outset, but ultimately you will save
time by avoiding endless jQuery/jQueryUI "upgrades" and
incompatibilities, bugs introduced by new features that you don't
need, less-than-helpful support forums, etc. Don't let any "pro
library" zealot tell you different. They are just jealous that you
don't use a library (and thus likely command higher rates). :)
From: Wenguang Wang on
Thanks for your very detailed answer. My users always use mouse, so
the onMouseOver hack will work well for now.

The solution you described does look very complicated to me
(especially I couldn't find an example), because I am a very novice
developer of web apps.

-Wenguang

On Jul 25, 1:15 am, David Mark <dmark.cins...(a)gmail.com> wrote:
> On Jul 25, 2:57 am, Alan Gutierrez <a...(a)blogometer.com> wrote:
>
>
>
>
>
> > Wenguang Wang wrote:
> > > On Jul 23, 9:47 pm, Alan Gutierrez <a...(a)blogometer.com> wrote:
> > >> Wenguang Wang wrote:
> > >>> Hi,
> > >>> My web page has a dynamic combo box which contains some dynamic
> > >>> information queried from the database.  Currently I am using php to
> > >>> generate such a page with the dynamic information.
> > >>> However, I want it to be more dynamic: when I click the combo box,
> > >>> before the combo box shows me all options, it should query the
> > >>> database and get the latest results.  Otherwise, the user has to
> > >>> manually click the refresh button.
> > >>> Is there a way to achieve such thing using combo box?  If not, what
> > >>> control and what technique should I use?
> > >> The select element has a DOM interface that allows you to add and remove
> > >> options. I assume you mean "SELECT" since there is no real combo box in
> > >> available in the DOM.
>
> > >>https://developer.mozilla.org/en/DOM/select
>
> > >> To get the information, your going to need to fetch it using XMLHttpRequest.
>
> > >>http://www.w3.org/TR/XMLHttpRequest/
>
> > >> Then you'd return JSON from your PHP script and evaluate the response.
>
> > >> This would be the way to do it with raw JavaScript. A library like
> > >> Prototype or jQuery could also be very helpful, but people on this
> > >> newsgroup do not like them because they leak memory on older browsers.
>
> >  > Very helpful!  I used AJAX to send the query, and parsed the received
> >  > JSON output generated by php, and got it working.  Thank you very
> >  > much!
> >  >
> >  > One thing is that I don't know what event of the select box I should
> >  > use to trigger the ajax event.  When I use the OnFocus event, it is
> >  > acting funny that sometimes it does not refresh the list.  So now I am
> >  > using OnMouseOver.  May not be very efficient, but it works.  I hope I
> >  > could get an event right before the drop down box is shown so I can
> >  > fill the list in that event.  Is this possible?
>
> > Please don't top post. A little nit. It is easier to keep the dialog
> > going from top to bottom.
>
> > You're now talking about auto-complete, which means you'll want to use
> > something besides the standard drop-down "SELECT" control. You really do
> > want a combo box.
>
> Well, there's no such thing.  What he wants is a read-only text input,
> a button and a list (a faux SELECT basically).
>
>
>
> > Have a look at jQuery UI auto-complete.
>
> [...]
>
> Don't bother.  Not only is it the wrong widget, but it requires
> including a dubious 70K of jQuery to boot.
>
>
>
> > There are other implementations of auto-complete, too.
>
> Loads (most of them awful).  But the OP is not after an auto-complete
> widget.
>
> > I've used this
> > one before to good effect.
>
> As you see it.  Of course, it is piled on top of the shambles that is
> jQuery, so...
>
>
>
> > The concept is that it will drop down a div beneath a text field with
> > options.
>
> Options?  That's an unfortunately confusing term in this context.  You
> drop down a list (perhaps wrapped in a DIV).
>
> > You can populate this drop-down using AJAX and it will update
> > as the user types in characters.
>
> You populate the list with list items, much in the same way that you
> populated the SELECT in the previous (aborted) example.  Instead of
> creating OPTION elements, you create LI's.  You use
> document.createElement to create them and the appendChild method of
> the list to append them.  When the list (or DIV) is first created, it
> is styled to be invisible and absent from the layout (display:none).
> When the user clicks the button, you set the display style of the list
> to an empty string (""), which adds it to the layout and makes it
> visible (the default display style will apply).
>
> As for positioning, the textbox and button should be placed in a
> relatively positioned DIV (position:relative) and the list (or
> containing DIV) should be absolutely positioned with left/top styles
> that put it just below the textbox and aligned to its left edge.  If
> elTextbox references the text input and elDiv references a DIV
> containing the list:-
>
> elDiv.style.left = elTextbox.offsetLeft + 'px';
> elDiv.style.top = (elTextbox.offsetTop + elTextbox.offsetHeight) +
> 'px';
>
> ...then display it like this:-
>
> elDiv.style.display = '';
>
> It should be clear what to do when the user clicks the outer container
> while the list is displayed.  The target will either be a list item,
> the text node contained in a list item or something else.  If the
> target node type is a text node (nodeType property), reference its
> parent (parentNode property).
>
> The first two cases set the value property of the text input to the
> text contained by the list item (see innerText and textContent).
> Regardless of the target, all clicks set the display style of the list
> (or containing DIV) back to 'none'.  One caveat to this, which is a
> matter of taste, is that clicking the button while the list is
> displayed may be treated as if it didn't happen (the list remains
> displayed).  Another is that you may want to attach the click handler
> to the BODY element (or HTML element is the body has margins) so that
> the list goes away on clicking anywhere in the document.
>
> As for cross-browser compatibility; it should hopefully go without
> saying in this case, but don't put a border on the outer container as
> some browser's offsetLeft/Top properties include the border width
> (which is obviously unwanted here).  In fact, explicitly set the
> border style to 'none' (or set the border-width to '0') in the
> *script* (the inline style will be less likely to be stepped on by
> user style sheets or future developers twiddling with the
> presentation).
>
> For the purposes of progressive enhancement, you should start with a
> standard SELECT and then replace it with a newly created DIV as
> prescribed above (but only after appropriate feature detection, of
> course).  That way the input will work when scripting is disabled and
> for browsers/configurations that do not support the required features.
>
> Once you get the basic concept working, save the script and style
> sheet for future use.  Repeat for other types of widgets as needed and
> eventually you will have a nice "toolkit".  If something goes wrong
> with one of them, you'll know exactly where to look.  And if you can't
> figure it out, you can post the dependency-free "plain old Javascript"
> to a forum such as this one and have some hope of getting a timely
> answer.
>
> That's about it and it's not nearly as complicated as it might sound.
> An experienced developer should be able to put together a working and
> aesthetically pleasing rendition, including the XHR bit, in an hour
> (at most).  That's why most experienced developers demand relatively
> exorbitant rates.  ;)
>
> Of course, the average jQuery user will take that long to download the
> UI library and wade through the documentation for an inappropriate
> widget.  Then they will display an unnecessarily complex "creation"
> that is not their own and therefore bound to the whims of the jQuery/
> jQueryUI developers (who necessarily do not have any concept of the
> specific project's context).
>
> And take my word for it, they are a very whimsical bunch.  All it
> takes is one "wouldn't it be cool if..." suggestion that they think
> can be easily implemented and it's off to the races adding more
> complexity that may never be needed by the project at hand and that
> may well cause problems on the next download (I've seen it happen a
> thousand times over the years).
>
> You will likely write more at the outset, but ultimately you will save
> time by avoiding endless jQuery/jQueryUI "upgrades" and
> incompatibilities, bugs introduced by new features that you don't
> need, less-than-helpful support forums, etc.  Don't let any "pro
> library" zealot tell you different.  They are just jealous that you
> don't use a library (and thus likely command higher rates).  :)

From: David Mark on
On Jul 25, 10:39 am, Wenguang Wang <wenguang.w...(a)gmail.com> wrote:
> Thanks for your very detailed answer.  My users always use mouse, so
> the onMouseOver hack will work well for now.

But it has the same problem as the focus "solution", just less
pronounced (depending on circumstances).

>
> The solution you described does look very complicated to me
> (especially I couldn't find an example), because I am a very novice
> developer of web apps.

It's not nearly as complicated as it sounds. You've already for the
XHR bit and successfully stocked a SELECT with options. Stocking,
positioning and displaying a list is not a huge leap from there.

I'm sorry I didn't have time to write the whole thing for you, but
that wouldn't have helped you learn anyway.

And please stop top-posting here. It destroys the flow and context of
the conversation (which I don't have time to put back).
From: David Mark on
On Jul 25, 3:18 pm, David Mark <dmark.cins...(a)gmail.com> wrote:
> On Jul 25, 10:39 am, Wenguang Wang <wenguang.w...(a)gmail.com> wrote:
>
> > Thanks for your very detailed answer.  My users always use mouse, so
> > the onMouseOver hack will work well for now.
>
> But it has the same problem as the focus "solution", just less
> pronounced (depending on circumstances).
>
>
>
> > The solution you described does look very complicated to me
> > (especially I couldn't find an example), because I am a very novice
> > developer of web apps.
>
> It's not nearly as complicated as it sounds.  You've already for the
> XHR bit and successfully stocked a SELECT with options.  Stocking,
> positioning and displaying a list is not a huge leap from there.
>
> I'm sorry I didn't have time to write the whole thing for you, but
> that wouldn't have helped you learn anyway.
>

Also, the OP should remember what I said about re-thinking the
design. There's no reason that a standard SELECT can't be used for
this. It's just that the refresh of its options cannot be triggered
by user interaction with the control. Perhaps this control is part of
a tabbed interface and can be refreshed on displaying its containing
tab. Or maybe a time-based trigger would be appropriate. As always,
it depends on the context and designs should eliminate impossibilities
and consider what is left.