Lewis
Lewis

Reputation: 13

Set data attribute for <li> in a loop using jquery

I have been struggling with this for a day or so now, I am pretty new to java script and building my first gui for my final project in order to achieve my qualification.

I am trying to build a music play web app.

the part i'm stuck on is when I perform a search my jquery generates a new ul element with li lising the song titles.

What im trying to do is to get the li to hold a data attribute that is unique to the song ("Mainly the file path and image path to the songs from the back end")

here is my code so far.

$("#searchButton").click(() => {
const input = $("#search").val();
const requestURL = "music/" + input.replace(/\s+/g, '%20');
$.ajax({
    url: requestURL,
type: "GET",
dataType: "json",
success: (data) => {
    if(data){ 
        $('ul,li').remove();

        $('<ul class="searchHeader"> </li>').text("Songs").appendTo('#songs');
        $('<ul class="albumHeader"> </ul>').text("Albums").appendTo('#albums');
        $('<ul class="artistHeader"> </ul>').text("Artist").appendTo('#artist');


        $(data).each(function(i) {
            $('<li class="results" </li>').text(data[i].songtitle).appendTo('#songsection')
        })


        --------//this is where i am having issues!!!!! -----

        $(".results").each(function (fp){
            $(this).attr("data-file", data[fp].filepath);
        })


        $(".results").click(() => {
            loadAudio($(".results").attr("data-file"));
            play();
        })

        var albumArray = [];
        for(var i = 0; i < data.length; i++){
            if(albumArray.indexOf(data[i].albumtitle) == -1){
                albumArray.push(data[i].albumtitle);  
            }
        }
        for(var i = 0; i < albumArray.length; i++){
        $('<li class="results" onclick=""> </li>').text(albumArray[i]).appendTo('#albumsection');
        }

        var artistArray = [];
        for(var i = 0; i < data.length; i++){
            if(artistArray.indexOf(data[i].name) == -1){
                artistArray.push(data[i].name);  
            }
        }
        for(var i = 0; i < artistArray.length; i++){
        $('<li class="results" onclick=""> </ul>').text(artistArray[i]).appendTo('#artistsection');
         }
        }
    } 
  })
})

As you can probably guess i'm getting the same data attribute for each li,

Any help would be greatly appreciated.

Thank you

Upvotes: 1

Views: 1465

Answers (1)

guest271314
guest271314

Reputation: 1

The issue at the code is

$(".results").click(() => {
  loadAudio($(".results").attr("data-file"));
  play();
})

within click handler, where $(".results") is the collection of all matched selectors, and .attr("data-file") gets only the first value of the selector passed to jQuery().

You can use $(this) or $(event.target) to reference the current element within $(".results") collection where the event was dispatched.

loadAudio($(this).attr("data-file"));
play();

Close tags of HTML passed to jQuery(). Multiple loops are not necessary. Use correct parameters of .each()

$(function() {

  var data = [{
    songtitle: 0,
    filepath: 0
  }, {
    songtitle: 1,
    filepath: 1
  }];

  $(data).each(function(i, value) {
    $("<li>", {
      "class": "results",
      text: "click " + value.songtitle,
      attr: {
        ["data-file"]: value.filepath
      },
      appendTo: "#songsection",
      on: {click: function(event) {
                    console.log(event.target.dataset.file, $(this)[0].outerHTML);
                    /*
                    // use built-in `event.target.dataset` or jQuery version
                    loadAudio($(event.target).attr("data-file"));
                    play();
                    */
                  }
          }
    })
  });

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<ul id="songsection">

Upvotes: 1

Related Questions