Search code examples
javascripthtmllistdrag-and-drop

How to make dynamic multiline list with drag & drop from first to second list


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).


Solution

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