Angular/Datables server-side processing - angularjs

I am trying to implement DataTables server-side processing/pagination for a table in angularjs. I have used the DataTables example but my table does not show. I am pretty sure I am missing one slight thing but can't figure it out....tried many things....
My HTML:
<div class="table-responsive">
<table id="consolidatedPageTable" class="table table-condensed table-striped table-bordered" >
<thead>
<tr>
<th >Source</th>
<th >Mailing Date</th>
<th >Status</th>
<th >CPI</th>
<th >User ID</th>
<th >Program</th>
<th >Customer Number</th>
<th >Customer Name</th>
<th >DL Date</th>
</tr>
</thead>
</table>
My controller:
app.controller('ConsolidatedController', function($scope,$rootScope,$http,$filter,$location,$routeParams) {
createTable();
$location.path('consolidated');
});
function createTable(){
$(function(){
var table = $('#consolidatedPageTable').dataTable({
"destroy": true,
"processing": true,
"serverSide": true,
"ajax": "scripts/consolidationTable.php",
"columnDefs": [
{
"targets": [9],
"visible": false,
"searchable": true
}
]
});
})
}
My php scipt (I replaced server specific information with XXX)
<?php
error_reporting(0);
$table = "consolidated";
$primaryKey = "customerNumber";
$columns = array();
$columns[] = array('db' => 'source' , 'dt' => 0);
$columns[] = array("db"=>"mailingDate","dt"=>1);
$columns[] = array("db"=>"status","dt"=>2);
$columns[] = array("db"=>"cpi","dt"=>3);
$columns[] = array("db"=>"userId","dt"=>4);
$columns[] = array("db"=>"shorttext","dt"=>5);
$columns[] = array("db"=>"customerNumber","dt"=>6);
$columns[] = array("db"=>"customerName","dt"=>7);
$columns[] = array("db"=>"dlDate","dt"=>8);
$sql_details = array("user" => "XXX","pass" => "XXX","db" => "XXX","host" => "XXX");
require("ssp.class.php");
echo json_encode(SSP::simple( $_GET, $sql_details, $table, $primaryKey, $columns ));
?>
I can run the php script by itself and it displays the correct data in the format shown in the dataTables example. In my application though, on the screen all I get is the header line and it does not appear to be in a dataTables looking format.
Can anyone see what could be causing no data to show?

I beleive the "columnDefs" object should be an array:
I console logged this after using the DTColumnDefBuilder included in the angular-datatables package. I could be wrong - I am having some difficulty with DT as well.

Related

Hide responsive datatable rows from left to right

I am working on an AngularJS solution and I am using datatables library to create responsive tables; Some of them should be displayed in Arabic, so when responsive columns must be hidden from left to right; How can I make that?
Below is my code:
<table datatable="ng" dt-options="vmAR.dtOptions" id="TableAR" class="table table-striped table-bordered">
<thead>
<tr>
<th>العمود 1</th>
<th>العمود 2</th>
<th>العمود 3</th>
<th ng-hide="true">test</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="object in List">
<td>{{object.param1}}</td>
<td ng-if="object.param2== '' " ng-bind="object.param3"></td>
<td ng-if="object.param2!= '' " ng-bind="object.param2"></td>
<td>{{object.param4}}</td>
<td ng-hide="true">{{object.param5}}</td>
</tr>
</tbody>
</table>
AngularJS code:
$scope.vmAR.dtOptions = DTOptionsBuilder.newOptions()
.withOption('paging', false)
.withOption('ordering', false)
.withOption('info', false)
.withOption('responsive', true);
Based on this link, I have tried the below, but nothing worked, it is still hiding columns from right to left:
$scope.vmAR.dtOptions = DTOptionsBuilder.newOptions()
//.withPaginationType('full_numbers')
.withOption('paging', false)
.withOption('ordering', false)
.withOption('info', false)
.withOption('responsive', true)
.withOption('columnDefs', [
{ responsivePriority: 1, targets: -1 }
]);
Any suggestion?
Update:
Even with the below code it didn't work:
$scope.vmAR.dtOptions = DTOptionsBuilder.newOptions()
//.withPaginationType('full_numbers')
.withOption('paging', false)
.withOption('ordering', false)
.withOption('info', false)
.withOption('responsive', true)
.withOption('columns', [
{ responsivePriority: 3 },
{ responsivePriority: 2 },
{ responsivePriority: 1 },
{ responsivePriority: 1 }
]);

How to display array in table using ng-repeat

Unlike other JSON data , I have simple arrays of two.
$scope.land = [ elephant, tiger, zebra ];
$scope.water = [ fish , octopus, crab];
I want to put up the array in table using ng-repeat. I tried this but data is not showing in proper format.
<table class="table table-dark">
<thead>
<tr>
<th scope="col">LAND</th>
<th scope="col">WATER</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="l in land track by $index">
<td>{{l}}</td>
<td>fish</td>
</tr>
</tbody>
</table>
EDIT:-
err in data showing vertical in table
enter image description here
new data :-
$scope.land = [ 'tiger in zoo', 'tiger in jungle', 'zebra'];
$scope.water = [ 'fish in pond'];
I think you are trying to display elements of two arrays next to each other (correct me if i'm wrong).
Here is a simple way to do that :
angular.module('myApp', [])
.controller('TestCtrl', function ($scope) {
$scope.land = [ 'tiger in zoo', 'tiger in jungle', 'zebra'];
$scope.water = [ 'fish in pond'];
$scope.combined = [];
var maxLength = ($scope.land.length > $scope.water.length) ? $scope.land.length : $scope.water.length;
//length is to be determined
for(var index = 0; index < maxLength ; index++) {
$scope.combined.push({
land: ($scope.land[index]) ? $scope.land[index] : '',
water: ($scope.water[index]) ? $scope.water[index] : ''
});
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="TestCtrl">
<table class="table table-dark">
<thead>
<tr>
<th scope="col">LAND</th>
<th scope="col">WATER</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in combined">
<td>{{item.land}}</td>
<td>{{item.water}}</td>
</tr>
</tbody>
</table>
</div>

How to collapse and hide in ng-repeat over table?

So I have a table where I need to show parent deals and on ng-show(clicking parent deal) I want to show child deals.
<table class="table table-hover">
<thead class="thead-dark">
<tr>
<th scope="col">Name</th>
<th scope="col">No_Of_Orders</th>
<th scope="col">Size</th>
<th scope="col">Book_Size</th>
<th scope="col">Remarks</th>
<th scope="col">Price_Guidance</th>
<th scope="col">CONTROL</th>
<th scope="col">Status</th>
<th scope="col">Current_Cut_Off</th>
<th scope="col">Tenor</th>
<th scope="col">Book</th>
<th scope="col">ORDCOLUMN</th>
<th scope="col">PKEY</th>
<th scope="col">Save</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="parentDeal in parentDeals track by $index" ng-click="childShow(parentDeal.PKEY)">
<td>{{parentDeal.Name}}</td>
<td>{{parentDeal.No_Of_Orders}}</td>
<td>{{parentDeal.Size}}</td>
<td>{{parentDeal.Book_Size}}</td>
<td>{{parentDeal.Remarks}}</td>
<td>{{parentDeal.Price_Guidance}}</td>
<td>{{parentDeal.CONTROL}}</td>
<td>{{parentDeal.Status}}</td>
<td>{{parentDeal.Current_Cut_Off}}</td>
<td>{{parentDeal.Tenor}}</td>
<td>{{parentDeal.Book}}</td>
<td>{{parentDeal.ORDCOLUMN}}</td>
<td>{{parentDeal.PKEY}}</td>
<td>{{parentDeal.Save}}</td>
<tr ng-repeat="childDeal in childDeals track by $index" ng-show = "childRowShow_{{childDeal.PKEY}}">
<td>{{childDeal.Name}}</td>
<td>{{childDeal.No_Of_Orders}}</td>
<td>{{childDeal.Size}}</td>
<td>{{childDeal.Book_Size}}</td>
<td>{{childDeal.Remarks}}</td>
<td>{{childDeal.Price_Guidance}}</td>
<td>{{childDeal.CONTROL}}</td>
<td>{{childDeal.Status}}</td>
<td>{{childDeal.Current_Cut_Off}}</td>
<td>{{childDeal.Tenor}}</td>
<td>{{childDeal.Book}}</td>
<td>{{childDeal.ORDCOLUMN}}</td>
<td>{{childDeal.PKEY}}</td>
<td>{{childDeal.Save}}</td>
</tr>
</tr>
</tbody>
</table>
This is the basic data:-
$scope.allDeals = [
{
"ORDCOLUMN":"2017-11-17T05:00:00.000000000Z",
"CONTROL":"N",
"PKEY":"UD0000000000720",
"Name":"rajat10 10:19",
"Tenor":"0Y",
"Size":0,
"Price_Guidance":"43%",
"Remarks":"-",
"Book_Size":20,
"Status":"Open",
"No_Of_Orders":2,
"Current_Cut_Off":2.3,
"Book":"Book#ReOffer",
"Save":"Edit"
},
{
"ORDCOLUMN":"2017-11-17T05:00:00.000000000Z",
"CONTROL":"Y",
"PKEY":"UD0000000000720",
"Name":"rajat10 10:19",
"Tenor":"Multi ...",
"Size":0,
"Price_Guidance":"-",
"Remarks":"-",
"Book_Size":20,
"Status":" Open",
"No_Of_Orders":2,
"Current_Cut_Off":2.3,
"Book":"Book#ReOffer",
"Save":"Edit"
},
{
"ORDCOLUMN":"2017-11-17T05:00:00.000000000Z",
"CONTROL":"N",
"PKEY":"UD0000000000720",
"Name":"rajat10 10:19",
"Tenor":"Perp",
"Size":0,
"Price_Guidance":"19%",
"Remarks":"-",
"Book_Size":0,
"Status":"Open",
"No_Of_Orders":2,
"Current_Cut_Off":2.3,
"Book":"Book#ReOffer",
"Save":"Edit"
}
....and so on
]
So, this data can be grouped by PKEY and parent object has control - "Y", child object has control - "N". Note:- There can be objects where there is only parent deal with no child deals.
In my app.js:-
$scope.parentDeals = $scope.allDeals.filter(function (item,index) {
return item.CONTROL == "Y";
});
$scope.childDeals = [];
$scope.childShow = function (PKEY) {
if($scope["childRowShow_"+PKEY]){
$scope["childRowShow_"+PKEY] = false;
}
else{
$scope.childDeals = $scope.allDeals.filter(function (item,index) {
if(item.PKEY == PKEY && item.CONTROL == "N"){
return item;
}
});
$scope["childRowShow_"+PKEY] = true;
}
};
Here, I am making two arrays:- parentDeals and childDeals.
Right now, I am applying ng-repeat on the separate row so, child deals are showing after all parent deals. Is there any way I can show them below the respective parent deals or can apply a different solution?
Yes, with ng-repeat-start and ng-repeat-end, we can explicitly specify the starting and ending for ng-repeat. So, instead of using the ng-repeat directive on one single DOM element, we can specify the ng-repeat-start and ng-repeat-end on any two DOM elements.
For eg.
<div ng-app="app">
<table ng-controller="TestController">
<tr ng-repeat-start="d in data">
<td><strong>{{d.name}}</strong></td>
</tr>
<tr ng-repeat-end>
<td>{{ d.info }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('app', []);
app.controller('TestController', function ($scope) {
$scope.data = [{
name: 'ABC',
info: 'Bangalore'
}, {
name: 'XYZ',
info: 'Mumbai'
}];
});
</script>

How can I export dynamic paginated data into PDF?

I'm struggling with export functionality in angularJS. I have a table consisting of dynamic data. As it contains a lot of data, I'm using dir-paginate. Pagination has worked for me fine. But when it comes to export, current page data is only exporting and not others.
Below is my table:
<table class="table table-striped" ng-if="worklist.finalarr.length>0">
<thead>
<th>S.No</th>
<th>User</th>
<th>Contact Name</th>
<th>Company Name</th>
<th>Phone</th>
<th>City</th>
</thead>
<tbody>
<tr dir-paginate="data in worklist.finalarr| filter:search|itemsPerPage:10" id="export">
<td>{{$index+1}}</td>
<td>{{data.empid}}</td>
<td>{{data.name}}</td>
<td>{{data.firmname}}</td>
<td>{{data.contact}}</td>
<td>{{data.city}}</td>
</tr>
</tbody>
</table>
<dir-pagination-controls max-size="10" direction-links="true" boundary-links="true" style="float:right" ng-if="worklist.finalarr.length>0">
</dir-pagination-controls>
Below is one of my attempts for exporting data using html2canvas (controller.js):
$scope.export = function(){
html2canvas(document.getElementById('export'), {
onrendered: function (canvas) {
var data = canvas.toDataURL();
var docDefinition = {
content: [{
image: data,
width: 500,
}]
};
pdfMake.createPdf(docDefinition).download("demo"+".pdf");
}
});
}
I know that html2canvas helps in capturing the webpage data that is only present on the view. So please help me out with an alternative.
Thanks in Advance

ng-repeat over an array of objects (how to get the object of the event clicked)

I have an array of objects that I am trying to display. I am passing in the object to the directive like this:
<td ng-repeat-start="(key,dept) in time" editable-field time="dept">{{times[$index][key].start}}</td>
<td ng-repeat-end>{{times[$index][key].end}}</td>
My table is structured like this:
Business Hours
<table class="table table-bordered">
<thead>
<tr>
<th></th>
<th style="vertical-align:top" scope="col" colspan="2">Sales</th>
<th style="vertical-align:top" scope="col" colspan="2" >Service</th>
<th style="vertical-align:top" scope="col" colspan="2">Parts</th>
<th style="vertical-align:top" scope="col" colspan="2">Accounting</th>
<th style="vertical-align:top" scope="col" colspan="2">Body Shop</th>
<th style="vertical-align:top" scope="col" colspan="2" >Other</th>
</tr>
</thead>
<tr ng-repeat="time in times">
<td>{{weekdays[$index]}}</td>
<td ng-repeat-start="(key,dept) in time" editable-field time="dept">td>
<td ng-repeat-end>td>
My controller:
.controller("businessHours", function($scope) {
$scope.weekdays = ["Sunday", "Monday", "Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];
$scope.departments = ["sales", "service","accounting","bodyshop","other"];
$scope.times = [];
$.each($scope.weekdays, function(index, value) {
var dayTimes = {};
$.each($scope.departments, function(index, value){
dayTimes[value] = {start: '5', end: '6'};
});
$scope.times.push(dayTimes);
});
})
The table I have built displays the business hours of a company. The user can click a cell inside the table and update the time. The problem I am facing is I am unable to get the object that the user has clicked. I would like to use the two way binding that I have setup in my scope using "=". I know there are other ways of getting this to work, but I am trying to follow the best practice. Can anyone please point me in the right direction.
fiddle: http://jsfiddle.net/kjodqdos/75/
<!--- Updated -->
I am able to get the event, but I am unsure on where the actual object is.
m.Event {originalEvent: MouseEvent, type: "click", timeStamp: 6290.860000000001, jQuery111109128661639738198: true, toElement: td.ng-binding.ng-scope.ng-isolate-scope…}
pass $event in ng-click action like ng-click="yourfunction($event)"
You can use event.srcElement.innerHTML to access the clicked cell, here's an example.I hope that it helps:
.directive("editableField", function($timeout){
return {
restrict: 'A',
template: '<td style="table-layout:fixed;" ng-click="showInputBox($event);hideSavedTime()">{{time.start}}</td>',
//weeksdays is empty here because of the isolated scope
replace:false,
scope: {
time: '='
},
controller: function($scope) {
console.log($scope.time);
$scope.showInputBox = function(event){
var cell = event.srcElement.innerHTML;
alert('Cell value - ' + cell);
}
}
}
})

Resources