Home > Software engineering >  Is there any way to add values dynamically to an onclick function?
Is there any way to add values dynamically to an onclick function?

Time:10-05

I've got a music player in which I can download audio files by linking the href directly to a click function. Each audio file is in a li element and everything works fine as long as I keep it hardcoded. But the moment that I convert the li elements and the link for download to dynamic, I can't connect the click function anymore. Can anyone help? Here's the code:

// Html hardcoded

<ul id="playlist1" class="hidden m-1 p-0">
<li id="li-items" data-song="the-deal.wav">The Deal<span class="dwn fa fa-download" onclick="downloadFile('/audio/the-deal.wav', 'The Deal')"></span></li>
<li id="li-items" data-song="rise-of-don.mp3">Rise of The Don<span class="dwn fa fa-download" onclick="downloadFile('/media/rise-of-don.mp3', 'Rise of The Don')"></span></li>
</ul>

// Audio Library js

var data1 = [{
          href: "/media/the-deal.wav",
          name: "The Deal",
          song: "the-deal.wav"
      }, {
          href: "/media/rise-of-don.mp3",
          name: "Rise of the Don",
          song: "rise-of-don.mp3"
      }]


// Create li elements
            for (var i = 0; i < data1.length; i  ) {
                var t = document.createElement('li');
               t.setAttribute("id","li-items");
               
               
                var ta = document.createElement('span');
                ta.classList.add("dwn","fa","fa-download");
                ta.setAttribute("onclick","downloadFile('url','filename')");  // << This is the line that I'm having trouble with. 'Url' and 'filename' should be added dynamically for each li element. 
                
                t.dataset.song = s.song;
                t.textContent = s.name;
                t.appendChild(ta);

                
                document.getElementById('playlist1').appendChild(t);

    }

// Audio Player js - (download function):

function downloadFile(url, filename) {
    //Filename download the user-defined name. The URL is the download address
    var link = document.createElement('a');
    link.href = url;
    link.download = filename;
    link.target = '_blank';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    link = null;
}

If anyone could help, I'd really appreciate it.

CodePudding user response:

I supposed in this line

ta.setAttribute("onclick","downloadFile('url','filename')");

You're using string as the attribute. Maybe you could

// ta.setAttribute("data-href", data[i].href)
// ta.setAttribute("value", data[i].name)

// You can also 
ta.dataset.href = data[i].href
ta.dataset.name = data[i].name

ta.addEventListener("click", downloadFile)

And then in the downloadFile

function downloadFile(e) {
    fileUrl = e.dataset.href
    fileName = e.dataset.name
    console.log(fileUrl, fileName)
    
    // continue with your actions
}

More on datasets -- https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset

CodePudding user response:

var data1 = [
// ... 
]

Create List items:

const playList = document.querySelector('#playlist1')
data1.forEach((data, i) => {
    const list = document.createElement('li');
    list.setAttribute('class', 'song-items');
    list.dataset.index = i;
    list.textContent = data.name;

    const listInner = document.createElement('span');
    listInner.classList.add('dwn', 'fa', 'fa-download');

    list.appendChild(listInner);
    playList.appendChild(list);
})

Check for the click event:

document.querySelectorAll('.song-items').forEach(item => {
    item.addEventListener('click', () => {
        const index = item.getAttribute('data-index');
        const { href, name } = data1[index];
        downloadFile(href, name);
    })
})

Download Function:

function downloadFile(url, filename) {
    console.log(filename, url)
    
    // ... 
}
  • Related