How can I use ajax.reload with jQuery datatable - javascript

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.

Related

DataTables not showing data

Hi I have the following data but cannot get DataTables to display it:
const data = [{
"School":"Arsenal 2011",
"Group":{
"Name":"Previous",
"ParentGroup":{
"Name":"Arsenal",
"ParentGroup":{
"Name":"USA",
"ParentGroup":null
}
}
},
"GroupDisplayText":null,
"Publisher":"Abbot",
"PublishedDate":"2011",
"PublishersWebsite":"http://google.com/USA/ADW%202011/Arsenal%202011.pdf"
},
{
"School":"New York 2000",
"Group":{
"Name":"New York",
"ParentGroup":{
"Name":"USA",
"ParentGroup":null
}
},
"GroupDisplayText":null,
"Publisher":"DoE",
"PublishedDate":"2000",
"PublishersWebsite":"http://google.com/USA/New York%202000%20Tables.pdf"
}];
$(document).ready(function () {
$('#example').DataTable( {
"ajax": data
} );
}
I have created a project on playcode
https://playcode.io/470603
I am getting a datatables error
DataTables warning: table id=example - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1
I have checked the json and all is ok?
Thanks
$(document).ready(function () {
$('#example').DataTable( {
data:data // ajax for to make ajax request to retrieve data.
"columns": [ // also needs to specify column config to display it
{ "data": "School" },
]
} );
}
for javascript object use data instead.

jQuery datatables exporting data to Excel

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.

A datatable as the full-featured form element

The idea I'm trying to achieve is to embed the datatable into the form.
For now, the form acts as a container. So far there are no any issues, but the name property for the datatable if ignored. The datatable not belongs to the form elements. AFAICS the following configuration is pretty common:
{
view:"form",
elements:[
{ view:"text", name:"inp1", value:"Test input" },
{ view:"datatable", name:"formDT", autoConfig:true, data:grid_data }
]
}
http://webix.com/snippet/7b7a8f2e
But if in the dataForm.elements I see only inputs.
Ideally, I want to get and set the datatable selection through the form's setValues and getValues methods. Or do I need to write my own method to gather the data from the inputs and the datatable separately? Has anyone faced such task before? TIA.
Here a custom component draft inherit datatable but support getValue setValue in order to act as a form input :
webix.protoUI({
name: "datatableInput",
defaults: {
},
$init: function(config) {
},
// Define component value (used by form setValues)
setValue: function(value) {
console.log('setValue');
this.clearSelection();
if (value) this.select(value);
},
// Get component value (used by form getValues)
getValue: function() {
console.log('getValue');
var item = this.getSelectedItem();
if (item) return item.id;
}
}, webix.ui.datatable);
Updated snippet :
http://webix.com/snippet/f952f35e

select2: load asynchronous data through promise

What is the best place to load the options for select2 asynchronously. I want the same facility as ajax, but instead of select2 sending an ajax request, it needs to load the values asynchronously from a promise object. Below code works, in which I load the data in query, but which means every keystroke, invocation of select dropdown, it will query the data. so, what is the correct configuration?
code:
var items2 = [
{
"Id": 1,
"Name": "First"
},
{
"Id": 2,
"Name": "Second"
},
{
"Id": 3,
"Name": "Third"
}
];
var names = function () {
var deferred = $q.defer();
$timeout(function () {
deferred.resolve(items2);
}, 200);
return deferred.promise;
};
var query: function (query) {
var results = [];
names().then(function(d){
$.each(d, function(index, item){
results.push({
id: item.Id,
text: item.Name
});
});
query.callback({ results: results });
})
};
Edit
looking at the source, it looks like it only allows either ajax or local for querying data. It would have been ideal if local takes a function which returns the data. Am I on the right track? is there an easy way to patch it?
thanks
// exports
window.Select2 = {
query: {
ajax: ajax,
local: local,
tags: tags
}, util: {
debounce: debounce,
markMatch: markMatch,
escapeMarkup: defaultEscapeMarkup,
stripDiacritics: stripDiacritics
}, "class": {
"abstract": AbstractSelect2,
"single": SingleSelect2,
"multi": MultiSelect2
}
};
Edit2:
'local` indeed accepts a function. but it doesn't play nicely with remote data, as the data is received with a delay (async), drop down is not populated with the new data. I have to close and open the drop-down again. This is not intuitive for the user.
As far I see, select2 invokes an ajax call for each key stroke, and opening the select box. I can get the same behavior using query (with promise) as in the original question. I was expecting select2 loads the data once, then do rest locally (search, and further invocation till any data change). looks like this is not an option. I may just cache my results locally. Better answer welcome.

Data Tables get JSON from API without setting "aaData"

I am using Data Tables and I get my data like it is shown in example
$('.data-table').dataTable({
"bProcessing": true,
"sAjaxSource": "/api/item/list",
"aoColumns": [
{ "mData": "Title" },
{ "mData": "Price" }
]
});
However there is a problem, I need to take all my objects and wrap them in aaData for this to work like so
[HttpGet]
public dynamic List()
{
var items = _db.Items.OrderBy(x => x.ID);
var a = new {
aaData = items
};
return a;
}
And this is bad for obvious reason that I need to modify my back-end for this instead of returning plain-old JSON. I've tried setting aaData instead of sAjaxSource but got errors and it didn't worked. Any ideas on how can I fix this?
Instead of the property aaData, you can tell DataTables to use another property name with the sAjaxDataProp parameter. For example:
// Get data from { "data": { "inner": [...] } }
$(document).ready( function() {
var oTable = $('#example').dataTable( {
"sAjaxSource": "sources/data.txt",
"sAjaxDataProp": "data.inner"
} );
} );

Categories