0

A. I need 2 lists next to each other. The left one containing a database of songtitles. I want to be able to drag & drop items from the left list to the right list (The right list is a play queue).

B. I want to populate the left list dynamically from a REST GET server call.

C. Both lists should have 3 lines per item (artist, songtitle and album)

Is all this even possible? What way should I go? I am looking for a way that is least 3rd party dependent (aren't we all).

1 Answers1

1

Heres an example I did in JSFiddle that I updated a little bit off of this example from W3Schools. it uses htmls drag and drop features and it was fairly simple to put together https://www.w3schools.com/html/html5_draganddrop.asp.

<script>
function allowDrop(ev) {
ev.preventDefault();
}

function drag(ev) {
console.log(ev.target.id);
ev.dataTransfer.setData("text", ev.target.id);
}

function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data))
}

function addData() {
// Mock return data from API call
  var data = [{title: "song 1", album: "album 1", artist: "artist 1"}, {title: "song 2", album: "album 2", artist: "artist 2"}]
  
  for (let i = 0; i < data.length; i++) {
  
    var columnTracks = document.getElementById("tracks");
    var node = document.createElement("div");
    var songTitle = document.createTextNode(data[i].title);
    var songAlbum = document.createTextNode(data[i].album);
    var songArtist = document.createTextNode(data[i].artist);
    
    node.setAttribute("ondragstart", "drag(event)");
    node.setAttribute("ondrop", "drop(ev)");
    node.setAttribute("draggable", "true");
    node.setAttribute("id", `${data[i].title}-${data[i].artist}`)
    node.class="item";
    node.appendChild(songTitle);
    node.appendChild(songAlbum);
    node.appendChild(songArtist);
    columnTracks.appendChild(node);
}}
</script>


<body>
  <div class="rows">
    <div ondrop="drop(event)" ondragover="allowDrop(event)" style="width: 50%;    float:right; height: 300px; background-color: grey;">
      <B>QUEUE</B>
    </div>
    <div id="tracks"  style="background-color: darkgray; height: 300px;">
    <B>TRACKS</B>
      <div id="item-1" class="item" ondragstart="drag(event)" draggable="true">
        Item 1
      </div>
      <div id="item-2" class="item" ondragstart="drag(event)" draggable="true">
        Item 2
      </div>
    </div>
  </div>
  
  
  <div>
  <button onclick="addData()" style="height: 20px; width: 150px;">
  ADD DATA
  </button>
  </div>
</body>
Khaladin
  • 418
  • 5
  • 11
  • Two things: The items added with addData can't be dropped. And how can get the childs songartist, songtitle and songalbum aligned vertically? – Richard Lleram Jun 24 '20 at 14:30
  • When creating the var songTitle, songAlbum, songArtist, instead of using createTextNode, you could use createElement("div") and then add the textNode to the div you created so they align vertically. – Khaladin Jun 24 '20 at 14:33
  • And do you happen to have a clue as to why the items can't be dropped? – Richard Lleram Jun 24 '20 at 15:09
  • Yes we have been setting the attribute wrong it should be with the node.setAttribute method as shown here in this post https://stackoverflow.com/questions/19625646/javascript-adding-an-id-attribute-to-another-created-element. I've updated my code in the addData function to reflect that – Khaladin Jun 24 '20 at 16:51
  • Drag Drop still doesn't work for the items added with addData – Richard Lleram Jun 25 '20 at 07:17
  • Sorry about that I forgot to copy the Id line. the drag and drop works by looking at the elements Id. because that wasn't set it wasn't putting it into the proper column, code updated – Khaladin Jun 25 '20 at 11:10
  • Thank you. It works now. I have 2 additional questions: I noticed that touch control is not working for drag/drop. How can this be done? And what to do if I want to copy an item when dragging, instead of moving it. So the item should not be removed from the left list. One other thing: because you use artist and title as ID for the div, I don't think it is possible to add the same song more than once to the queue. – Richard Lleram Jun 26 '20 at 20:40