Exporting data from a datatable using a select element exports each option from a select element

I am trying to add export buttons to my datatable, my table includes select flags inside, the problem is that it exports all the parameter values โ€‹โ€‹included in the select box ... I use ajax to get the results from the server, then manipulate different data before rendering using the dataSrc function as follows:

 dataTableInit: function (columns_def) { var me = this; me.dataTable_obj = $('#leads_table').DataTable({ "pageLength": per_page, dom: 'Blfrtip', buttons: [ 'copy', 'csv', 'excel', 'pdf', 'print' ], "order": [order], "ajax": { url: route, type: method, data: filtering_data, "dataSrc": function (json) { return me.setLeadsTableData(json); } }, "columns": columns_def, .... 

in setLeadsTableData i checking the columns returned from the server, then if this is a column that should be a selection field, I change it like this:

  setStatusesSelectBox: function (status_obj, lead_id) { var me = this; var statuses_list = ''; var bg_color = status_obj.name == "new" ? me.new_status_row_bg_color : ''; $.each(me.client_statuses, function (key, val) { if (val.id != status_obj.id) { if (typeof val.is_won !== "undefined" && val.is_won != 0) { statuses_list += "<option data-icon='fa fa-thumbs-o-up' value='" + val.id + "'>" + val.name + "</option>"; } else if (typeof val.is_lost !== "undefined" && val.is_lost != 0) { statuses_list += "<option data-icon='fa fa-thumbs-o-down' value='" + val.id + "'>" + val.name + "</option>"; } else { statuses_list += "<option value='" + val.id + "'>" + val.name + "</option>"; } } else { if (typeof val.row_bg_color !== 'undefined') { bg_color = val.row_bg_color; } if (typeof status_obj.is_won !== "undefined" && status_obj.is_won != 0) { statuses_list += "<option data-icon='fa fa-thumbs-o-up' value='" + val.id + "' selected>" + val.name + "</option>"; } else if (typeof status_obj.is_lost !== "undefined" && status_obj.is_lost != 0) { statuses_list += "<option data-icon='fa fa-thumbs-o-down' value='" + val.id + "' selected>" + val.name + "</option>"; } else { statuses_list += "<option value='" + val.id + "' selected>" + val.name + "</option>"; } } }); statuses_list += "</select>"; var select_start = "<select name='status' data-show-icon='true' data-row-bg='" + bg_color + "' class='form-control status-select' data-lead-id='" + lead_id + "'>"; ; return select_start + statuses_list; }, 

any answer will help, rate it

+5
source share
3 answers

Use the exportOptions ' format.body to gain control over the exported data. Use the dataTables API to find the currently selected value for each <select> window. Here for the first column and pdf:

 buttons: [ { extend : 'pdf', exportOptions : { format: { body: function( data, row, col, node ) { if (col == 0) { return table .cell( {row: row, column: col} ) .nodes() .to$() .find(':selected') .text() } else { return data; } } } }, ... } ] 

Where table is an instance of the table, in your case me.dataTable_obj . Now just change if (col == 0) { so that it responds to columns where you have <select> tags (I don't know that).

+5
source

If you use the export format only for visible columns, the fixed column indices will play some tricks on you, so in my case it was to check the node child, and if it is selected, then make the format

 body: function(data, row, col,node) { var elementType = node.firstChild; if (elementType != null) { if (elementType.nodeName == "SELECT") return $(elementType).find(':selected').text(); else return data; } else return data 
+1
source

Credit to Mikhail Ushakov for starting me. There were some possibilities to simplify the code and make it work a little smoother (in my case) the biggest problem is that almost everything in my tables is a link or select. In the case of links, other code also grabbed html for the link, not text. In my case, I also had strange things like tables, so I had to expect several children in each node. Also declined to use jQuery;)

 exportOptions: { format : { body : (data, row, col, node) => { let node_text = ''; const spacer = node.childNodes.length > 1 ? ' ' : ''; node.childNodes.forEach(child_node => { const temp_text = child_node.nodeName == "SELECT" ? child_node.selectedOptions[0].textContent : child_node.textContent; node_text += temp_text ? `${temp_text}${spacer}` : ''; }); return node_text; } } }, 
0
source

Source: https://habr.com/ru/post/1238497/


All Articles