Discussion:
[OpenLayers-Dev] Openlayers and scriptaculous autoComplete
Ehud Shabtai
2010-09-01 22:23:25 UTC
Permalink
Hi,

I'm trying to use openlayers along with a form which uses the
Ajax.autoComplete of scriptaculus.
I can't make it work properly, as the autoComplete always shows me the first
batch of results regardless of the input.

It seems that Openlayers intercepts the ajax response from the server in its
Function.prototype.bind definition which defines function(moreargs).
function(moreargs) is called for every response from the server and it
appends the response into the args array. So my args array now contains all
of the autoComplete responses (which are not valid anymore as only the last
response contains the correct set). When it passes this array further down
to scriptaculus, scriptaculus only uses the first response as it does not
expect an array. So I always get the same batch of completions.

Can I avoid Openlayers intercepting the autoComplete responses?

Thanks,
--
Ehud Shabtai
http://www.freemap.co.il/map/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/openlayers-dev/attachments/20070513/5aebc64a/attachment.html
Christopher Schmidt
2010-09-01 22:23:25 UTC
Permalink
Post by Ehud Shabtai
Hi,
I'm trying to use openlayers along with a form which uses the
Ajax.autoComplete of scriptaculus.
I can't make it work properly, as the autoComplete always shows me the first
batch of results regardless of the input.
It seems that Openlayers intercepts the ajax response from the server in its
Function.prototype.bind definition which defines function(moreargs).
function(moreargs) is called for every response from the server and it
appends the response into the args array. So my args array now contains all
of the autoComplete responses (which are not valid anymore as only the last
response contains the correct set). When it passes this array further down
to scriptaculus, scriptaculus only uses the first response as it does not
expect an array. So I always get the same batch of completions.
Can I avoid Openlayers intercepting the autoComplete responses?
I don't think so. Does this mean that our definition of Function.bind is
different from that in Prototype somehow? Looking at the code, it seems
like the end result of the current (Prototype 1.5.1) definition and our
current definition in OpenLayers should end up being the same...

I can't figure out why this is happening (though I know it is, because I
ran into the same thing recently). Do you feel like you understand it
and see what we're doing wrong?

Regards,
--
Christopher Schmidt
MetaCarta
Ehud Shabtai
2010-09-01 22:23:25 UTC
Permalink
Post by Christopher Schmidt
I don't think so. Does this mean that our definition of Function.bind is
different from that in Prototype somehow? Looking at the code, it seems
like the end result of the current (Prototype 1.5.1) definition and our
current definition in OpenLayers should end up being the same...
I'm no javascript expert but I think that the implementation is a bit
different and that seems to be the problem.

Here's Prototype's implementation:

Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
}

and here's the Openlayers one:

Function.prototype.bind = function() {
var __method = this, args = [], object = arguments[0];
for (var i = 1; i < arguments.length; i++)
args.push(arguments[i]);
return function(moreargs) {
for (var i = 0; i < arguments.length; i++)
args.push(arguments[i]);
return __method.apply(object, args);
}
};


I believe that the problem is in the inner function. Prototype uses
args.concat(arguments), which I think (?) only creates a temporary
array for calling the function. args is not changed.
OpenLayers uses args.push which changes args and adds new elements in it.

I tried to remove the inner loop in OpenLayers and used
args.concat($A(arguments)) instead. This fixes the autoComplete
problem. I assume that the correct fix is to create another local
array and put in it both the args elements and the additional
arguments elements. But I wasn't sure if the Openlayers implementation
intentionally differs from prototype?
--
Ehud Shabtai
http://www.freemap.co.il/map/
Christopher Schmidt
2010-09-01 22:23:25 UTC
Permalink
Post by Ehud Shabtai
Post by Christopher Schmidt
I don't think so. Does this mean that our definition of Function.bind is
different from that in Prototype somehow? Looking at the code, it seems
like the end result of the current (Prototype 1.5.1) definition and our
current definition in OpenLayers should end up being the same...
I'm no javascript expert but I think that the implementation is a bit
different and that seems to be the problem.
Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
}
Function.prototype.bind = function() {
var __method = this, args = [], object = arguments[0];
for (var i = 1; i < arguments.length; i++)
args.push(arguments[i]);
return function(moreargs) {
for (var i = 0; i < arguments.length; i++)
args.push(arguments[i]);
return __method.apply(object, args);
}
};
I believe that the problem is in the inner function. Prototype uses
args.concat(arguments), which I think (?) only creates a temporary
array for calling the function. args is not changed.
OpenLayers uses args.push which changes args and adds new elements in it.
Ahh, okay. That's probably unintentional -- I don't see any case where
the OpenLayers code would care, cause we don't bind any functions that
would be called multiple times. I bet... ah, yeah. this is probably just
a typo in our translation from Prototype -> OL stuff, dropping $A().
That's definitely a bug that I've bumped into: I'll cook up a patch
(though if you have something that works, you can feel free to create a
ticket and patch!)
Post by Ehud Shabtai
But I wasn't sure if the Openlayers implementation
intentionally differs from prototype?
I don't think so. I think it was a mis-translation, nothing more. We
just haven't bumped into it, because our uses of 'bind' are all
one-time-only.

Regards,
--
Christopher Schmidt
MetaCarta
Loading...