I was struggling trying to get the autocomplete feature to work with a list of keys and values where key is a unique_id and value is the textual name. I found a couple of solutions ([#354625] and #322383: Autocomplete nid/vid extraction. i.e. CCK Nodereference) but they were either too complicated or too intrusive. I felt that if I could just hook onto the act of selecting a value, I would be able to solve my problem.

So, I wrote this patch that uses jQuery to trigger a custom event "autocomplete_select" whenever an item is selected. With this event in place I can now do something like this:

Drupal.behaviors.autocompleteSupervisor = function(context) {
	$("input#edit-autocompleteField", context).bind('autocomplete_select', function(event) {
		var values = $(this).val().split('|');  // my key was a pipe-delimited string (name|id)
		$(this).val(values[0]);// set the value of the field to just the name part
		if (values[1]) {  // if an id was found...
			$("input#edit-recommendedSupervisors-0", context).val(values[1]);  // set the val of some other field to the id
		}
	});
};
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

chuckdeal97’s picture

I was trying to reference this page: http://drupal.org/node/354625 which is a one-off solution to #322383: Autocomplete nid/vid extraction. i.e. CCK Nodereference. In both cases, my solution should work and be simpler and less intrusive.

andreiashu’s picture

Version: 6.4 » 7.x-dev

Not sure if this is already in 7 but it would be useful.

malks’s picture

Hi,

I'm trying to get this working, and think I've loaded in the javascript (used hook_nodeapi()) but can't quite get the desired result :/ Javascript not my strongest point, have tried debugging in firebug etc. and while it looks like the trigger in the patch is getting fired I don't know how to work out if my code in the behaviours is being run...

Any help much appreciated.
Anthony.

EDIT: just with hook_nodeapi() what value of $op should I be loading in the code? I thought "prepare" might be best but I can't seem to get a prepare event so have tried using "view" and "alter" but still not much luck.

chuckdeal97’s picture

I don't have access to my code repo at the moment, so I don't have an answer about how to use hook_nodeapi. But as for your other problem of not knowing if your js behavior is firing...have you tried old school debugging and put in some alerts? It's not scientific, but sometimes it helps. I usually place an alert at points just before and just after some choice is made (an if stmt, function call, etc) so that I can attempt to follow the workflow via the alerts that pop up.

If you do a view source on the generated page, do you see a reference to the new javascript?

malks’s picture

Hey,

Thanks for the response. I did put some alerts in (old school lol) one before the anonymous javascript function and one inside the function. The first did appear but the second didn't. Where should I see the javascript code if it's attaching correctly?

I'm not sure if I've got the right name of the element to attach to as I notice in view source that there is an input with the id (just a quick one, it shouldn't be the name should it?) "edit-project-test" and a hidden one which does the autocomplete with an id "edit-project-test-autocomplete" and I'm using the first (but have tried the second) with no luck.

I definitely feel that I'm not loading the javascript in the right place so will try hook_form_alter() I think or maybe some theme statements.

Anthony.

malks’s picture

Using the hook_form_alter() did the trick. One last question... I followed your example and it works but in the select list I'm still getting the "full" value, i.e. it shows "Project|13" even though it is correctly storing Project in the autocomplete field and 13 in my id field. Anyway around this?

Thanks,
Anthony.

chuckdeal97’s picture

Sorry about the delay. Here is the js function I use

	$("input#edit-displayname", context).bind('autocomplete_select', function(event) {
		var values = $(this).val().split('|');
		$(this).val(values[0]);
		if (values[1]) {
			$("input#edit-name", context).val(values[1]);
		}
	});

My values are displaystring|value pairs, so I split the string on the '|' and put the displaystring back into the autoselect field and I have a hiddenfield paired with the autocomplete that receives the value. Upon submit, both the displaystring and value will be available to you.

malks’s picture

Hey again,

That's what I've done (read: blindly copied) already and it works, that is I get the display string in the autoselect form and the value in the hidden field correctly... BUT in the dropdown that has the values computed for the autocomplete it still has the unparsed value, that is with the '|' in it. Is there anyway to get rid of that? Not a biggie, no one has actually complained about it, just chasing it up for completeness :)

Thanks again,
Anthony.

esteewhy’s picture

@chuckdeal97

Charles, your solutions works like a charm! What can we do to push this into the core ?

The only minor improvement i'd ask is this:

-  $(this.input).trigger('autocomplete_select');
+  $(this.input).trigger('autocomplete_select', [node]);

With this in place, i think you won't need pipe-trickery above:

.bind('autocomplete_select', function(event, node) {
  $('input').val($(node).text());//caption
  $(':hidden').val(node.autocompleteValue);//key
})
esteewhy’s picture

@andreiashu

Andrei, can you please suggest, if the discussed feature has a chance to make it's way into 6.x ?

sotiris’s picture

submit

Alan D.’s picture

+2 For D7 and backport to D6

Trying to combining autocomplete & AHAH is trivial using the new listener, but near impossible with standard listeners. (the keystrokes were being really painful)

The following is a D6 example using the original patch above:

The autocomplete 'autocomplete_select' event triggers what would have been a 'change' event. So when the autocomplete is really finished, the AHAH request is triggered.

<?php
  $element['nid'] = array(
    '#type' => 'textfield',
    '#description' => t('Contact'),
    '#default_value' => $node ? $node->title .' [nid:'. $node->nid .']'  : '',
    '#autocomplete_path' => 'htsa-contact/autocomplete',
    '#size' => 30,
    '#ahah' => array(
      'path' => 'common/ahah/' . implode('][', $element['#array_parents']),
      'wrapper' => 'contact-element-'. $element['#id'],
      'method' => 'replace',
      'effect' => 'fade',
      'event' => 'autocomplete_select',
    ),
  );
?>
bcn’s picture

Component: forms system » javascript
Status: Active » Needs review
FileSize
516 bytes

As per #9

bcn’s picture

Minus the whitespace in the patch above....

bcn’s picture

I've been testing this patch out for a couple weeks on D7 and it seems to work fine.. Has anyone else tested? Anyone else ready to RTBC this?

Also, attached to this post is a drupal 6 version of the patch (zipped so it doesn't get tested), which also seems to work fine for me..

bcn’s picture

Status: Needs review » Needs work

Patch from #14 (and #16) is missing:

-    this.input.value = this.selected.autocompleteValue;
+   this.select(this.selected);
   }

Will reroll soon...

bcn’s picture

Here's an updated patch for Drupal 7...

Leaving this at 'needs work' because it seems with this patch applied, the "autocomplete_select" event is getting triggered twice, when the mouse is used to select an option from the list of autocomplete result choices. If the selection is made with the enter key, the event only fires once..

bcn’s picture

Status: Needs work » Needs review
FileSize
533 bytes
683 bytes

Maybe this will work... I moved the triggering function around a bit, and it seems to fix the issue of double firing for mousedown (click) events.

the .zip attachment is for Drupal 6...

mdeltito’s picture

@noahb

I just added this functionality myself in the same manner, and I rolled my own patch that matches yours exactly. Thus, I can confirm that this patch is tested working for Drupal 6.

bcn’s picture

Issue tags: +autocomplete

tagging...

clashar’s picture

Version: 7.x-dev » 6.16

I tried patches for Drupal 6 from #15 and #18, but still no effect. Maybe I am confused as I imported only 2 lines of code.

Or maybe I am confused with functionality, should I see both Autocomplete and Select options simultaneously together?

bcn’s picture

Version: 6.16 » 8.x-dev

At this point features would likely have to be delayed to 8.x

chris.jichen’s picture

autocomplete.js_.patch queued for re-testing.

Alan D.’s picture

Version: 8.x-dev » 7.x-dev
Status: Needs review » Reviewed & tested by the community

This is not an API change, just a minor addition, so D7 should be alright. While the core Autocomplete sucks, hopefully some of these patches get in....

Ajenjo’s picture

autocomplete.js_.patch queued for re-testing.

webchick’s picture

Version: 7.x-dev » 8.x-dev

Sounds like a nice feature, but we don't do features at this point, and it sounds like there's a workaround, albeit sub-optimal.

Since this is fairly non-invasive though, it might be something we could conceivably backport from D8 in a point release of D7.

jerdavis’s picture

I came across this tonight when trying to add auto submit to DamZ's d7 port of editablefields. I'm wondering if we could just add $(this.input).trigger('change'); and use a standard event? What do we gain by declaring a custom event?

At any rate, I'd love to see this included in 8 and back ported to 7. It seems more or less required if you want to try and make any autocomplete fields do a ahah form submission when selecting an existing value.

catch’s picture

Issue tags: +Needs backport to D7

Adding needs backport tag, looks like that might need some discussion but also doesn't look out of the question.

xjm’s picture

#18: ac_select_event-d7.patch queued for re-testing.

Status: Reviewed & tested by the community » Needs work
Issue tags: +autocomplete, +Needs backport to D7

The last submitted patch, ac_select_event-d7.patch, failed testing.

xjm’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
566 bytes

Rerolled for current D8; assuming this is still RTBC based on #24 and webchick's review in #26.

sun’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/misc/autocomplete.js
@@ -166,6 +166,7 @@ Drupal.jsAC.prototype.hidePopup = function (keycode) {
+    $(this.input).trigger('autocomplete_select', [this.selected]);

1) Underscores are rarely used in JavaScript, so I think the event name should be 'autocompleteSelect'.

2) Why don't we pass the entire this object to event listeners?

20 days to next Drupal core point release.

webadpro’s picture

sub

webadpro’s picture

Status: Needs work » Needs review

oups

xjm’s picture

Status: Needs review » Needs work

I think it's still NW for #32.

webadpro’s picture

So what do I need to change in D7 to get this to work?

Do I only need to use the path at #31 to get this to work?

webadpro’s picture

@checkdeal97 - #7 ... Whats does your form element look like?

jerdavis’s picture

@webadpro you can either patch core, or you can also "fix" it for your own module(s) by overriding the core JS, see here for an example:

http://drupalcode.org/sandbox/damz/1130436.git/blob/refs/heads/7.x:/edit...

webadpro’s picture

Thanks, but my question was what does his form element looks like? Do I need to have 2 elements to get this working?

jaxxed’s picture

I would also like to support this change.

The first line change is a no-brainer. Why the key-based update is directly updating the input element, when there is already an abstraction is confusing.
The addition of the select hook is also great, but perhaps we should just trigger the 'change' event?

Everett Zufelt’s picture

RobLoach’s picture

Everett is correct... If we adopt jQuery UI, we will get the select event, along with much more.

Alan D.’s picture

I guess that #675446: Use jQuery UI Autocomplete will not be back-ported? As such, should this issue be assigned back to D7?

mkalkbrenner’s picture

Just want to mention that #18 works fine for D6. Thanks for that patch.

paulmarbach’s picture

Status: Needs work » Needs review
FileSize
1.06 KB

This patch fixes the mouse event error in #17 and some of these other fixes.

Status: Needs review » Needs work

The last submitted patch, autocomplete.js_.d7_autocompleteSelect_event.patch, failed testing.

paulmarbach’s picture

Version: 8.x-dev » 7.x-dev
FileSize
1.05 KB

reattaching reformatted patch

xjm’s picture

Version: 7.x-dev » 8.x-dev

Thanks @paulmarbach. Let's keep the version on 8.x; I don't see that this has been committed to D8 yet. We should also create a patch for Drupal 8 first. Once the fix is committed to D8, it is probably backportable to D7 (and will probably be exactly the same patch except that the files are in different directories). Thanks!

Alan D.’s picture

It looks like the other thread has stalled.

As far as I know, jQuery UI autocomplete will not be accessible enough for Core until at least 1.9.

It would be great to push this forward so we can (maybe) get this in so that we do not have to override the core JScript for a few years :?

OptimusPrime23’s picture

Status: Needs work » Needs review
Issue tags: -autocomplete, -Needs backport to D7

#14: autocomplete.triggerEvent.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +autocomplete, +Needs backport to D7

The last submitted patch, autocompleteSelect.js_.patch, failed testing.

nod_’s picture

Version: 8.x-dev » 7.x-dev

7 only, on 8.x this will be provided by jQuery UI.

skruf’s picture

Status: Needs work » Needs review

autocomplete.js_.patch queued for re-testing.

skruf’s picture

Re-rolled patch for 7.x

warmth’s picture

Good job! Have you seen this: http://drupal.org/project/autocomplete_deluxe

undersound3’s picture

#54: ac_select_event-365241-54.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +autocomplete, +Needs backport to D7

The last submitted patch, ac_select_event-365241-54.patch, failed testing.

a.milkovsky’s picture

Might this can help somebody.
I use autocomplete change event with some fix - $(this).blur() :

$('.form-autocomplete').change(function(){
      $(this).blur(); // fix for select on click and enter press
      // do your code here
      my_super_puper_function(this);
});
mkalkbrenner’s picture

Status: Needs work » Needs review

#54: ac_select_event-365241-54.patch queued for re-testing.

juampynr’s picture

Patch at #54 worked perfectly fine.

gaurav-varshney’s picture

Title: Add select event to autocomplete feature » #54 Not working In IE8

I have also applied the #54 Patch it works fine every where except in IE8.
is there any way so it works in IE8.

nod_’s picture

Title: #54 Not working In IE8 » Add select event to autocomplete feature
drupov’s picture

#54 went ok for me in FF, even with IE8 running through Wine on Ubuntu. I haven't tested it yet in real Windown IE8 environment.

mgifford’s picture

Ajithlal’s picture

I am getting error
ReferenceError: context is not defined

I applied #54 patch and my javascript below

$("input#edit-address", context).bind('autocomplete_select', function(event) {
var values = $(this).val();
alert(values);
});

sgabe’s picture

Issue summary: View changes

Patch in #54 applies fine and works fine for Drupal 7.

John Pitcairn’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs backport to D7

@Ajithlal: the event is 'autocompleteSelect'.

Patch at #54 applies to 7.34.

Removing the backport tag, D8 uses jQuery UI so there is nothing to backport.

Let's mark this tested and approved, shall we? It doesn't break any existing functionality. IE8 support can be a follow up issue?

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 54: ac_select_event-365241-54.patch, failed testing.

Status: Needs work » Needs review
David_Rothstein’s picture

Status: Needs review » Reviewed & tested by the community

Didn't actually review this, but that's surely a bogus test failure so moving back to RTBC...

I'm not clear on the IE8 situation - is it just that the new functionality doesn't work on IE8 (probably OK) or that it breaks things that used to work on IE8 (not OK) or is fine on IE8 after all?

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 54: ac_select_event-365241-54.patch, failed testing.

Status: Needs work » Needs review
David_Rothstein’s picture

Status: Needs review » Reviewed & tested by the community

Another bogus test failure, so back to RTBC for now.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 54: ac_select_event-365241-54.patch, failed testing.

Status: Needs work » Needs review
mgifford’s picture

Hopefully we can set this back to RTBC.

othermachines’s picture

Patch in #54 works for me (7.34).

My test snippet:

(function ($) {
  Drupal.behaviors.autocompleteSupervisor = {
    attach: function (context) {
      $("input#edit-autocompleteField", context).bind('autocompleteSelect', function(event, node) {
        console.log($(this).val()); // user-entered string
        console.log($(node).data('autocompleteValue')); // key of selected item
        console.log($(node).text()); // label of selected item
      });
    }
  };
})(jQuery);

Thanks -

* Edit: passed in node obj and demo'd the available data. Took me a bit of fussing to figure it out so maybe it'll help someone.

mgifford’s picture

Status: Needs review » Reviewed & tested by the community

Ok, back to RTBC.

David_Rothstein’s picture

Status: Reviewed & tested by the community » Fixed
-      .mousedown(function () { ac.select(this); })
+      .mousedown(function () { ac.hidePopup(this); })

This seems to replace the double-call to select mentioned earlier in this issue with a double-call to hidePopup... but I guess that's harmless.

It's been many many months and no one else has confirmed any problems with IE8, plus #63 says it works there. So let's go with it.

Committed to 7.x - thanks!

  • David_Rothstein committed f56b706 on 7.x
    Issue #365241 by bcn, paulmarbach, xjm, chuckdeal97, skruf: Add select...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

taggartj’s picture

A quick note on Drupal 8

var autocomplete = Drupal.autocomplete;
var myAutoBox = $("#edit-myform-search").autocomplete({
      select: function( event, ui ) {
        //console.log( event);
        //console.log( ui );
      }
     });