Mark Ziemann
Mark Ziemann

Reputation: 51

How to do JS variable substitution for exportTableToCSV?

In my web page I want to be able to export multiple tables as csv. I can code these individually (like this), but my for loop isn't working.

// this works
$("#xx001").on('click', function (event) { exportTableToCSV.apply(this, [$('#table001'), 'export.csv']);  });
$("#xx002").on('click', function (event) { exportTableToCSV.apply(this, [$('#table002'), 'export.csv']);  });

// this fails
let myxx = "";
let mytable  = "";
for (let i = 0; i < 5; i++) {
    myxx += "xx00" + i ;
    table += "table00" + i ;
    $('#'+${myxx}).on('click', function (event) { exportTableToCSV.apply(this, [$(  '#'+${table}    ), 'export.csv']); });
});

I expected that the both tables could be exported, but I'm getting a "File not found" error using the loop.

Upvotes: 2

Views: 52

Answers (2)

Khyron
Khyron

Reputation: 468

It shouldn't be necessary to create a loop for this. A single jQuery statement can bind a listener to every button.

$('.btn').on('click', function (event)...

The trick is that apply() needs the id of the relevant table. That can be provided dynamically by traversing the DOM relative to the particular button that was pressed.

If the table element is followed by the button (as it is in the linked example), then we only need to reference the previous element:

$('.btn').on('click', function (event) { exportTableToCSV.apply(this, [$(this).prev().attr("id"), 'export.csv']) 
});

Note that prev() can accept selector arguments, so even if the table isn't the immediately preceding sibling element you could use a selector to find it something like prev("table")

Upvotes: 0

mrReiha
mrReiha

Reputation: 955

Your function inside of the loop will call that last myxx and table which both are 005 at the time of firing event ( when the loop is iterated until the end, and those two variables got filled with the last value of loop ).

If you need more explanation about what dafuq is happening, you should check these articles about closures. article one and article two. There are tons of more resources out there, but I just found these two at the moment.

You need to pass the right variable to it just like this:

for (let i = 0; i < 5; i++) {
    let myxx = "xx00" + i ;
    let table = "table00" + i ;

    (function( x, t ) {

        $('#' + x ).on('click', function (event) { exportTableToCSV.apply(this, [$( '#' + t  ), 'export.csv']); });

    })( myxx, table );

};

the above code should do the job for you.

Upvotes: 1

Related Questions