Is it possible to not load data first time on page load? - datatables

I'm using the jquery DataTables plugin.
Is it possible to not load data first time?
I will load data later with different filters applied.

You could use the deferLoading Parameter and set it to 0.
This will delay the loading of data until a filter or sorting action happens.
$(document).ready(function() {
$('#example').dataTable( {
"processing": true,
"serverSide": true,
"deferLoading": 0,
"ajax": {
url:"scripts/server_processing.php",
'data': {
'dbName': 'willi'
}
}
});
});
More Info here (dataTables 1.10.0)

Related

Datatables responsive, set specific options

I am using DataTables with the responsive extension on our web application, but I have a question.
When the table is made responsive, it should hide the pagination option.
I tried this with "bLengthChange": false:
$(function () {
$("#table1").DataTable({
"language": {
"url": "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Dutch.json"
},
"order": [[1, "asc"]],
"bAutoWidth": false,
responsive: {
details: {
type: 'column'
},
"bLengthChange": false
},
columnDefs: [ {
className: 'control',
orderable: false,
targets: 0
} ],
});
});
However, this does not work. My target is that I can see the pagination amount dropdown menu on fullscreen, but that option should be hidden if responsive.
Can I add options like bLengthChange specific to the "responsive" state?
Can I add options like bLengthChange specific to the "responsive"
state?
No, you cannot. Try inspect $.fn.dataTable.Responsive.defaults again, as I believe you already have done. It does not give so much sense either, the responsive extension is an extension while lengthMenu is a core feature. If you want to hide the lengthMenu you would need to reinitialise the table or do something hackish that may or may not conflict with other features or other extensions. But you can do the hack yourself. Hook into the responsive-resize event and hide or show the lengthMenu according to the responsive status :
table.on( 'responsive-resize', function ( e, datatable, columns ) {
var $lengthMenu = $('.dataTables_length')
var count = columns.reduce( function (a,b) {
return b === false ? a+1 : a;
}, 0 );
if (count>0 && $lengthMenu.is(':visible')) $lengthMenu.hide()
if (count<= 0 && !$lengthMenu.is(':visible')) $lengthMenu.show()
} );
demo -> http://jsfiddle.net/v1dnxLkg/
Thank you.
Fixed it with this CSS:
#media screen and (max-width: 767px){
div.dataTables_wrapper > div.row > div > div.dataTables_length{
display: none;
}
}

jquery datatable column header not update properly

I try reuse 1 table with different amount of data based on different button click, I able to populate data successfully, but the problem is, the header did not populate correctly, I had debug and see the correct amount of column pass into table, but why it still retain the design from the 1st click? the 1st data from the 1st click have 3 column, but in the 2nd click, it still retain the same 3 column instead of 8 column? how to make the header populate correctly?
I try to destroy and recreate, but the code not working well if declare before the table create, any idea?
//if ($.fn.DataTable.fnIsDataTable($(selector)[0])) {
// $(selector).dataTable.fnClearTable();
// $(selector).dataTable.fnDraw();
//}
var oDataTable = $(selector).dataTable({
"sDom": _sDom,
"sPaginationType": "bootstrap",
"bDestroy": true,
"bServerSide": true,
"bFilter": true,
"bStateSave": true,
"bSort": tools,
"bAutoWidth": false,
"sAjaxSource": source,
"fnServerParams": function (aoData) {
aoData.push({ "name": "sParams", "value": params });
},
"bProcessing": true,
"oLanguage": {
"sLengthMenu": _displayLen
},
"aoColumns": cols
});
1st button click
2nd button click
Ok, found the answer, after fndestroy, I still need to remove header from table before recreate a new set of header
$(selector).find('thead tr th').remove();

Rails + Multiple DataTables + UI nested accordion

I'm using multiple similar dataTables within a nested UI accordion. While I've had no problem initializing multiple dataTables using the class-level selector, I'm having a problem getting the header and footer of any given table to align correctly.
I assume this is the same problem as a dataTable in a tab: the table (or header) needs to be redrawn once the accordion pane is displayed.
With initialization of a single table, or id-based initialization, I've had no problem using fnDraw or fnAdjustColumnSizing in a function to redraw a table on display. However, using mass-initialization, this approach doesn't work, because the specific displayed table can't be easily targeted.
I've tried to find a way of targeting only the currently displayed table for redraw, but haven't been successful.
Has anyone else dealt with this issue successfully? Thanks for any ideas....
I'm sure this is super-hacky, but the only way I could set it up so I could create a dynamic, multi-level accordion with a dataTable nested within each, was to actually nest the dataTable initialization within the accordion activation (at the level of the table), then mark the table div as initialized so it could be re-opened. Here's my js code:
$(document).ready(function(){
$(function() {
$('.accordion.second-level').bind('accordionactivate', function (event, ui) {
if (ui.newPanel.length) {
thisPanel = ('#'+ ui.newPanel.attr('id'));
if ($(thisPanel).hasClass('not_activated')) {
$(thisPanel + ' .dataTables_types').dataTable({
"bAutoWidth": false,
"bPaginate": false,
"bScrollCollapse": true,
"sScrollY": "295px",
"aaSorting": [[ 1, "desc" ]],
"sDom": "<'row'<'span10'f>>t<'row'<'span10'i>>",
"aoColumns": [
{ "bSortable": false },
null,
null,
{ "iDataSort": 4 },
{'bVisible': false},
{'bVisible': false},
null
],
"fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) {
/* Calculate the total transactions on this page */
var total = 0;
for ( var i=iStart ; i<iEnd ; i++ )
{
total += aaData[ aiDisplay[i] ][5]* 1;
}
var nCells = nRow.getElementsByTagName('th');
nCells[1].innerHTML = total;
$(nCells[1]).formatCurrency({negativeFormat:'%s-%n'});
}
});
$(thisPanel).removeClass('not_activated');
}
}
});
});
});
I'd still love to know if there's a better/more efficient way to do this, but this does work.

dataTables plugin: how to sort data initially (server-side processing)

I cannot make it to work properly.
I need on initial load to have my table sorted by 0-index column in 'desc'.
I've tried:
$(function() {
ordersTable = $('#orders').dataTable({
"sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
"sPaginationType": 'full_numbers',
"bDestroy": true,
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "{% url get_orders %}",
"aoColumnDefs":[
{"aTargets":[0], "asSorting": ["decs", "asc"]}
]
});
and what it does is sends "sSortDir_0 :'asc'" and displaying "asc" active after that.
How can it make it work? (without faking click on the column to resend the ajax)
Thanks
Ok, I guess I've found it: aaSorting and aaSortingFixed sets the initial sorting. (reference here)

sencha list paging plugin

I'm trying to use sencha touch's listpaging plugin. But there is almost no good( or bad ) documentation about how to use it and i'm confused.
When i activate the plugin in my list
this.myList = new Ext.List({
store: this.myStore,
plugins: [{
ptype: 'listpaging',
autoPaging: false
}],
itemTpl: '...'
});
a 'Load More' text and a loading image is added to the end of the list.
But i don't know how to configure my store to enable this plugin to be able to load more data.
App.regStore('MyStore', {
model: 'myModel',
proxy: {
type: 'ajax',
url: 'http://mydomain.com/json?howmany=10&page=1',
reader: {
type: 'json',
root: 'results'
}
}
});
App.stores.myStore = Ext.StoreMgr.get('MyStore');
How can i configure my store so when i tap "Load more", the store brings up page 2 and add them to the list automatically?
I've had a similar issue with the ListPaging plugin in SenchaTouch 2, and managed to sort out the 'load more' message behaviour when the end of the data set is reached.
This builds on what John Gordon has come up with (regarding specifying the pageSize and clearOnPageLoad config options), since these properties seem to be the same in Senchatouch 2. I haven't looked at SenchaTouch 1.x in detail. In SenchaTouch 2, all config options must be defined in a config property:
Ext.define('MessagingApp.store.MessageThreads', {
extend : 'Ext.data.Store',
requires: ['MessagingApp.model.MessageThread'],
config:
{
model: 'MessagingApp.model.MessageThread',
autoLoad: false,
clearOnPageLoad: false, // This is true by default
pageSize: 10, // This needs to be set for paging
proxy: {
type: 'jsonp',
pageParam: 'currentPage',
limitParam: 'pageSize',
url: APIURL + '/message-app-service/GetMessageThreads',
reader: {
type: 'json',
rootProperty: 'Data'
}
}
}
});
In the view, where we specify the plugins, we can override the 'load more' and 'no more records' messages:
{
xtype:'dataview',
store:'MessageThreads',
id:'threadList',
itemTpl:Ext.create('Ext.XTemplate',
'<!-- template markup goes here -->',
{
//custom helper functions here
}
),
plugins:[
{
xclass:'Ext.plugin.ListPaging',
autoPaging: true,
// These override the text; use CSS for styling
loadMoreText: 'Loading...',
noMoreRecordsText: 'All messages loaded'
}
]
}
The issue is that while our web service returns an array of records for a particular page, there is no overall total count property, which is needed for the plugin to determine when all records have been loaded. Hence as it is, the 'Load more' message will remain (issue #1 in the accepted solution). So in the init function of our controller, we have to attach an event handler for the load event on the store to hook into when a new page of data is received:
Ext.define('MessagingApp.controller.Messages',
{
extend: 'Ext.app.Controller',
config:
{
views: [
'MessageThreads',
// Other views referenced by this controller
],
stores: [
'MessageThreads'
],
refs:
{
// References to UI elements by selector...
}
},
init: function() {
// Other internal initialisation...
this.control(
{
// Selector-object pairs...
});
// Provide a means to intercept loads of each page of records
var threadStore = Ext.getStore('MessageThreads');
threadStore.addBeforeListener('load', this.checkForThreadListEnd, this);
},
// Remaining controller functions...
});
In the handler, we realise that we've reached the end of the data set when the number of records returned is less than the page size. If the total record count is a multiple of the page size, the last 'page' will have an empty array. Once the end of the data set has been identified, we update the totalCount config property of the store:
checkForThreadListEnd: function(store, records, isSuccessful) {
var pageSize = store.getPageSize();
var pageIndex = store.currentPage - 1; // Page numbers start at 1
if(isSuccessful && records.length < pageSize)
{
//Set count to disable 'loading' message
var totalRecords = pageIndex * pageSize + records.length;
store.setTotalCount(totalRecords);
}
else
store.setTotalCount(null);
},
// Other controller functions...
Because this is a 'before' event handler, this property will be crucially updated before the plugin decides whether to display the 'load more' or 'no more records' messages. Unfortunately, the framework doesn't provide a means to hide the 'no more records' message, so this would have to be done via CSS.
Hope this helps.
I'm having problems finding good documentation, too, but I can at least answer your question. You need to add pageSize to your store, clearOnPageLoad as well, if you want to not clear out what was already loaded. Her's my code:
Ext.regStore('publicresources', {
model: 'PublicResource',
autoLoad:false,
remoteFilter:true,
sortOnFilter:true,
pageSize: 15,
clearOnPageLoad: false,
sorters: [
{
property : 'distance',
direction: 'ASC'
}
]
});
My outstanding issues that I'm looking into are:
How to turn off the "More" element when there are no more records to load
How to detect that there are no more records to load, and where to put that detection code.
How to keep the list at the location that the user was at. Each load jumps back to the 1st item in the list
Good luck!
Remember also that this works only server side currently.
Forum thread http://www.sencha.com/forum/showthread.php?105193-Store-pageSize
In regards to the "load more vs. no more records" message -
If you are writing a custom proxy (example here A Sencha Touch MVC application with PhoneGap), you set the total records in the returned Operation.
If the total records are not yet known, you can do something like the below, where,
1) if you are returning the requested limit of records, set the total to something larger than the records the store will now hold
2) if returning < the requested limit of records, set the total to 1 (to force the "no more records message")
//return model instances in a result set
operation.resultSet = new Ext.data.ResultSet({
records: contacts,
//total : contacts.length,
total : contacts.length === operation._limit ? (operation._limit * operation._page +1) : 1,
loaded : true
});
//announce success
operation.setSuccessful();
operation.setCompleted();
//finish with callback
if (typeof callback == "function") {
callback.call(scope || thisProxy, operation);
}
Just to add what worked for me..
If your server returns a totalCount and you want to set it you can use the totalProperty in the reader
reader: {
type: 'json',
rootProperty: 'results',
totalProperty: 'resultCount'
}