简体   繁体   中英

Jquery only appending to first class element

for the first iteration of this it works fine, the table is created as intended. However upon the second iteration, the drop down menu is empty. The loops are all working correctly so I'm assuming it has to be something to do with how I am appending the option to select. Appreciate any help.

Javascript

function loadPlayers() {

  //first ajax call to retrieve players
  $.ajax({
    url: '/players',
    type: 'GET',
    contentType: "application/json",
    success: function(data) {

      //second ajax call to retrieve presentations
      $.ajax({
        url: '/presentations',
        type: 'GET',
        contentType: "application/json",
        success: function(presentationData) {

          // loop through each player and append player/presentation to table
          data.forEach(function(player) {
            console.log("players")
            $(".player-table").append(
              $('<tr>').append(
                $('<td>').attr('class', 'player-td').append(player.name),
                $('<td>').attr('class', 'presentation-td').append(player.presentation),
                $('<td>').attr('class', 'new-presentation-td').append(
                  $('<select>').attr('class', 'new-presentation-dropdown').append(

                    // loop through each presentation in database and add to dropdown
                    presentationData.forEach(function(presentation) {
                      console.log(presentation.name);
                      $(".new-presentation-dropdown").append('<option>' + presentation.name + '</option>')

                    })
                  )
                )
              )
            )
          })
        }
      })
    }
  })
}

HTML

  <table class="player-table">
    <tr class="player-name-tr">
      <th>Player Name</th>
      <th>Current Presentation</th>
      <th>New Presentation</th>
    </tr>
  </table>

You're running the 2nd loop inside the append statement - it means the loop appending the options is run before the <select> is created. Since the select element has not yet been created $(".new-presentation-dropdown") matches nothing in the DOM. Moving the loop appending the options outside of all the .append() statements should fix this issue:

data.forEach(function(player) {
    console.log("players");
    $(".player-table").append(
            $('<tr>').append(
                    $('<td>').attr('class', 'player-td').append(player.name),
                    $('<td>').attr('class', 'presentation-td').append(player.presentation),
                    $('<td>').attr('class', 'new-presentation-td').append(
                            $('<select>').attr('class', 'new-presentation-dropdown')
                    )
            )
    );

    // loop through each presentation in database and add to dropdown
    presentationData.forEach(function (presentation) {
        console.log(presentation.name);
        $(".new-presentation-dropdown").append('<option>' + presentation.name + '</option>')
    })
});

However $(".new-presentation-dropdown") will match every <select> created so that'll give strange results. I'd suggest you assign the $('<select>') to a variable and append the options to the variable, before appending it to the table, like this: (Untested but should work)

data.forEach(function(player) {
    console.log("players");

    var $newPresentationDopdown = $('<select>').attr('class', 'new-presentation-dropdown');

    // loop through each presentation in database and add to dropdown
    presentationData.forEach(function (presentation) {
        console.log(presentation.name);
        $newPresentationDopdown.append('<option>' + presentation.name + '</option>')
    });

    $(".player-table").append(
            $('<tr>').append(
                    $('<td>').attr('class', 'player-td').append(player.name),
                    $('<td>').attr('class', 'presentation-td').append(player.presentation),
                    $('<td>').attr('class', 'new-presentation-td').append($newPresentationDopdown)
            )
    );
});

Based on append method documentation you can pass function by below feature:

A function that returns an HTML string, DOM element(s), text node(s), or jQuery object to insert at the end of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set.

Whiles below code is inconsistent by that rule:

$('<select>').attr('class', 'new-presentation-dropdown').append(

   // loop through each presentation in database and add to dropdown
     presentationData.forEach(function(presentation) {
         console.log(presentation.name);
         $(".new-presentation-dropdown").append('<option>' + presentation.name + '</option>')

    })
  )

You don't return any result in your passed function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM