1

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

1

1 Answer 1

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">

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for this, it's made my code a lot more elegant, but I am still having the same issue the data attribute is set to the same file path for each li tag.
@Lewis "but I am still having the same issue the data attribute is set to the same file path for each li tag." Can you create a stacksnippets to demonstrate? See stackoverflow.com/help/mcve
I can but all my data is being pulled in from my backend and i can replicate this in the stack snippet. The code you provided works great for displaying the song titles but its setting the data attr to the same file path

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.