"Subclassing" the standard #autocomplete form widget
I need a widget for Forms API which is *almost* identical to the textfield autocomplete widget in 5.0. I want the same user experience -- the user types and chooses an item. But I want the underlying AJAX and Drupal behavior to differ a bit. An example of the type of widget I'd want would be a "Country Selection" widget where what I really want is the two-character country code (US, CA, GB, FR, and so on), but I want the user to think of typing "United States", "Canada", "Great Britain", "France" or so on in order to get the popup to get set on this code. Looking through the 5.0 sources, the way the current autocompletion widget works is via includes/form.inc, where the theming function theme_textfield($element) special cases textfields with the '#autocompletion_path' , by making sure that autocomplete.js gets added to the page going out, and by adding a hidden <item> to store state information that the code in autocomplete.js needs to do its work. I really don't need to change behavior very much; I just need to send back an array of array(key, value), where the standard widget sends back an array of string values. But pretty much everything else that Unconed's code does exactly what I want, and while I can copy if if that's easiest, I don't want or need to change what he did. What's the best way to create my modified Forms API widget? It looks like I'd want to "override" or "subclass" theme_textfield, although only to add behavior: I don't want standard autocomplete widgets to behave any different than usual (although I'd not want both sets of code to compete on the same widget). I'd then copy autocomplete.js and make very small changes in it, changing function names where required. Is there a better way to do this? Or even better, has someone else already done this? Thanks, Rob Rob Thorne Torenware Networks
On Wed, 17 Jan 2007, Rob Thorne wrote:
I really don't need to change behavior very much; I just need to send back an array of array(key, value), where the standard widget sends back an array of string values. But pretty much everything else that Unconed's code does exactly what I want, and while I can copy if if that's easiest, I don't want or need to change what he did.
How would your widget degrade if there is no JavaScript enabled? It would still need to look up the code for the country name on the server side anyway (or would require the user to provide the country code if that is in a form item). Either way, the Drupal default approach puts less strain on the server, while supporting a discrete JavaScript approach as far as I see. Gabor
The country example was only an example, since it's easy to explain. My actual use cases are much larger: * Looking up a contact from a voter list... you want the user to type from the name, but get back a voter/contact id string or number. * Type the name of a political district (say, a Canadian parliamentary riding), but get back its ID number. In these cases, I'd probably have alternate UIs to work with non-JavaScript aware clients (say, a search page), since the AJAX and non-AJAX versions of the UI would need to be pretty different. Rob Gabor Hojtsy wrote:
On Wed, 17 Jan 2007, Rob Thorne wrote:
I really don't need to change behavior very much; I just need to send back an array of array(key, value), where the standard widget sends back an array of string values. But pretty much everything else that Unconed's code does exactly what I want, and while I can copy if if that's easiest, I don't want or need to change what he did.
How would your widget degrade if there is no JavaScript enabled? It would still need to look up the code for the country name on the server side anyway (or would require the user to provide the country code if that is in a form item). Either way, the Drupal default approach puts less strain on the server, while supporting a discrete JavaScript approach as far as I see.
Gabor
On Thu, 2007-01-18 at 11:19 -0800, Rob Thorne wrote:
The country example was only an example, since it's easy to explain. My actual use cases are much larger:
* Looking up a contact from a voter list... you want the user to type from the name, but get back a voter/contact id string or number. * Type the name of a political district (say, a Canadian parliamentary riding), but get back its ID number.
In these cases, I'd probably have alternate UIs to work with non-JavaScript aware clients (say, a search page), since the AJAX and non-AJAX versions of the UI would need to be pretty different.
Rob
I would look at the nodereference autoselect widget. It takes a node title for input and converts it into an nid before stuffing it in the db.
Darrel O'Pry wrote:
I would look at the nodereference autoselect widget. It takes a node title for input and converts it into an nid before stuffing it in the db.
OK, it looks like great minds think alike. Or at least, I think like the CCK team. I came up with an implementation of this for CiviNode about a year ago, where I did look-up by contact name from CiviCRM. It's a very similar problem to what nodereference.module needs to do in CCK. Very similar problem, and very similar hack: you append " [NID]" to the end of your node titles, and to get the $nid back when the form comes back, you just parse off the " [NID]" string, and save away the nid. This is almost exactly what I did for the first release of CiviNode. Except I used " (CID)". :-) I'm guessing that the CCK folks did it for the same reason I did: it didn't require mucking with the JavaScript, and it does work. I was thinking there was a better way to do this, but the fact the CCK did the same thing I did before suggests that some hacks are just better than others. Thanks, Rob
Rob Thorne a ecrit le 18/01/2007 22:41:
I'm guessing that the CCK folks did it for the same reason I did: it didn't require mucking with the JavaScript, and it does work.
I was thinking there was a better way to do this, but the fact the CCK did the same thing I did before suggests that some hacks are just better than others.
As a matter of fact, I tried to come up with a better solution than the [nid] thing (my motto was "nid should stay out of the user's eyes") see http://drupal.org/node/62498#comment-114723 for historical records. I even submitted a generic attempt for Core over there : http://drupal.org/node/80565 (on double checking, it seems you commented there some time ago - or is that another Rob ?) This did not get much success - I'm not sure it was a good idea to begin with, or maybe it was but I did it wrong. So i got back to the [nid] hack. Still not really happy with it, though. Yves
Nope, different Rob. I'm Torenware on drupal.org; RobRoy is, well, whoever RobRoy is. But I agree with RobRoy's comment on your thread: there really ought to be a solution in Core for this. --Other Rob Yves CHEDEMOIS wrote:
I even submitted a generic attempt for Core over there : http://drupal.org/node/80565 (on double checking, it seems you commented there some time ago - or is that another Rob ?) This did not get much success - I'm not sure it was a good idea to begin with, or maybe it was but I did it wrong.
So i got back to the [nid] hack. Still not really happy with it, though.
Yves
RobRoy is, well, whoever RobRoy is. Hey, look. I'm famous! :-P
Rob Roy Barreca Founder and COO Electronic Insight Corporation http://www.electronicinsight.com rob@electronicinsight.com Rob Thorne wrote:
Nope, different Rob. I'm Torenware on drupal.org; RobRoy is, well, whoever RobRoy is.
But I agree with RobRoy's comment on your thread: there really ought to be a solution in Core for this.
--Other Rob
Yves CHEDEMOIS wrote:
I even submitted a generic attempt for Core over there : http://drupal.org/node/80565 (on double checking, it seems you commented there some time ago - or is that another Rob ?) This did not get much success - I'm not sure it was a good idea to begin with, or maybe it was but I did it wrong.
So i got back to the [nid] hack. Still not really happy with it, though.
Yves
participants (5)
-
Darrel O'Pry -
Gabor Hojtsy -
Rob Barreca -
Rob Thorne -
Yves CHEDEMOIS