jQuery .change() event is only fired once

javascript, jquery

Solution

You're not setting up the event handler properly:

$("select").change(retrieveProject);

In your code, you were calling the "retrieveProject" function, and the return value from that function call was being passed as the "change" handler (and of course having no effect). That's why it appeared that the event was being generated upon page load.

When you're working with a function as a value, you don't use `()` after the function reference — it's the reference itself (the function name, in this case) that you want. That's what needs to be passed to jQuery.

Also — and this is important — make sure that your code is run either in a "ready" or "load" handler, or else that your `<script>` comes after the `<select>` element on the page. If the script is in the document head, then it'll run before the DOM is parsed, and it'll have no effect. (Another way to deal with that would be to use an `.on()` delegated form as suggested in another answer.)

More: it looks like you're overwriting your `<select>` element when you fetch the content in "getProjects". Thus, you should definitely use the delegated form:

$(document).on("change", "select", retrieveProject);

Also, you should be using local variables in "getProjects":

function getProjects() {
    var selectionList; // keep this local to the function - implicit globals are risky

    $.getJSON("php/getProjects.php", function (data) {
        selectionList = "<form><select>";
        for (var i = 0; i < data.length; i++) {
            selectionList += "<option name='prjTitle'>" + data[i].ProjectTitle + "</option>";
        }
        selectionList += "</select></form>";
    }).complete(function() {
       $('#project-selection-menu').append(selectionList).removeClass('hidden');
       firstLoad = false;
    });
}

Problem

I have an application that retrieves Project names from a database when the DOM is ready. Each Project is added to a `<select><option>` in an html `<form>`. Once the list is populated the user can select a project title, which will request the remaining information from the database specific to that project. To achieve this I'm using the `$.change()` jQuery method. Unfortunately, the event is only fired once when the `<select>` element is created and added to the DOM. Selecting another project from the list does not fire the event, and therefore does not trigger a `$.post()` call. ``` $(function(){ getProjects(); var firstLoad = true; $("select").change(retrieveProject); // Removed parenthesis based on answers // On page load, get project names from the database and add them to a Select form element function getProjects() { var selectionList; $.getJSON("php/getProjects.php", function (data) { selectionList = "<form><select>"; for (var i = 0; i < data.length; i++) { selectionList += "<option name='prjTitle'>" + data[i].ProjectTitle + "</option>"; } selectionList += "</select></form>"; }).complete(function() { $('#project-selection-menu').append(selectionList).removeClass('hidden'); firstLoad = false; }); } function retrieveProject() { if ( firstLoad == true ){ alert(firstLoad); // This alert fires return false; } else { alert(firstLoad); // This alert doesn't fire $.post("php/getProjects.php", function (data) { // This should have been "php/retrieveProject.php"! // Do stuff with the returned data }).complete(function() { console.log("Success."); }); } } )}; ```

Original source