jQuery datatables exporting data to Excel - javascript

I am trying to export directly from the datatable to Excel.
Starting with the ajax call:
displayRecords();
function displayRecords()
{
$.ajax({
url: 'process/getRecords.php',
type: 'POST',
data: '',
dataType: 'html',
success: function(data, textStatus, jqXHR)
{
var jsonObject = $.parseJSON(data);
var table = $('#resultsTable').DataTable({
{
"data": jsonObject,
"columns": [
{"data": "JOB_REFERENCE"},
{"data": "VOYAGE_REFERENCE"},
// few more columns
],
"iDisplayLength": 25,
"scrollY": 500,
"scrollX": true,
"bDestroy": true,
"paging": true,
"stateSave": true
}
},
error: function(jqHHR, textStatus, errorThrown)
{
console.log('fail: '+ errorThrown);
}
});
// button click to export results
var tableresults = $('#resultsTable').dataTable();
$("#btnExport").on('click', function(e)
{
e.preventDefault();
window.open('data:application/vnd.ms-excel,' +
encodeURIComponent(table[0].outerHTML));
});
}
Using all of the above, I can successfully export the results from the datatable. I can even use the filter search to drill down to a smaller data set, and export the results.
I was using the following fiddle: http://jsfiddle.net/donpayne/jzdjdo3z/
The problem I am having lies with the Show Entries dropdown of the datatable. Typically, the dropdown is set to 10. Whether you filter the search down or not, if the total record count is greater than the Show Entries dropdown, the Excel sheet will only return the total amount set in the dropdown.
You can test what I am talking about in the fiddle. Set the Show Entries dropdown to 10, then export to Excel. If you'll notice, there are 58 total records in that table. The Excel sheet will only return 10 records.
I need the to return all the records. If I have 2000 records, and the Show Entries dropdown is set to 10, I need the exported Excel sheet to include all 2000 records.
The same if I filter the search down to about 56 records; when I export to excel, I should have a total of 56 records on that spreadsheet, regardless of what the Show Entries dropdown is set to.
As stated, I referenced the code from the fiddle and altered it to fit my datatable.

I think the best thing to do is to remove the paging, then do the export, then turn the paging back on once it's done.
I made a couple minor changes:
$(function ()
{
var table = $('#example').DataTable();
$("#btnExport").click(function(e)
{
table.page.len( -1 ).draw();
window.open('data:application/vnd.ms-excel,' +
encodeURIComponent($('#example').parent().html()));
setTimeout(function(){
table.page.len(10).draw();
}, 1000)
});
});
Updated fiddle: http://jsfiddle.net/jzdjdo3z/176/
Page Length docs: https://datatables.net/reference/api/page.len()
Paging option docs: https://datatables.net/reference/option/paging
I'm not sure why initializing with dataTables vs DataTables made a difference, but it did. So keep an eye out for that.

Related

How can I use ajax.reload with jQuery datatable

I have a requirement to make a search form that will call a web api and populate a jQuery DataTable when a button is clicked. I don't want to load the form until the button is clicked so I have a separate button handler to call my post method. I was told I should use ajax.reload() with this in case someone has to search again to narrow the results but am having some trouble working it into my code. Can anyone assist me with my requirement? My code works fine as is but I would like to know if it can be done more efficiently. See my working code below.
<script>
var dataTable;
var resultsContainer = $('#ResultsContainer');
$(document).ready(function() {
dataTable = $('#SearchResultsTable').DataTable({
"columns": [
{ "data": "clientId" },
{ "data": "lastName" },
{ "data": "firstName" }
],
"language": {
"zeroRecords": '#Resource.NoRecordsFound'
},
"searching": false,
"lengthChange": false
});
});
$('#SearchButton').click(function (e) {
e.preventDefault();
RequestData();
});
function RequestData() {
$.post('#Url.Content("?handler=ClientSearch")', $('#ClientSearchForm').serialize(), function (data) {
ProcessResponse(data);
});
}
function ProcessResponse(data) {
dataTable.clear();
dataTable.rows.add(data);
dataTable.draw();
resultsContainer.addClass('d-block');
}
</script>
It looks like the DataTable ajax.reload method requires the URL for the data to be defined. In the example on https://datatables.net/reference/api/ajax.reload, they use the ajax option in the configuration object to set the URL:
var table = $('#example').DataTable( {
ajax: "data.json"
} );
Then calls to table.ajax.reload() will just pull the updated data in from data.json again. In your case, you're doing a POST to retrieve the data with the search form. So you'll either need to:
use a jQuery ajax object as the value of your DataTable ajax option (see https://datatables.net/reference/option/ajax#object); or
Set ajax.url (https://datatables.net/reference/api/ajax.url) with each search form submission
Hope that helps.

Displaying frequently changing data in a data table

I am using data tables to display dynamic data which keeps changing, the data is stored in an array and the array length keeps changing(might increase or decrease). I have set an interval of 1000 milliseconds to keep the data table updated. But since I am using paging, whenever I go to a different page rather from page 1, I am redirected back to page 1 automatically when the data table gets refreshed every 1000 milliseconds (one second). Is there any way which can help me to prevent this? I don't think we can stop the reloading of data table when data gets updated, but I am looking for ideas/hacks one can do to prevent this issue. One simple alternative is to use a button which when clicked refreshes the table rather than auto-refreshing with some interval.
fun1 = setInterval(() => {
if (names.length >= 0 ) {
var namesArray = names.map((device) => {
return Object.keys(device).map((key) => {
return device[key]
});
});
if (Table != undefined) {
Table.destroy();
}
Table = $('#ID1').DataTable({
destroy: true,
data: namesArray,
paging: true,
searching: false,
oLanguage: {
"sEmptyTable": " "
},
ordering: false,
info: false,
columns: [
{ title: "Name" },
{ title: "Age" },
],
});
}
}, 1000);
}

href in DataTables

I am trying to insert a href into one of my columns in DataTables but Im having some issues since I need the actual href to show my slug and then the full company name.
Example how it should be formatted: "company"
Real data: Toyota Cars.
I am using columns.render which seems to be the correct function but I can't wrap my head around how I can get 'company' between the a tags. The function does not even make use of the "data" specifier, instead it takes the data first in my ajax file which in this case is slug.
My DataTable.js file
ajax: '/api/datatable',
columns: [
{ data: 'slug' },
{ data: 'company' },
],
"columnDefs": [
{ targets: [0, 1], visible: true},
{ "targets": 0,
"data": "This doesnt even seem needed?",
"render": function ( data, type, row, meta ) {
return 'full company name';
}
}
],
I will go ahead and give an answer, based on the assumption that you are trying to merge values of 2 columns. If my assumption is not correct, please, update the question to clarify "expected vs actual" results.
You are using data parameter in render function. That parameter is based on the value you specified in columns.data. In your case (with target === 0), data will contain the value that DataTable got for { data: 'slug' } column.
If you want to merge values from different columns into one, then render function is the correct way to do it. However, instead of data, you should use row parameter, which contains all key-value fields for a row.
For example:
// ...
"targets": 0,
"data": null,
"render": function ( data, type, row, meta ) {
return ''+row.company+'';
// or whatever your row object key-value structure is
}
// ...

Select2 Multiple format to be passed to JSON

I am using the select2 multiple for search box. I am passing these data with JSON and saving it using ajax(JSON stringify).
I just need 2 variables passed, which is the ID(primary key, customized) and the Selection itself.
I managed to save it to the database when only 1 value is selected.
When selecting multiple values, in my console.log, I see something like this
{21,23,25,26}
which is the selection itself.
How do I get it show like this,
Object0->{id:1, selection:21}
Object1->{id:2, selection:23}
Object2->{id:3, selection:25}
Object3->{id:4, selection:26}
Below is the code I am using,
var nature = {
ubtBusinessInfo: businessId, // the primary key
ubtBusinessListing: nature.val() // here is selection
};
Here is the initialization of the select2,
nature
.select2({
allowClear: true,
placeholder: "Filter as you type",
minimumInputLength: 3,
multiple: true,
ajax: {
url: 'home/umkei/info/nature',
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return { q: term };
},
results: function (data, page) {
return { results: data };
},
cache: true
}
})
nature is defined from(I tried both as below)
var nature = $('[name=nature_business]') OR var nature = $(#nature_business);
I know it must have something to do with the nature.val() usage. Must have been something like array but I dont know how to differentiate/split those data to be key->value pairs.
Thank you.
I got this about last week and thought I'd share my solution.
var nature=[];
var splitnature = nature_business.val().trim().split(',');
var n;
for(n=0; n<=splitnature.length-1;n++){
nature.push({
ubtBusinessListing: splitnature[n],
ubtBusinessInfo: businessId
});
}

Fetch the specific column value from Datatable when user clicks

I have a datatable populated with aaData which is depicting the task created by users. Now, there is an action column in datatable which has two or three action buttons or logos like pdf - to view the user guide of that task, browse- link for the source code of the task and one is contributors logo which onclick should display the contributors for that particular task.
The aaData is of the following format which is populating the table
"aaData": [
[
"JSAG Home Page",
"JSAG Home page contains information about various POCs done",
"05/12/2012",
[
{
"displayValue":"Browse",
"link":"http://myTask.com/home",
"displayIcon" : "browselogo"
},
{
"displayValue":"Source Code",
"link":"svn/HomePage/trunk/",
"displayIcon" : "svnlogo"
},
{
"displayValue":"Audience Overview",
"link":"svn/Documents/Audience Overview.pdf",
"displayIcon" : "pdflogo"
},
{
"displayValue":"Contributors: ABC,XYZ",
"link":"#",
"displayIcon" : "people"
}
],
],
[
"Backlog",
"Backlog Forum application is designed to provide a platform for different groups to maintain backlog task items. ",
"25/08/2012",
[
{
"displayValue":"Browse",
"link":"http://mytask.com/BacklogApp",
"displayIcon" : "browselogo"
},
{
"displayValue":"Source Code",
"link":"svn/trunk/webapp-project/",
"displayIcon" : "svnlogo"
},
{
"displayValue":"Contributors: ABC",
"link":"#",
"displayIcon" : "people"
}
],
]
]
This format is for all datatables and contributors logo is there in all. What i wanted was, when user clicks the contributors icon, he should be able to see those contributors "ABC, XYZ, PQR".
I thought of fetching the action column data and then $each() the contributors array but i am not able to proceed with it.
How can i achieve this thing? How can i pick up the column value onclick because each datatable is being populated dynamically.
Please help.
Below is the code to populate a contributors div
$(document).on('click', '#contributor', function(contributors){
$.each(contributors, function(i, data) {
var ul_data = "<li><h3>"+ data+ "</h3></li>";
$("#contributors_div").append(ul_data);
});
}
$('#contributors_div').show();
});
How do i getrecentActdata as my contributors JSON array
Its going to be similar to this, provided you are declaring you datatable in the variable oTable
$(document).on('click', '#contributor', function(){
var aPos = oTable.fnGetPosition( $(this) );
console.log(aPos);
//if aPos returns an array in console, use first val at pos zero to get row data
var aData = oTable.fnGetData(aPos[0]);
console.log(aData);
// inspect your returned object, then tailor your $.each iteration
$.each( aData["contributors"], function(i, data) {
var ul_data = "<li><h3>"+ data+ "</h3></li>";
$("#contributors_div").append(ul_data);
});
}
$('#contributors_div').show();
});

Categories