Unable to load server side data using Scroller Extension jQuery Datatable - javascript

I am trying to render my Datatable with Scroller plugin in. Data is loading once but when scrolled further shows loading data only. Am I missing something ? I am trying to implement it in Salesforce Lightning. I have loaded Scroller Library v1.4.2 and DataTable v1.10.11
sessionTable = $j('#table-1').DataTable(
{
"info": true,
"searching": true,
"processing": false,
"dom": '<"div-pg"pi><"div-search"f><"div-tbl">t<"bottom-info"> ', // f search, p :- pagination , l:- page length
paging:true,
"order" : [[2,"asc"]],
"serverSide": true,
//scrollY: "200px",
scrollX : true,
"ajax": function (data, callback, settings) {
var allRecs = component.get("c.runQuery");
allRecs.setParams(
{
"request" : data ,
});
allRecs.setCallback(this, function(response)
{
console.log('in setCallback Populating Data' );
/*console.log(response.getReturnValue());*/
var state = response.getState();
if(state === 'SUCCESS' && response.getReturnValue != null)
{
//callback(JSON.parse(response.getReturnValue()));
//callback(sessionTable.rows.add(JSON.parse(response.getReturnValue())).columns.adjust().draw());
var resp = JSON.parse(response.getReturnValue());
console.log(resp);
setTimeout( function () {
callback( {
draw:resp.draw,
data: JSON.parse(resp.data),
recordsTotal: resp.recordsTotal,
recordsFiltered: resp.recordsTotal
} );
}, 200 );
});
$A.enqueueAction(allRecs);
},
scrollY: "300px",
scroller: {
loadingIndicator: true
},
scrollCollapse: true,
"language":
{
"emptyTable": "Loading Data"
},

The issue was with Salesforce Lightning, it was not returning the response.
Here is walkaround for this, we can force Salesforce to give response by adding following code after enqueuing:-
$A.enqueueAction(allRecs);
window.setTimeout(
$A.getCallback(function() {
console.log('Calling');
}), 200);

Related

checkbox not working in data table when paginated

I have a data table using jquery that display a list of data. I implemented a checkbox on the first column that I can check for each record or check all the records at once. If there is one checkbox or more selected then the approve and reject button would show up. While all these can work at the moment but if I select a next page and start checking any checkbox, the approve/reject button will not display.
Code:
<article class="col-xs-6 text-right">
<button id="approveButton" class="btn btn-success update-button" value="1">Approve</button>
<button id="rejectButton" class="btn btn-danger update-button" value="2">Reject</button>
</article>
var $table = $("#dt_basic").DataTable({
"scrollY": ($(window).height() - 270)+"px",
"scrollX": false,
"pageLength": ' . Yii::$app->params['settings']['listing_length'] . ',
"processing": true,
"serverSide": true,
"columnDefs": [{ "targets": [0, 6], "searchable": false, "orderable": false, "visible": true, className: "text-center-desktop" }],
"deferLoading": ' . $total . ',
"order": [],
"ajax": "' . Yii::$app->urlManager->createUrl(['xxxx']) . '",
"sDom": "<\'dt-toolbar\'<\'col-xs-12 col-sm-9\'f><\'col-sm-3 hidden-xs\'l>>r"+
"t"+
"<\'dt-toolbar-footer\'<\'col-sm-5 col-xs-12 hidden-xs\'i><\'col-xs-12 col-sm-7\'p>>",
"autoWidth" : true,
"preDrawCallback" : function() {
responsiveHelper_dt_basic = new ResponsiveDatatablesHelper($(\'#dt_basic\'), {tablet : 1024, phone : 480});
},
"rowCallback" : function(nRow) {
responsiveHelper_dt_basic.createExpandIcon(nRow);
},
"drawCallback" : function(oSettings) {
responsiveHelper_dt_basic.respond();
var pagination = $(this).closest(".dataTables_wrapper").find(".dataTables_paginate");
pagination.toggle(this.api().page.info().pages > 1);
}
});
$("#approveButton").hide();
$("#rejectButton").hide();
$("#masterCheck").on("click", function (e) {
if ($(this).is(":checked", true)) {
$(".subChk").prop("checked",true);
} else {
$(".subChk").prop("checked", false);
}
});
//This would not detect if checkbox is ticked in next page
$("input:checkbox").on("change",function(){
if ($("input:checkbox:checked").length > 0) {
$("#approveButton").show();
$("#rejectButton").show();
} else {
$("#approveButton").hide();
$("#rejectButton").hide();
}
});
$(".update-button").on("click", function(e) {
e.preventDefault();
var status = $(this).val();
let allVals = [];
$(".subChk:checked").each(function() {
allVals.push($(this).attr("id"));
});
console.log(allVals);
let join_selected_values = allVals.join(",");
$.ajax({
url: "updatewithdrawbulk",
type: "UPDATE",
data: {
ids: join_selected_values,
type: status
},
success: function(data) {
location.reload();
},
error: function (data) {
alert("There is some error, please try again");
}
});
});
After going to next page, checking the master checkbox will work (checked all sub checkbox as well) and approve/reject button will show. My only issue is when I tick any checkbox individually, it will not show the buttons.
I was wondering if this is an issue with the code or jquery data table?
The issue is that when you are attaching these .on bindings - it will only attach for the elements that currently exist in the html to be found.
When your next set of rows are drawn - these do not have the events bound to them.
If you hook into the event callback that tells you when new rows have appeared - you should bind your events again so that these new rows work as expected.
In the sample I would expect this to be achieved within the drawCallback event.

how to destroy table and reinitialize same table with new updated data using Datatables Jquery plugin

I am using Datatables plugin and dynmically populating the table with the data returned from server. on different table draws the returned data has variable no of columns. On each table intilization the code is checking if there has been previous initializations and removes it before creating a new table with dynamic data, using this code:
if ( $.fn.dataTable.isDataTable( '#contracts_forecast' ) ) {
$('#contracts_forecast').DataTable().clear();
$('#contracts_forecast').DataTable().destroy();
$('#contracts_forecast tbody').empty();
$('#contracts_forecast thead').empty();
}
On the serverside I am manually editing the data and updating the database. When the database is updated with new data , I want to refresh the table so the change is reflected in the table. In order to do that I am using an POST SUBMIT event, which is triggered after the data is submitted to server and then call the function getDT(filter_product_code, filter_product_name) to update the table with new data
PROBLEM:
When the post submit event is triggered , it recalls the function getDT(filter_product_code, filter_product_name); and change is reflected. BUT THE NEW TABLE with UPDATED IS ADDED TO CURRENT TABLE WITHOUT THE OLD TABLE BEING DESTROYED Which leaves me with two same tables on screen
p.s I am assuming every time getDT() function is called it should check for if table is initialized and destroy it before creating a new one using the same
$(document).ready(function() {
$('#filter').click(function(){
var filter_product_code = $('#filter_product_code').val();
var filter_product_name = $('#filter_product_name').val();
if(filter_product_code == '' || filter_product_name == '')
{
alert('Select Both filter option');
}
var columns = [];
getDT(filter_product_code, filter_product_name);
function getDT(filter_product_code, filter_product_name) {
$.ajax({
serverSide: true,
type:'POST',
url: "/XXX/_fetch.php",
data: {filter_product_code: JSON.stringify(filter_product_code),
filter_product_name: JSON.stringify(filter_product_name)},
success: function (data) {
data = JSON.parse(data);
columnNames = Object.keys(data.data[0]);
for (var i in columnNames) {
columns.push({data: columnNames[i],
title: capitalizeFirstLetter(columnNames[i])});
}
if ( $.fn.dataTable.isDataTable( '#contracts_forecast' ) ) {
$('#contracts_forecast').DataTable().clear();
$('#contracts_forecast').DataTable().destroy();
$('#contracts_forecast tbody').empty();
$('#contracts_forecast thead').empty();
}
table = $('#contracts_forecast').DataTable({
data: data.data,
columns: columns,
dom: "Bfrtip",
select: true,
buttons: [
{ extend: "create", editor: editor },
{ extend: "edit", editor: editor },
{ extend: "remove", editor: editor }
],
"columnDefs": [
{
"targets": [0],
"visible": false,
"searchable": false
},
{ className: "tablecolumns", targets: "_all" },
]
} );
$('#contracts_forecast').on( 'click', 'tbody td:not(:first-child)', function (e) {
editor.inline( this );
} );
}
});
editor.on( 'postSubmit', function ( e, json, data, action, xhr ) {
getDT(filter_product_code, filter_product_name);
});
}
});
} );
I was doing a mistake by declaring the column variable outside function. Each time the function was called it was adding to already existing columns. So just needed to define column variable inside function.
getDT(filter_product_code, filter_product_name);
function getDT(filter_product_code, filter_product_name) {
var columns = [];
$.ajax({
serverSide: true,
// paging: true,
// retrieve:true,
type:'POST',

dropdown not being populated in filter toolbar in jquery grid

I have referred this link and also this one link Both are Oleg's solutions to the problem. I used the same solution but the drop down doesn't populate with the values except for 'All'
I placed the code in load complete and I see the values when you call the 'setSearchSelect' function but only 'All' shows up in the dropdown.
Here's the code-
setupGrid: function (grid, pager) {
$(grid).jqGrid({
datatype: 'local', // set datatype to local to not inital load data
mtype: 'GET',
url: swUrl + ptSearchDashboardUrl,
colNames: colNames,
colModel: colModel,
altRows: false,
pager: $(pager),
loadonce: true,
sortable: true,
multiselect: true,
viewrecords: true,
loadComplete: function (data) {
//setSearchSelect.call($grid, 'RequestType');
//setSearchSelect.call($grid, 'Country');
},
onSelectRow: function() {
var checkedIDs = $(this).jqGrid('getGridParam', 'selarrrow');
if (checkedIDs.length > 0)
$("#ReassignBtn").show();
else
$("#ReassignBtn").hide();
}
}).navGrid(pager, { add: false, edit: false, del: false }).trigger('reloadGrid', [{ current: true }]);
setSearchSelect.call($grid, 'RequestType');
setSearchSelect.call($grid, 'Country');
$grid.jqGrid("setColProp", "Name", {
searchoptions: {
sopt: ["cn"],
dataInit: function(elem) {
$(elem).autocomplete({
source: getUniqueNames.call($(this), "Name"),
delay: 0,
minLength: 0,
select: function(event, ui) {
var $myGrid, grid;
$(elem).val(ui.item.value);
if (typeof elem.id === "string" && elem.id.substr(0, 3) === "gs_") {
$myGrid = $(elem).closest("div.ui-jqgrid-hdiv").next("div.ui-jqgrid-bdiv").find("table.ui-jqgrid-btable").first();
if ($myGrid.length > 0) {
grid = $myGrid[0];
if ($.isFunction(grid.triggerToolbar)) {
grid.triggerToolbar();
}
}
} else {
// to refresh the filter
$(elem).trigger("change");
}
}
});
}
}
});
$(grid).jqGrid('filterToolbar', {stringResult:true, searchOnEnter:true, defaultSearch:"cn"});
}
This is from the UI - I can only see one option value even though there are many.
<td class="ui-search-input">
<select name="RequestType" id="gs_RequestType" style="width: 100%;">
<option value="">All</option>
</select>
</td>
The code which you use getUniqueNames which uses .jqGrid("getCol", columnName) to get the data from the column. On the other side you use datatype: 'local' to create empty grid. The calls setSearchSelect.call($grid, 'RequestType');, setSearchSelect.call($grid, 'Country'); and getUniqueNames.call($(this), "Name") will be made before the grid will be filled with data. Thus you fill set empty set of select elements.
I suppose that you change later the datatype to "json" or "xml" and reload the grid. Only after your get response from the server you will ba able to fill the select values. I would suggest you to use beforeProcessing, which will be called after loading the data from the server, but before processing of the data. You can modify getUniqueNames and setSearchSelect so that it get the data from the input data directly and calls setColProp. Finally you should call destroyFilterToolbar and call filterToolbar once more to create the filter toolbar with the current data.

Firefox ReferenceError:... is not defined issue

I'm using Datatables with server side processing, and i need to add some extra parameters to my query to do some filtering. This is how my setup looks like:
if($('#example').length) {
var oTable = $('#listings').dataTable({
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": ajax_url+'?action=load_table_data',
"fnServerParams": function ( aoData ) {
aoData.push( { "name": "filters", "value": get_table_filters() } );
}
});
var tableFilterArray = {};
//Setting up and changing the filters, etc...
function get_table_filters() {
return JSON.stringify(tableFilterArray);
}
}
The script works fine in Chrome, but fails to run in Firefox, gives me the following error:
ReferenceError: get_table_filters is not defined
Here is a demo: http://jsfiddle.net/HaXUR/3/
What am i missing here?
Move the get_table_filters out of the if statement
if($('#example').length) {
var oTable = $('#listings').dataTable({
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": ajax_url+'?action=load_table_data',
"fnServerParams": function ( aoData ) {
aoData.push( { "name": "filters", "value": get_table_filters() } );
}
});
var tableFilterArray = {};
}
function get_table_filters() {
return JSON.stringify(tableFilterArray);
}

kendoui: How to display foreign key from remote datasource in grid

i have a kendoui grid which list claims. one of the columns is lenders which is a foreign key reference to the lenders table. what i want is to be able to display the lender name in the grid instead of its id reference.
ive setup the lenders datasource as follows
var dsLenders = new kendo.data.DataSource({
transport: {
read: {
url: "../data/lenders/",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation === "read") {
return options;
}
}
}
});
and the grid looks like this
$("#gridClaims").kendoGrid({
dataSource: claimData,
autoSync:true,
batch: true,
pageable: {
refresh: true,
pageSizes: true
},
filterable: true,
sortable: true,
selectable: "true",
editable: {
mode: "popup",
confirmation: "Are you sure you want to delete this record?",
template: $("#claimFormPopup").html()
},
navigable: true, // enables keyboard navigation in the grid
toolbar: ["create"], // adds insert buttons
columns: [
{ field:"id_clm", title:"Ref", width: "80px;" },
{ field:"status_clm", title:"Status", width: "80px;" },
{ field:"idldr_clm", title:"Lender", values: dsLenders },
{ field:"type_clm", title:"Claim Type"},
{ field:"value_clm", title:"Value", width: "80px;", format:"{0:c2}", attributes:{style:"text-align:right;"}},
{ field:"created", title:"Created", width: "80px;", format: "{0:dd/MM/yyyy}"},
{ field:"updated", title:"Updated", width: "80px;", format: "{0:dd/MM/yyyy}"},
{ field:"user", title:"User" , width: "100px;"},
{ command: [
{text: "Details", className: "claim-details"},
"destroy"
],
title: " ",
width: "160px"
}
]
});
however its still displaying the id in the lenders column. Ive tried creating a local datasource and that works fine so i now is something to do with me using a remote datasource.
any help would be great
thanks
Short answer is that you can't. Not directly anyway. See here and here.
You can (as the response in the above linked post mentions) pre-load the data into a var, which can then be used as data for the column definition.
I use something like this:-
function getLookupData(type, callback) {
return $.ajax({
dataType: 'json',
url: '/lookup/' + type,
success: function (data) {
callback(data);
}
});
}
Which I then use like this:-
var countryLookupData;
getLookupData('country', function (data) { countryLookupData = data; });
I use it in a JQuery deferred to ensure that all my lookups are loaded before I bind to the grid:-
$.when(
getLookupData('country', function (data) { countryLookupData = data; }),
getLookupData('state', function (data) { stateLookupData = data; }),
getLookupData('company', function (data) { companyLookupData = data; })
)
.then(function () {
bindGrid();
}).fail(function () {
alert('Error loading lookup data');
});
You can then use countryLookupData for your values.
You could also use a custom grid editor, however you'll probably find that you still need to load the data into a var (as opposed to using a datasource with a DropDownList) and ensure that the data is loaded before the grid, because you'll most likely need to have a lookup for a column template so that you're newly selected value is displayed in the grid.
I couldn't quite get ForeignKey working in any useful way, so I ended up using custom editors as you have much more control over them.
One more gotcha: make sure you have loaded your lookup data BEFORE you define the column. I was using a column array that was defined in a variable I was then attaching to the grid definition... even if the lookup data is loaded before you use the grid, if it's defined after the column definition it will not work.
Although this post past 2 years, I still share my solution
1) Assume the api url (http://localhost/api/term) will return:
{
"odata.metadata":"http://localhost/api/$metadata#term","value":[
{
"value":2,"text":"2016-2020"
},{
"value":1,"text":"2012-2016"
}
]
}
please note that the attribute name must be "text" and "value"
2) show term name (text) from the foreign table instead of term_id (value).
See the grid column "term_id", the dropdownlist will be created if added "values: data_term"
<script>
$.when($.getJSON("http://localhost/api/term")).then(function () {
bind_grid(arguments[0].value);
});
function bind_grid(data_term) {
$("#grid").kendoGrid({
dataSource: ds_proposer,
filterable: true,
sortable: true,
pageable: true,
selectable: "row",
columns: [
{ field: "user_type", title: "User type" },
{ field: "user_name", title: "User name" },
{ field: "term_id", title: "Term", values: data_term }
],
editable: {
mode: "popup",
}
});
}
</script>
For those stumbling across this now, this functionality is supported:
https://demos.telerik.com/aspnet-mvc/grid/foreignkeycolumnbinding

Categories

Resources