/*! © SpryMedia Ltd - datatables.net/license */ /** * A button that can be used to trigger a server-side action, typically a * download of a file generated by the server. If server-side processing * is enabled in the host table it will automatically add the last parameters * used for a table draw allowing the script to output a file with the same * order / search applied as the main table. * * This is particularly useful when using server-side processing and wishing * to allow user export of the data in a table. The default Buttons package * will only export the data available on the client-side, while this button * can be used to let the server generate the required file and then download * it to the client-side. * * @name Download Button * @summary A button that can be configured to trigger a server-side action. * @author SpryMedia Ltd (www.datatables.net) * @copyright Copyright SpryMedia Ltd. * @requires DataTables 3+ * @license MIT - http://datatables.net/license/mit * * @example * // Download button * const table = new DataTable('#example', { * layout: { * topStart: { * buttons: [{ * extend: 'download', * url: '/api/download' * }] * } * } * }); */ import DataTable, { Api, util } from 'datatables.net'; function flattenJson(data: any, name?: any, flattened?: any) { if (!flattened) { flattened = {}; } if (!name) { name = ''; } if (util.is.plainObject(data)) util.object.each(data, function (idx, val) { if (name === '') { flattenJson(val, idx, flattened); } else { flattenJson(val, name + '[' + idx.toString() + ']', flattened); } }); else if (Array.isArray(data)) { for (let i = 0; i < data.length; i++) { if (name === '') { flattenJson(data[i], i, flattened); } else { flattenJson( data[i], name + '[' + i.toString() + ']', flattened ); } } } else { flattened[name] = data; } return flattened; } DataTable.ext.buttons.download = { text: 'Download', action: function (e: Event, dt: Api, node: Node, config: any) { // Gather information to be submitted var data = {}; if (dt.page.info().serverSide) { Object.assign(data, dt.ajax.params()); } if (typeof config.data === 'function') { config.data(data); } else if (typeof config.data === 'object') { Object.assign(data, config.data); } // Convert data to a flat structure for submission var flattened = flattenJson(data); // Create an iframe var iframe = document.createElement('iframe'); iframe.style.border = 'none'; iframe.style.height = '0'; iframe.style.width = '0'; document.body.appendChild(iframe); var contentDoc = iframe.contentWindow!.document; contentDoc.open(); contentDoc.close(); var form = contentDoc.createElement('form'); form.method = config.type; form.action = config.url; contentDoc.appendChild(form); util.object.each(flattened, function (name, val) { let input = contentDoc.createElement('input'); input.type = 'text'; input.name = name.toString(); input.value = val as string; input.autocomplete = 'no' as any; form.appendChild(input); }); form.submit(); }, url: '', type: 'POST', data: {} };