-4

I have a page where users can choose to book a ticket for a concert. First, they click on a artist which launches them into the booking process (and passes "artist" to the starting function).

The program then loads the venues for the artists. When the user changes the venue (and the value isn't blank) it tried to load the dates available in another select drop down menu by calling another function.

The original code was like:

<select onchange="loadDates(artist)">...</select>

However for some reason this wasn't passing the parameter from the starting function to the next function.

So I changed it too:

    <select onchange="loadDates.call(this, artist)">..</select>

However the next function still gives me the error "artist is not defined" when I try to run it. Can anyone see what I'm doing wrong here as I read online that this works perfectly. I can give more information if need be. Thanks

Kijewski
  • 25,517
  • 12
  • 101
  • 143
Joshua
  • 906
  • 5
  • 12
  • 23
  • 1
    *"Javascript can't pass parameters between functions"* Yes, it can. (But they're called "arguments" in JavaScript.) – T.J. Crowder Jun 12 '14 at 10:30
  • @T.J.Crowder can you please advise what I'm doing wrong up above then? And sorry for using the wrong term! – Joshua Jun 12 '14 at 10:31
  • Using inline event handlers is what you're doing wrong ;) They're not evaluated in the current scope, therefore `artist` is undefined there. – Niet the Dark Absol Jun 12 '14 at 10:31
  • Are you certain that `artist` is a global? – Paul Jun 12 '14 at 10:31
  • So the variable exists? – Marco Acierno Jun 12 '14 at 10:33
  • The variable exists, it's passed into the function initially after an onclick fires. I just read above that this is likely the issue as it isn't global. It fires after is clicked, so that would make it internal to the launch function? – Joshua Jun 12 '14 at 10:35

1 Answers1

3

Code in onXyz attributes is run at global scope, so both of your examples require that there be a global variable called artist. If there isn't one, then you'll get a ReferenceError because you're trying to take the value of a symbol that isn't defined.

If you meant to pass a string, put quotes around it. If you meant to pass something else, you'll need to say what that was. But the fundamental issue is that artist is not a defined symbol at global scope, which is where you're trying to use it.

If you have artist defined in some non-global location (good! globals are a bad thing), then you'll want to hook up your event handler via modern techniques rather than using the onXyz attributes.

The simplest way if you're not using a DOM library (like jQuery or similar) is to assign to the onXyz property of the select box element:

(function() { // Something to keep the stuff inside from being globals
    var artist = "Joe Cocker";

    var selectBox = document.querySelector("selector for the select box");
    selectBox.onchange = function() {
        loadDates(artist); // `artist` is in scope now
    };
})();

In general, though, I avoid the onXyz properties because they only allow a single handler per event per element, preferring the DOM method addEventListener (and its Microsoft-specific predecessor, attachEvent). I didn't use them above for simplicity. If you don't use a DOM library, you might want this hookEvent function given in another answer which uses addEventListener if it's there, or attachEvent if it isn't, and supplies some missing bits for the attachEvent browsers.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks for the explination. I should be able to place this at the end of my JS code (and comment out the onchange), replace the "selector for the select box" with my div-id and it should work, right? – Joshua Jun 12 '14 at 10:50
  • @JoshuaDempsey: Provided your code is at the end of your HTML, so the element exists as of when you go to look it up, yes. I'm not sure what you mean by "div-id", you presumably want to attach this to the `select` element, not a `div`. – T.J. Crowder Jun 12 '14 at 12:01
  • Ah yes TJ, sorry, you are correct I messed that up. I think the problem is that I am creating the elements dynamically (using createElement) and then I get "Uncaught TypeError: Cannot set property 'onchange' of null ", however the code to create the selects is before the function so I don't know why this is happening. – Joshua Jun 12 '14 at 13:38