Mike,
You are the man! No seriously! I fully understood WHY the comment
bubble HTML was only using the last iteration's value, but I am no
expert with closures. The book jQuery in Action touches on it, but I
still haven't wrapped my head around its power. Thank you thank you
thank you so much. Your explanation is clear, concise and elegant. I
have tested it out and it works great
As far as the coding practices are concerned, I am aware of all of the
issues and whipped this together toward the end of the day yesterday
and was determined to get it to work today. Also, I am using a portal
solution that uses Velocity templates so the $ alias can't be used.
And having to deploy the "theme" just to test in the development
environment coerced me to use sloppy practices.
In regards to the amount of queries to Google, I FULLY agree with
storing these values on the server instead of the client doing the
heavy lifting. I need to SHOW this in order for it to get
accomplished, if you know what I mean.
Thanks again!
Joe
On Apr 26, 11:53 am, "Michael Geary" <[EMAIL PROTECTED]> wrote:
> Joe, the problem is that your code has a single variable "i". At any point
> in time, when you reference that variable you will get the *current* value
> of "i".
>
> While the for loop is running, "i" gets each of the values you expect. But
> when is your callback function called? Much later, *after* the loop has
> finished running. At this point "i" has the last value it was given in the
> loop, 150.
>
> (Note that your loop does not run from 1 through 150, but 1 through 149. The
> last time through the loop, the value is 149, and then when the value
> reaches 150 the loop terminates - so "i" is 150 after that.)
>
> Then why is the marker created at the correct location? Because the
> searchAddress geocoding function calls the callback with "point" set
> correctly. But "i" is your own variable, and there's only one copy of it for
> the entire program.
>
> The easiest way to fix this is usually to use a closure. You could code it
> like this:
>
> jQuery(function( $ ) {
>
> var $map2 = $('#map2');
>
> $map2.jmap({
> mapCenter:[30.2687,-97.7452],
> mapZoom: 13
> });
>
> for( i = 1; i < 150; i++ )
> createMarker( i );
>
> function createMarker( i ) {
> $map2.jmap("searchAddress", { address :$('#address'+i).val() },
> function(options,point) {
> $map2.jmap("addMarker", {
> pointLatLng: [point.y, point.x],
> pointHTML: "<div style='width:200px;'><p>This office is
> located at:</p><p><b>" + $('#address'+i).val() + "</p></div>" ,
> centerMap: false
> });
> });
> }
>
> }); // End of DOM Ready
>
> The only real change to the code here is the addition of the createMarker()
> function. This function is called each time through your loop, and each time
> it's called it gets its *own* local variable, also named "i". (It isn't
> significant that this name "i" is the same name as the "i" outside the
> function - they are two different variables and could have different names.)
>
> So, when the searchAddress callback is called, it's using the local "i"
> inside that particular instance of the createMarker function, which will be
> the value you expect.
>
> I took the liberty of making a couple of unrelated changes to the code, just
> to illustrate some recommended coding techniques - in particular, the use of
> the $map2 variable instead of calling the jQuery function $('#map2') every
> time through the loop. Any time you can move something outside a loop
> instead of calling it repeatedly, it will help performance.
>
> One thing I didn't fix is the hard coded value of 150 (or 149). You probably
> don't want to just hard code this - what happens when you open another
> office? :-)
>
> HOWEVER...
>
> All that said, there is a much worse problem with the code, one that we
> can't fix here.
>
> The Google client geocoder is limited to 15,000 queries per day per API key.
> At 150 per visit, you are going to hit that limit as soon as your page is
> visited (or reloaded) 100 times. Then you will be blocked from further
> geocoding requests, typically for 24 hours.
>
> Even before you hit the limit, geocoding 150 locations is going to take a
> while.
>
> There's no way to fix this in JavaScript. Instead, you need to geocode all
> of your locations ahead of time, save them in a database or a file on your
> server, and code those latitude/longitude points into your HTML/JavaScript.
> This will eliminate all the need for geocoding on the client. Your map will
> load *much* faster, and you won't have to worry about the geocoder API
> limit.
>
> -Mike
>
> > From: Joe
>
> > Check the following code:
>
> > $j = jQuery;
>
> > $j().ready(function()
> > {
>
> > $j('#map2').jmap({
> > mapCenter:[30.2687,-97.7452],
> > mapZoom: 13
> > });
>
> > for(i=1; i < 150; i++)
> > {
>
> > $j('#map2').jmap("searchAddress", {address:
> > $j('#address'+i).val() }, function(options,point)
> > {
> > $j('#map2').jmap("addMarker", {
> > pointLatLng:[point.y,
> > point.x],
> > pointHTML: "<div style='width:
> > 200px;'><p>This office is located at:</p><p><b>" +
> > $j('#address'+i).val() + "</p></div>" ,
> > centerMap: false
> > });
> > });
>
> > }
>
> > }); // End of DOM Ready
>
> > In the markup there are 150 like these:
>
> > // "N" represents a number from 1 to 150
>
> > <input type="hidden" id="addressN" value="123 Main Street New
> > York, NY 10101" />
>
> > Now when I throw in some alerts I notice that the 2nd
> > function (the callback function) actually places the proper
> > point, but does NOT produce the proper HTML; for each point
> > that is place the comment bubble has the address of the LAST
> > point that was placed on the map. Why would it place the
> > point in the proper iteration, but not the associated HTML?