2014-01-15 16 views
10

私は、DOMの準備ができたらデータベースからプロジェクト名を取得するアプリケーションを持っています。各プロジェクトは、の<select><option>に追加されています。リストにデータが入力されると、ユーザーはプロジェクトタイトルを選択できます。プロジェクトタイトルは、そのプロジェクトに固有のデータベースから残りの情報を要求します。jQuery .change()イベントは一度だけ発生します

これを実現するには、$.change() jQueryメソッドを使用しています。残念ながら、イベントは、<select>要素が作成されてDOMに追加されたときに1回だけ発生します。リストから別のプロジェクトを選択してもイベントは発生しないため、$.post()呼び出しは実行されません。

あなたはイベントの委任

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

を処理する必要が

$(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."); 
      }); 
     } 
    } 
)}; 
+0

私は取り残さ匿名関数と 'getProjects();'を呼び出すことでコードの量を減らすことができましたが、明らかに混乱を招いていました。 – Roy

答えて

10

を削除:

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

あなたのコードでは、あなたはでした "retrieveProject"関数があり、その関数呼び出しからの戻り値が "変更"ハンドラとして渡されていました(もちろん効果がありません)。そのため、イベントがページの読み込み時に生成されているように見えます。あなたはとしての機能を操作しているとき

、あなたがしたいこと、それは(この場合は関数名)を参照そのものだ関数リファレンス—後()を使用しないでください。それがjQueryに渡される必要があります。

また—、これはあなたのコードは、どちらかあなたの<script>は、ページ上の<select>要素が来ることを、他の「準備完了」または「負荷」ハンドラ、またはで実行されていることを確認する重要—です。スクリプトがドキュメントの先頭にある場合は、DOMが解析される前にスクリプトが実行され、効果はありません。 (それに対処するための別の方法は、他の回答で提案されているように.on()委任フォームを使用することであろう。)


の詳細:あなたは「getProjects」のコンテンツを取得するとき、あなたの<select>要素を上書きしているように見えます。このように、あなたは間違いなく委任の形式を使用する必要があります。

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

また、あなたは「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; 
    }); 
} 
+0

私は実際にDOMが準備されるのを待っていることを示すために質問を編集しました。関数名の後ろに括弧を削除しましたが、警告のいずれも起動しません。 – Roy

+0

@Roy「