Jquery autocompleteselect not firing with 1.1.9

There appears to be a problem with using jquery UI autocomplete (via CJuiAutoComplete) in Yii 1.1.9. The autocompleteselect Javascript event does not seem to fire when an item from the selection list is clicked. The problem appears to lie with jquery / jquery ui because substituting Yii 1.1.8 while keeping jquery 1.7 still exhibits the problem. However, falling back to jquery 1.6 and Yii 1.1.8 eliminates the problem. I have not yet tried Yii 1.1.9 with the older jquery because Yii now utilizes the ‘on’ function which is not present in jquery 1.6. It would be nice to determine whether there is something Yii is newly doing that is provoking a jquery problem or whether this is an out and out jquery problem. I have not yet reduced this to a small test case but plan on doing so shortly.

Can you post just your CJuiAutocomplete code…

Attached are 4 files that constitute a complete minimal Yii application that exhibits the problem. With Yii 1.1.8 and Jquery 1.6 all is well. With Yii 1.1.9 and Jquery 1.7 the problem is exhibited.

When the autocomplete suggestion is clicked in 1.1.9 the “value” ends up in the text box, while in 1.1.8, the “label” ends up in the text box. This is due to the autocompleteselect event not firing in 1.1.9. The default action of the audocomplete widget is to put the “value” in the associated text box. The application’s Javascript code bound to the autocompleteselect event overrides this action and puts the “label” in the text box. So if you type “Alp” and then select the suggestion, the letter ‘A’ ends up in the text box using 1.1.9 but “Alpha” ends up in the text box using 1.1.8.

The configuration is:

Server: RHEL5 Linux, Apache 2.2.3, PHP 5.3

Client: Windows XP SP3 using either Chrome or IE8.

Using the Chrome debugger, the Javascript function autocompleteselect() contained in layout.php is never reached using 1.1.9. The breakpoint is reached using 1.1.8.

Some further debugging has isolated the problem and provided a workaround. It appears that the improved? event handling in Jquery 1.7 is the culprit. The delgate no longer catches the autocompleteselect event in 1.7 and this is related to the fact that the target is now the invisible anchor element generated by the autocomplete widget, not the text box input element. This is evident if the "delegate" is changed to a "bind". The bind does catch the event but event.target points at the anchor element. This results in the code, as written, still not working since it attempts to set the value of an anchor element. However, the event object also provides a currentTarget DOM element which is in fact the text box input element. So a small code change makes things work.

$('body').delegate('input', 'autocompleteselect', function(event, ui) { return autocompleteselect(event, ui); }); (Old code doesnt catch event)





$('input').bind('autocompleteselect', function(event, ui) { return autocompleteselect(event, ui); });    (New code - catches event)








function autocompleteselect(event, ui) {


	event.currentTarget.value = ui.item.label;    (Use "event.currentTarget" to get INPUT element, not "event.target" which is an A element)


	return false;


}

Someone with a much more detailed knowledge of the DOM and event handling can probably explain the difference between event.target and event.currentTarget and whether delegate no longer catching the event is a bug or a feature.

Is this worthy of reporting to the Jquery folks? It certainly is mysterious and hints of further lurking incompatibilities. If so, how should it be reported?

As you found out this is related to jquery and/or jquery UI… to report it, first step would be to create a ticket for the autocomplete plugin - http://bugs.jqueryui…?P=autocomplete

Anyway

To solve this in another way you can use this code:




$this->widget('zii.widgets.jui.CJuiAutoComplete',array(

	'sourceUrl' => array('/site/ajaxcallback'),

	'name' => 'test',

	'options' => array(

		'minLength' => '2',

		'focus'=> 'js:function(event,ui) {

			$("#autoc").val(ui.item.label);

			return false;

		}',

		'select'=>'js:function(event,ui) {

			$("#autoc").val(ui.item.label);

			return false;

		}',

	),

	'htmlOptions' => array(

		'id'=>'autoc'

	)

));



With this code you can remove completely the binding/delegating and the initialize function.

The "focus" event is fired while scrolling with the keyboard (up/down) on the autocomplete list, and the "select" event is fired when you click or ENTER on the desired item… they both set the label value into the input field.

Thanks for the more elegant inline solution. I like this method of grouping the Javascript snippets with the rest of the code they work with rather than in a separate file. I have more of this sort of stuff in my actual application and will change to using this method.

I will report this issue to the JQuery folks. I am curious whether you think that this is an expected behavior for the new version of JQuery. It smells like a bug to me.

Can’t say if its a bug or not as the new on() method was introduced to clean all the mess with bind()/live()/delegate()…

but if this worked before and now it’s not working than it’s cetainly a BC break… so it’s good to report it so the jQuery UI devs can check on this.

By the way, I briefly tried replacing the "delegate" with "on" and the event still fails to be caught. So the incompatibility relates less to the method of catching than to the event target which seems to have changed from the INPUT element to the A element under the new JQuery core.

Well… internali the new jquery source code uses on() always… so delegate is just an alias for the new on() method :D

Yes the new on() method did clarify the things about what element is delegated and what elements are the one that fired the event, for more info check the documentation of the new on() method - http://api.jquery.com/on/

By your description if that worked before I guess that the jQuery UI team will need to adjust the autocomplete code to the new on method functionality

Well I did indeed spend the time creating an extremely reduced test case using the jsfiddle tool recommended by the JQuery folks. Unfortunately, the ticket was flippantly closed because the test case used JQuery UI 1.8.9 instead of the latest 1.8.17. The closer stated that evidently UI 1.8.9, being of the advanced age of almost 1 year, was not compatibie with JQuery 1.7.1. I used this version in constructing the reduced test case because that appears to be the latest version easily available under their recommended jsfiddle tool. I realize that the version of UI that is bundled with Yii 1.1.9 is 1.8.16, released much more recently, and that is the version where I originally encountered the problem.

Late breaking news…The Jquery folks say that UI 1.8.17, and only, 1.8.17 is compatible with core 1.7.1. So you probably want to fix Yii to distribute this version, not 1.8.16 as is currently done. I have not tested to see if the behavior is improved.

See…http://bugs.jquery.com/ticket/11147

You opened a ticket with jQuery instead with jQuery UI like I suggested you… I even posted you the link to the autocomplete issue list where to open the ticket… the guys from jQuery does not have anything to do with the jQuery UI autocomplete functionality… thats why you get answers like the one you got.

Anyway… did you test with the new jQuery UI to check if this has been fixed ?

Because in the changelog there are only 2 fixes for autocomplete and they to not reasemble your problem - http://jqueryui.com/docs/Changelog/1.8.17

NOTE: jQuery UI 1.9.17 was released yesterday - http://blog.jqueryui…egory/releases/ - so we could not include it before ;)

I just tested UI 1.8.17 and it in fact works. Here is the test code - it fails by not reaching the alert with 1.8.16 and works with 1.8.17. I must say that I don’t agree with the backwards compatibility philosphy that the Jquery core folks have since I would tend to consider stuff like this an error in the core rather than requiring a change in UI but I guess their goal is to improve the design at the expense of compatibility.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>Autocomplete JQuery 1.7.1 problem</title>

<script src="/js/jquery-1.7.1.js" type="text/javascript"></script>

<script src="/js/jquery_ui_1.8.17_custom_min.js" type="text/javascript"></script>

</head>

<body>

<input type="text" id="test" />

<script type="text/javascript">

/<![CDATA[/

jQuery(function($) {

$(’#test’).autocomplete({‘minLength’:‘2’,‘source’: [‘abcd’,‘abxy’,‘abxz’]});

$(‘body’).delegate(‘input’, ‘autocompleteselect’, function() { alert(‘got here’) });

})

/]]>/

</script>

</body>

</html>

I just upgraded jQuery UI to 1.8.17 - http://code.google.com/p/yii/source/detail?r=3537

Would have done before but had to wait for them to fix one file that we use in Yii - http://bugs.jqueryui.com/ticket/8004