TAG | jquery
Here is a link to an awesome jquery manual that is so easy to use. Thanks Remy and Yehuda!
I have been tracking down a nasty bug in my code over the last 6 hours. Here is the scenario. I have a section of nodes on my webpage that has fields and those fields handle events from the user. For example, I have a name field that when typed into there is an autocomplete box that pops up. The user has the ability to duplicate the entire section of nodes so that they can create more items. I am using my own node copy code which consists of taking the innerHTML from the first node and parsing out some things, incrementing ids and then plugging it back into the system by appending it after the original node. I am using jQuery for the event handling, but not for the node copy, since the node copy has some custom stuff that I have to do.
The bug occurs only on IE when I copy the nodes and then try to fire an event by typing in the field. What happens is that the event handler for the SUBSEQUENT input boxes can not be fired until I modify the field in the ORIGINAL node block. Then I get BOTH events!!! Nasty huh?
The solution actually lies in jQuery’s clone function. Here you see that when they do a clone they will eliminate the property that is embedded in the html called jQuery12341234=”2″ (those number are some internal jQuery identifier, probably for the event handler).
To fix the bug all I had to do was remove that attribute and definition and viola it works!
Here is jQuery’s replace from their clone function.
html.replace(/ jQuery\d+="(?:\d+|null)"/g, "")
My approach (before I found that jQuery was doing it also was this.
html.replace(/jQuery\d+=["']\d+["']/g, "")
Since jQuery programmers know more than me (i.e. when null might be in that field) I just ditched mine and used theirs.
Have a great day!
Eric
I am using jquery with the Devbridge autocomplete plugin. It is an awesome tool. Unfortunately we had a bug reported that on IE6 the autocomplete box does not correctly cover up the other controls on the page. There are select boxes below the field with the drop down and when everything else is covered up, these select boxes stick out like a sore thumb.
Normally you would use the bgiframe plugin for jquery to address this problem, but in this case we don’t have a reference to the dropdown list once it is filled in from the ajax call. So, my solution was to add a simple callback to the autocomplete plugin that is fired off after the list is populated and made visible. That gives me the option that simply takes the list container and calls bgiframe on it. And viola! My dropdown list covers up all the controls underneath, even the select lists.
Here is a patch if you would like to patch the autocomplete plugin. Note, it also contains a fix from my last post about using multiple fields as input (the Devbridge autocomplete part is at the bottom of the post).
--- jquery.autocomplete.js 2009-09-27 23:15:14.000000000 -0600
+++ ../jquery.autocomplete.js 2010-01-29 15:29:14.000000000 -0700
@@ -230,6 +230,9 @@
},^M
^M
getSuggestions: function(q) {^M
+ if (this.options.noCaching) {^M
+ this.clearCache();^M
+ }^M
var cr, me;^M
cr = this.isLocal ? this.getSuggestionsLocal(q) : this.cachedResponse[q];^M
if (cr && $.isArray(cr.suggestions)) {^M
@@ -280,6 +283,7 @@
}^M
this.enabled = true;^M
this.container.show();^M
+ if ($.isFunction(me.options.onListShow)) { me.options.onListShow(this.container); }^M
},^M
^M
processResponse: function(text) {^M
Download the actual patch right here! jquery.autocomplete.js.patch
Remember, to patch your file, simply cd to where your jquery.autocomplete.js file resides (and copy in this patch to that directory to a file called jquery.autocomplete.js.patch) and run this command
patch jquery.autocomplete.js < jquery.autocomplete.js.patch
Now, once you have that file patched, you can do this sort of thing with your autocomplete options.
$("input[name*=some_name], input[name*=some_other_name]").each(function(i) {
$(this).autocomplete(
{
serviceUrl:baseURL + '/lib/dostuffremotely',
minChars:3,
width:500,
maxHeight:400,
zIndex: 9876,
deferRequestBy: 0, //milliseconds
params: {
'prefix':'xyz',
'column':'abc'
},
onListShow: function(container) { container.bgiframe(); }, // LOOK HERE, THIS IS NEW!!!
onSelect: function(value, data){ // "this" is NOT defined here
// handle onselect
}
}
);
Happy jquerying!
Eric

