DGRFDSGN DGRFDSGN - 4 years ago 80
Javascript Question

Dynamic function and dynamic parameter/argument

I have this function called

copyToClipboard()
. This takes a parameter called element. This function copies the content of a element by locating its id, selecting and copying the contents.

For instance:

JS

/*
* Copy to clipboard fn
*/
function copyToClipboard(element) {
var $temp = $("<input>");
$("body").append($temp);
$temp.val($(element).text()).select();
document.execCommand("copy");
var $tempval = $temp.val($(element).text());
$temp.remove();

var $notif = $("<p>");
$notif.attr("class","notif");
$("body").append($notif);
$notif.html('Copied content to clipboard!');
setTimeout(function() {
$notif.fadeOut();
$notif.promise().done(function(){
this.remove();
});
}, 400);
}


HTML:

<p id="p1">content of #p1</p>
<p> not me tho </p>
<p id="p2">content of #p2</p>
<button onclick="copyToClipboard('#p1')">Copy P1</button>
<button onclick="copyToClipboard('#p2')">Copy P2</button>


I am trying to improve this into a function which generates the buttons dynamically.

My approach so far where I integrated the above function into a new function, iterating over the elements found by ID/Class (IDs in this example),vb generating buttons with the onclick function container the iterated value as a parameter/argument.

/*
* generate copy buttons fn
*/
function generateCopyButtons() {

var links = document.getElementById('links').getElementsByTagName('p');
for (var i = 0; i < links.length; i++) {
var $link = links[i];
var thisId = $($link).attr('id');
if( thisId && thisId !== "null" && thisId !== "undefined" ){
var $button = document.createElement('button'); // btn
$button.innerHTML = 'Copy ' + thisId; //btn text
var element = '#' + thisId; // # + id
// console.log(element); // works like i want, #p1, #p2

//how do i pass the element into this function??
$button.onclick = function(element) {
var $temp = $("<input>");
$temp.val($(element).text()).select();
document.execCommand("copy");
var $tempval = $temp.val($(element).text());
$("body").append($temp);
$temp.remove();

var $notif = $("<p>");
$notif.attr("class","notif");
$("body").append($notif);
$notif.html('Copied content to clipboard!');
setTimeout(function() {
$notif.fadeOut();
$notif.promise().done(function(){
$notif.remove();
});
}, 400);
};
$($link).prepend($button);
// $($thisHashId).remove();
}
}

}
$(document).ready(function(){
generateCopyButtons();
});


Right now it doesn't show errors and it doesn't work. Using the previous buttons works fine.

jsfiddle demonstrating problem

Answer Source

Thanks to @lookforangular is was able to update my code. first selecting all p nodes in the div#links in a foreach loop. This way the click event can be handeled in general instead of selecting single p nodes.

By setting the id as a data-p the click event can use the data-p value as dynamic argument to target the div you want to copy. Feel free to rewrite, use or update this function. Below the code is a link to a working fiddle demonstrating the effect. Small bonus a message notifies the user of this action.

 /*
  * generate copy buttons fn
  */
 function generateCopyButtons() {
   var pNodes = document.querySelectorAll('#links p[id^="p"]');
   pNodes.forEach(function(element) {
     var $button = document.createElement('button'); // btn       
     $button.innerHTML = 'Copy ' + element.id; //btn text
  // for this example we will set the value of data-p dynamically with the id so we have something to target. 
     $button.setAttribute('data-p', element.getAttribute('id'));
     element.prepend($button);

   $($button).on("click", function() {
     var $datap = '"#' + $($button).attr('data-p') + '"';
     //console.log($datap);
     var $temp = $("<input>");
     $("body").append($temp);
     $temp.val($(element).text()).select();
     document.execCommand("copy");
     $temp.remove();

     var $notif = $("<p>");
     $notif.attr("class", "notif");
     $("body").append($notif);
     $notif.html('Copied content to clipboard!');
     setTimeout(function() {
       $notif.fadeOut();
       $notif.promise().done(function() {
         this.remove();
       });
     }, 400);
   });

   });
 }
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download