Window.google.ac has no properties : The low-down
If you are using Google's ac.js for auto-complete and you are seeing Window.google.ac has no properties or similar, this is what I have found during the course of fixing iSuggest.
Ac.js submits an Ajax request which returns a string describing a Javascript function call like this...
The script then "evals" this string resulting in a call to window.google.ac.sendRPCDone(). Either the Ajax return convention or the ac.js file must have changed because the iGoogle page DOM 's window object currently does not have a .google member (and consequently .google.ac).
Ac.js does, however, have a sendRPCDone() function so, to get this to work, I took a copy of the file and modified it to hook the sendRPCDone() function into the DOM where the eval-ed function expects it to be.
You can get my modified copy of ac.js (renamed shac.js) here.
Ac.js submits an Ajax request which returns a string describing a Javascript function call like this...
window.google.ac.sendRPCDone(frameElement, "k;", new Array("kmart", "k n", "k swiss", "k g", "k n filters", "k n air filters", "k lite codec", "k lite", "k lite codec pack", "k rock"), new Array("4,310,000 results", "4,030,000 results", "20,300,000 results", "297,000 results", "1,650,000 results", "1,270,000 results", "2,360,000 results", "5,480,000 results", "2,130,000 results", "103,000,000 results"), new Array(""));
The script then "evals" this string resulting in a call to window.google.ac.sendRPCDone(). Either the Ajax return convention or the ac.js file must have changed because the iGoogle page DOM 's window object currently does not have a .google member (and consequently .google.ac).
Ac.js does, however, have a sendRPCDone() function so, to get this to work, I took a copy of the file and modified it to hook the sendRPCDone() function into the DOM where the eval-ed function expects it to be.
You can get my modified copy of ac.js (renamed shac.js) here.
Comments
window.google = new Object();
window.google.ac = new Object();
window.google.ac.Suggest_apply = sendRPCDone;
However, they've also changed the array structure so that keywords and number of results now comes in the same array in consequent elements. So changed will have to be made to the iterations in sendRCPDone.
window.google.ac.Suggest_apply(frameElement, "k;", new Array(2, "kmart", "4,280,000 results", "k n", "3,850,000 results", "k swiss", "17,400,000 results", "k n filters", "1,860,000 results", "k lite", "10,900,000 results", "k lite codec", "3,690,000 results", "k n air filters", "1,580,000 results", "k g", "310,000 results", "k lite codec pack", "3,090,000 results", "klove", "4,060,000 results"), new Array(""));
I copied their new ac.js and added the new Object hooks again. That way the array handling is updated too.
Thanks again for your help Fred.
I've been trying to run more than one suggest dropdowns on the same page. One feeds of Google, the other one feeds of my own Suggest_apply request. The problem is that I'm struggling to encapsulate the whole script without the two scripts running in to each other.
Has anyone done this?
My thinking is that you put the whole script in a construct Suggest() {ac.js}.
var first = new Suggest();
Where Suggest is the whole ac.js script encapsulated.
You would either have to ensure that all function and global variable names are unique or, as you say, wrap them in objects.
var googleSuggest.sendRPCDone = function(...) { ... }
var fredsSuggest.sendRPCDone = function(...) { ... }
Note that...
function sendRPCDone() { };
var myObject.sendRPCDone = sendRPCDone;
...might not be enough, as it is simply referencing a single instance of the function. I'm not sure about this, though.