PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.87
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.87
51.1.87 51.1.86 51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 All 41 releases
← All changes | includes/widgets/Data_Table/script.js +33 -17 51.1.65 → 51.1.87 View file →
@@ -272,44 +272,60 @@
272 272 if (!$scope.find('.king-addons-table-export-button-cont').length) return;
273 273
274 274 const exportBtn = $scope.find('.king-addons-table-export-button-cont .king-addons-button');
275 275
276 - const htmlToCSV = (filename, $view) => {
276 + const csvEscape = (value) => {
277 + const text = String(value == null ? '' : value).replace(/\r?\n/g, ' ').trim();
278 + if (/[",]/.test(text)) {
279 + return '"' + text.replace(/"/g, '""') + '"';
280 + }
281 + return text;
282 + };
283 +
284 + const tableRowsToCSV = ($view) => {
277 285 const rows = $view.find(".king-addons-table-row");
278 286 const data = [];
279 287 rows.each((_, row) => {
280 288 const cols = row.querySelectorAll(".king-addons-table-text");
281 - const rowData = Array.from(cols).map(cell => cell.innerText);
289 + const rowData = Array.from(cols).map(cell => csvEscape(cell.innerText));
282 290 data.push(rowData.join(","));
283 291 });
284 - downloadCSVFile(data.join("\n"), filename);
292 + return data.join("\r\n");
285 293 };
286 294
287 - const downloadCSVFile = (csv, filename) => {
288 - const csvFile = new Blob([csv], { type: "text/csv" });
295 + const triggerDownload = (blob, filename) => {
296 + const url = URL.createObjectURL(blob);
289 297 const downloadLink = document.createElement("a");
290 298 downloadLink.download = filename;
291 - downloadLink.href = window.URL.createObjectURL(csvFile);
292 - downloadLink.style.display = "none";
299 + downloadLink.href = url;
300 + downloadLink.rel = "noopener";
301 + downloadLink.style.position = "fixed";
302 + downloadLink.style.left = "-9999px";
293 303 document.body.appendChild(downloadLink);
294 304 downloadLink.click();
305 + setTimeout(() => {
306 + URL.revokeObjectURL(url);
307 + downloadLink.remove();
308 + }, 1500);
295 309 };
296 310
297 311 exportBtn.each(function () {
298 312 const $btn = $(this);
299 313 if ($btn.hasClass('king-addons-xls')) {
300 - // XLS export
301 - $btn.on('click', () => {
302 - const $table = $scope.find('table');
303 - TableToExcel.convert($table[0], {
304 - name: 'export.xlsx',
305 - sheet: { name: 'Sheet 1' },
306 - });
314 + $btn.on('click', (event) => {
315 + event.preventDefault();
316 + const table = $scope.find('table').get(0);
317 + if (!table) {
318 + return;
319 + }
320 + const html = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel"><head><meta charset="UTF-8"></head><body>' + table.outerHTML + '</body></html>';
321 + triggerDownload(new Blob(['\uFEFF' + html], { type: 'application/vnd.ms-excel' }), 'export.xls');
307 322 });
308 323 } else if ($btn.hasClass('king-addons-csv')) {
309 - // CSV export
310 - $btn.on('click', () => {
311 - htmlToCSV("placeholder.csv", $scope.find('.king-addons-data-table'));
324 + $btn.on('click', (event) => {
325 + event.preventDefault();
326 + const csv = tableRowsToCSV($scope.find('.king-addons-data-table'));
327 + triggerDownload(new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8;' }), 'export.csv');
312 328 });
313 329 }
314 330 });
315 331 };