3

I have a small google map script to get location, either from Lat Lon pair, or address , and also to UPDATE those lat, lon and address input fields ..

See jsfiddle here

When clicking the "draw" button - a function called codeAddress() is supposed to be called . but on the firebug console i get :

Error: ReferenceError: codeAddress is not defined

I do not understand why the codeAddress() is not defined ...

The strange thing is , that if I move the function OUTSIDE of the

jQuery(document).ready(function(){} it DOES work (See jsFIDDLE)

(I also need to move the var marker - otherwise it will only center the map,and gives marker is undefined error;

So my question is very simple, What am i doing wrong ? Why the same function works outside the jQuery(document).ready(function(){} but not inside ?

And a sidekick question : How do I get to update the address input field when the marker is dragged (like with the lon lat inputs..) ???

UPDATE - thanks to all - learned another important thing . Unfortunately - all are valid answeres and solutions - but I can accept only one, and for me , the easiest solution to understand (being so unfamiliar with JS - and despite it being maybe a not perfect practice ) is @cowls thanks again to everyone..

Obmerk Kronen
  • 15,619
  • 16
  • 66
  • 105

3 Answers3

3

The simple solution is to replace

function codeAddress() { ... }

with

codeAddress = function() { ... }

Your problem is that you're declaring codeAddress as a variable whose scope is local to the function you're binding to the document ready handler. So as soon as that function exits, codeAddress doesn't exist any more. The second declaration (note the missing "var") declares codeAddress as a global variable, so it will remain accessible after the ready function has exited.

AmericanUmlaut
  • 2,817
  • 2
  • 17
  • 27
  • Thanks, it does work - But I would like to understand in order to not repeat this mistake . If I use a `jquery()click.` event - instead of the `onclick`) - then I could move it back inside ?? – Obmerk Kronen Dec 06 '12 at 10:06
  • 1
    @ObmerkKronen Yes, that also works. The reason is that you're then binding the function from within the scope in which it's visible (inside the function where it is declared). Once you've bound the function, the variable codeAddress that refers to it will leave scope, so "codeAddress" will be undefined, but the function to which it referred will stay bound to the click event of your DOM element. – AmericanUmlaut Dec 06 '12 at 10:12
  • +1 for the comment explanation and upvote for a possible solution - see my update. thanks .. – Obmerk Kronen Dec 06 '12 at 10:45
  • @ObmerkKronen You don't have to apologize for not accepting an answer - I answer questions to force myself to deal with at least one problem a day that is alien to me. It's not for reputation, it's to keep the brain lubricated :) – AmericanUmlaut Dec 06 '12 at 11:06
  • not for apologizing - but honestly all answers - even if displaying different logic - were ok for me . And I understand about the "brain lubrication" - based on time available I also try to do that (although not with JS related questions - more of PHP and Wordpress..) Thanks again. – Obmerk Kronen Dec 06 '12 at 11:12
2

Rather than use onclick, you should assign a click handler to the required elements INSIDE your document.ready method.

E.g.

$(input).click(function() { codeAddress() });

Would assign the code address function to the click event for all input boxes, obviously you want to target this at specific classes or ids

this is best practice rather than using onclick.

cowls
  • 24,013
  • 8
  • 48
  • 78
  • This is not an answer to the question being asked – AmericanUmlaut Dec 06 '12 at 09:46
  • 1
    It would solve the question being asked and is better practice. – cowls Dec 06 '12 at 09:47
  • It does solve the problem, actually - I misread your answer. I disagree, though, that it's best practice. I find it much easier to understand what a button is supposed to do if its click handler is bound in the onclick attribute, because the behavior is immediately visible when you look at the element, rather than having to search for references to it. The only time I think it's really advantageous to bind in code is when you're actually binding dynamically. – AmericanUmlaut Dec 06 '12 at 09:52
  • 1
    See: http://stackoverflow.com/questions/5871640/why-is-using-onclick-in-html-a-bad-practice – cowls Dec 06 '12 at 09:54
  • The problem isn't that I'm unfamiliar with the concept of unobtrusive javascript, it's that I disagree with it as a blanket solution. In the case of a function that has a fixed, 1:1 relationship with a DOM element, I find in-HTML binding perfectly reasonable and more readable. – AmericanUmlaut Dec 06 '12 at 09:58
2

When the button is clicked, codeAddress() is looked up in the global scope, but you've defined it inside $(document).ready().

Declaring the function outside of $(document).ready() is probably the best here, only functions that you will only be calling from inside the ready handler should be defined inside; doing this will also keep your ready handler cleaner.

To find the location when a marker has been dragged over a location you need to use the GeoCoder server to map it to a textual location:

var geocoder = new google.maps.Geocoder();

google.maps.event.addListener(marker, 'dragend', function(evt) {
    geocoder.geocode({latLng: evt.latLng}, function(results, status) {
        if (status==google.maps.GeocoderStatus.OK && results.length) {
            // do something with results[0..x].formatted_address
        }
    })
});
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • Thanks for the answer - but for sake of understanding better - what you are saying, is that I do not need the document.ready at all ? for all the functions ? and if not - why only that one ?. – Obmerk Kronen Dec 06 '12 at 10:04
  • @ObmerkKronen No, just to define functions you will be using in other places *outside* of `$(document).ready( ... )`. – Ja͢ck Dec 06 '12 at 10:05
  • ok. I know that this is my own ignorance talking here - but doesn´t the `$(document).ready( ... )`function supposed to load wahtever other function is inside when the document load is done , AND make them available for use ?? Or maybe you mean that the `onclick`is actually considered `outside`? – Obmerk Kronen Dec 06 '12 at 10:09
  • 1
    @ObmerkKronen Function declarations don't do anything by themselves, so they're safe outside of the ready handler. The rest of the code should stay inside, because they can only run when the document is actually ready. And yes, code inside `onclick` attributes run globally. – Ja͢ck Dec 06 '12 at 10:11
  • +1 +up for the explanation and the Patience. learned a lot. see Update – Obmerk Kronen Dec 06 '12 at 10:47