Angular datatables with filter column width - javascript

I tried to set width for column in angular datatables with filters.
But width of the column not changed.
I try following
var columnsSpecification = [
{
type: 'text',
bRegex: true,
bSmart: true
}, {
type: 'text',
bRegex: true,
sWidth:"90px"}];
$scope.dtOptions = DTOptionsBuilder.newOptions()
.withBootstrap()
.withOption('scrollX', '700%')
.withOption('scrollY', height + 'px')
.withOption('oLanguage', { "sEmptyTable": " " })
.withOption('lengthMenu', [[-1, 1000, 100, 50, 25, 10], ['All', 1000, 100, 50, 25, 10]])
.withOption('paging', false)
.withOption('bInfo',false)
.withColumnFilter({
aoColumns:columnsSpecification
})
.withTableTools('/Content/DataTables/swf/copy_csv_xls.swf')
.withTableToolsButtons(['xls']);
In html file I tried this:
<table id="table-machines" datatable="ng" class="table table-striped" dt-options="dtOptions">
<thead>
<tr>
<th>Name</th>
<th style="width: 90px !important">Value</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="m in records>
<td>{{m.name}}</td>
<td style="width: 90px !important">{{m.Value}}</td>
</tr>
</tbody>
But Value column another zise rather I setted.
I'v found, that if there is not filter - all fine.
How can I set table width and preserve filters?

vm.dtColumns = [
DTColumnBuilder.newColumn('id').withTitle('ID').withOption('width', '5%')
];

You need to define the option width in your columnDefs option:
vm.dtColumnDefs = [
DTColumnBuilder.newColumn(1).withOption('width', '90px')
];
See this example.

Finally I've found the solution for avoiding datatables overwrite bootstrap columns width definitions:
$scope.dtOptions = DTOptionsBuilder.newOptions()
.withOption('autoWidth', false)
It was as easy as put that name and set to false... but it in the API doesn't appear to be available :(

Related

How to pass a variable to the dataset for a graph in chart.js?

I'm trying to create a graph in chart.js partly using data values that are static and given in the code, but also partly using data values given by the user. The value of the variable is subject to change because it is a sum of different parsed inputs from the user, and I'd like the chart to be able to update in real-time based on changes in the sum.
I understand that the below code returns an error because the variable classaverage is not defined, and also understand that it is possible to just repeat the calling of the class names and do the calculations all over again underneath the Chart() function. But, as the actual table is actually much larger than the one in the sample, I'd prefer to use a shorter method and not have to take up all of that space. Is this possible?
My code:
document.getElementById("jack").contentEditable = true;
document.getElementById("john").contentEditable = true;
document.getElementById("joe").contentEditable = true;
function myFunction() {
var jack2 = document.getElementById("jack").innerText;
var john2 = document.getElementById("john").innerText;
var joe2 = document.getElementById("joe").innerText;
var total2 = (parseInt(jack2) || 0) + (parseInt(john2) || 0) + (parseInt(joe2) || 0);
document.getElementById("total").innerHTML = total2;
}
var ctx = document.getElementById('totalchart').getContext('2d');
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Class', 'City', 'District'],
datasets: [{
label: 'Average Weight',
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: [classaverage, 130, 135]
}]
},
options: {
scales: {
yAxes: [{
display: true,
ticks: {
beginAtZero: true,
min: 0,
max: 200,
}
}]
}
}
});
table,
tr,
th,
td {
border: 1px solid black;
border-collapse: collapse;
font-style: Arial;
}
<table>
<tr class="cell">
<th>Person</th>
<th>Weight</th>
</tr>
<tr class="cell">
<td>Jack</td>
<td id="jack" oninput="myFunction()">120</td>
</tr>
<tr class="cell">
<td>John</td>
<td id="john" oninput="myFunction()">140</td>
</tr>
<tr class="cell">
<td>Joe</td>
<td id="joe" oninput="myFunction()">150</td>
</tr>
<tr class="cell">
<td>Total</td>
<td id="total"></td>
</tr>
</table>
<canvas id="totalchart"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
I'm not exactly sure what you are trying to achieve with your calculations if you update your answer I will be able to show you a working example, but to update the chart in real-time you will need to addData():
function addData(chart, label, data) {
chart.data.labels.push(label);
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
chart.update();
}
and possibly removeData():
function removeData(chart) {
chart.data.labels.pop();
chart.data.datasets.forEach((dataset) => {
dataset.data.pop();
});
chart.update();
}
unless you replaceData():
function replaceData(chart, data) {
chart.data.labels = Object.keys(data);
chart.data.datasets.forEach((dataset) => {
dataset.data = Object.values(data);
});
chart.update();
}
I have created an example fiddle showing implementation of addData
please refer to the docs

Display the total value of a column below the table PHP

i've set up a table that fetches data from my database and display it on a web page. but i don't know how to get the total value of one of my columns and display it below the table
php code.
foreach($result as $row)
{
$sub_array = array();
$sub_array[] = $row['order_id'];
$sub_array[] = $row['order_customer_name'];
$sub_array[] = $row['order_item'];
$sub_array[] = $row['order_value'];
$sub_array[] = $row['order_date'];
$sub_array[] = $row['session'];
$sub_array[] = $row['total'];
$data[] = $sub_array;
}
Table:
div class="container box">
<table id="customer_data" class="table table-bordered table-striped">
<thead>
<tr>
<th>Order ID</th>
<th>Customer Name</th>
<th>Programs</th>
<th>Price</th>
<th>Date</th>
<th>Session</th>
<th>Total Price</th>
</tr>
</thead>
</table>
</div>
Javacript code (dataTable): in javascript, there is a code to filter data based on date and can export table data
<script type="text/javascript" language="javascript" >
function fetch_data(is_date_search, start_date='', end_date='')
{
var dataTable = $('#customer_data').DataTable({
"processing" : true,
"serverSide" : true,
"order" : [],
"ajax" : {
url:"fetch.php",
type:"POST",
data:{
is_date_search:is_date_search, start_date:start_date, end_date:end_date
}
},
dom: 'lBfrtip',
buttons: [
'excel', 'csv', 'pdf', 'copy'
],
"lengthMenu": [ [10, 25, 50, -1], [10, 25, 50, "All"] ]
});
}
You can use Datatable column rendering options or other events to manipulate the data or calculating the total.
var globalDataSum=0;
var table =$('#example').DataTable( {
"columnDefs": [{
// The `data` parameter refers to the data for the cell (defined by the
// `data` option, which defaults to the column being worked with, in
// this case `data: 0`.
"render": function ( data, type, row ) {
globalDataSum+=data;
return data;
},
"targets": 0
}]
});
And listen to the data table drawn event. Then update the element
table.on( 'draw', function () {
$("#total").text(globalDataSum)
} );
If you want to use extensions of the data table to calculate the total, you can refer Data table Sum plugin

How to sort date with dd-MMM-yyyy hh:mm tt format in datatable

I'm currently working on datatable, I found my sorting for date column was not working. here was my screenshot
Here was my code
<table id="tbl" class="table table-small-font table-bordered table-striped">
<thead>
<tr>
<th> </th>
<th class="text-left">Dated</th>
<th class="text-left">Day</th>
<th class="text-center">Remarks</th>
<th class="text-center">State</th>
<th class="text-center"></th>
</tr>
</thead>
<tbody>
#{ IEnumerable
<PublicHoliday> PublicHolidays = (IEnumerable
<PublicHoliday>)ViewData["PublicHolidays"]; int Idx = 1; } #foreach (var i in PublicHolidays) {
<tr>
<td>#Idx</td>
<td>#i.Dated.ToString("dd-MMM-yyyy hh:mm tt")</td>
<td>#i.Dated.ToString("ddd")</td>
<td>#Html.DisplayFor(x => i.Remarks)</td>
<td>#i.ForStateName</td>
<td><a data-toggle="tooltip" title="Delete" onclick="DeleteRecord(#i.Id);"><span class="glyphicon glyphicon-remove"></span></a></td>
</tr>
Idx++; }
</tbody>
</table>
<script src="~/lib/jquery-ui-1.12.1/jquery-ui.min.js"></script>
<script src="~/js/jquery.dataTables.min.js"></script>
<script src="~/js/dataTables.bootstrap.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var tbl = $('#tbl').DataTable({
dom: "<'row'<'col-sm-6 col-xs-7'l><'col-sm-6 col-xs-7'f>>" + "rtip",
order: [
[0, "asc"]
],
pagingType: "numbers",
iDisplayLength: 50
});
});
</script>
the sort column does not work at all, and I can't find any plugin from datatable to use. anyone please help.. thanks in advance
I am not really sure that there is any plugin that supports date-dd-MMM-yyyy hh:mm tt format
So i have made modification to the plugin to support this format.
Here is the code for it.Load this piece of code after loading the datatable plugin
(function() {
var customDateDDMMMYYYYToOrd = function(date) {
var dateTime = date.split(' '),
dateObj = new Date(dateTime[0].replace(/-/g, ' ')),
time = "00:00",
type = "AM";
if (dateTime.length > 1) { // if time part and am/pm part is available
time = dateTime[1],
type = dateTime[2];
}
var splitTime = time.split(":"),
hours = type == "PM" ? Number(splitTime[0]) + 12 : Number(splitTime[0]),
minutes = Number(splitTime[1]),
seconds = 0,
milliseconds = 0;
return new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate(), hours, minutes, seconds, milliseconds);
};
// This will help DataTables magic detect the "dd-MMM-yyyy" format; Unshift
// so that it's the first data type (so it takes priority over existing)
jQuery.fn.dataTableExt.aTypes.unshift(
function(sData) {
"use strict"; //let's avoid tom-foolery in this function
if (/^([0-2]?\d|3[0-1])-(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)-\d{4}/i.test(sData)) {
return 'date-dd-mmm-yyyy';
}
return null;
}
);
// define the sorts
jQuery.fn.dataTableExt.oSort['date-dd-mmm-yyyy-asc'] = function(a, b) {
"use strict"; //let's avoid tom-foolery in this function
var ordA = customDateDDMMMYYYYToOrd(a),
ordB = customDateDDMMMYYYYToOrd(b);
return (ordA < ordB) ? -1 : ((ordA > ordB) ? 1 : 0);
};
jQuery.fn.dataTableExt.oSort['date-dd-mmm-yyyy-desc'] = function(a, b) {
"use strict"; //let's avoid tom-foolery in this function
var ordA = customDateDDMMMYYYYToOrd(a),
ordB = customDateDDMMMYYYYToOrd(b);
return (ordA < ordB) ? 1 : ((ordA > ordB) ? -1 : 0);
};
})();
The above code is the modification of date sort plugin(dd-mmm-yyyy).I have modified the customDateDDMMMYYYYToOrd function to fit this specific example
Add this so that the plugin would know what to be use when date is sorted
var tbl = $('#tbl').DataTable({
dom: "<'row'<'col-sm-6 col-xs-7'l><'col-sm-6 col-xs-7'f>>" + "rtip",
order: [[0, "asc"]],
pagingType: "numbers",
pageLength: 50,
columnDefs: [
{ type: 'date-dd-mmm-yyyy', targets: 1 } //add this part
]
});
You can find the list of sorting plugins available for datatable here
Note:
Please note that this plug-in is **deprecated*. The datetime
plug-in provides enhanced functionality and flexibility
Since 02-Jan-2017 12:00 AM and so on is valid RFC2822 dates, all you have to do is to set the column type to date :
columnDefs: [
{ targets: 1, type: 'date' }
]
Or if you have some odd values in the data, like null values you can just pass back the parsed value and sort as number, by that forcing correct sorting anyway (I guess that is the real problem) :
columnDefs: [
{ targets: 1,
type: 'num',
render: function(data,type) {
if (type == 'sort') return Date.parse( data ).valueOf()
return data
}
}
]
There is really no need for a special sorting plugin here. A third option is to set the unformatted date as data-sort attribute on the itself
<td data-sort="#i.Dated.ToString()">#i.Dated.ToString("dd-MMM-yyyy hh:mm tt")</td>
I use momentjs and lodash, it would like:
var records = [
["1", "28-Jan-2017 12:00 AM"],
["1", "28-May-2017 12:00 AM"],
["1", "28-Mar-2017 12:00 AM"]
];
records = _.map(records, record => {
record.push(moment(record[1], "DD-MMM-YYYY hh:mm A").unix());
return record;
});
$(document).ready(function() {
$('#example').DataTable( {
data: records,
columns: [
{ title: "id" },
{ title: "date" },
{ title: "ts"}
],
'columnDefs': [
{ 'orderData':[2] },
{
'targets': [2],
'visible': false
},
],
});
});
$(document).ready(function() {
$('#example').DataTable( {
data: records,
columns: [
{ title: "id" },
{ title: "date" },
{ title: "ts"}
],
'columnDefs': [
{ 'orderData':[2] },
{
'targets': [2],
'visible': false
},
],
});
});
Here is the jsFiddle
You can add the following sorting method to your options to sort according to date and time , specially if your time in 12 hour(AM/PM) format. I use the following code and it works for me:
$('#tableid').DataTable({
"order": [[, 'desc']],//order column in descending order.
"columnDefs": [
{ "type": "date", "targets": }//date column formatted like "03/23/2018 10:25:13 AM".
],
"pageLength": 25
});

Dynamically change datatables column width via API

I know we can set the columns width on a datatable via the columns.width option. But now I want to change that option on the xhr event.
Based on the ajax response I get from the server I want to hide/show a column and adjust the other columns width accordingly (they are all fixed size). Is there any way to achieve that via API?
I looked around all docs but seems it's not possible to achieve.
You cannot change settings once the dataTable is initalised. But if you are using column.width and you have turned autoWidth off, then the width of each column is easy to change. Here is an example :
var table = $('#example').DataTable({
autoWidth: false,
ajax: {
url: 'https://api.myjson.com/bins/avxod'
},
columns: [
{ data: 'name', width: 50 },
{ data: 'position', width: 50 },
{ data: 'salary', width: 50 },
{ data: 'office', width: 50}
]
})
$('#example').on('xhr.dt', function() {
$('#example thead th:eq(1)').width('400');
})
demo -> http://jsfiddle.net/cc7x6h64/
It works because column.width is injected into each <th> as style="width: xxx;"

Datatable is showing sum for all rows, instead of currently displayed rows

I have created datatable with jQuery which has seven columns. But it has approx. 24 rows. Initially, First eight rows will be displayed. There is "show more" link at the end of table. If user click on that link then eight more rows will be displayed.
The sixth column of datatable has "due-amount" values which has class "total-due-class". I am trying to display the sum of currently displayed rows of sixth column at the bottom of page. For example, initially eight rows will be displayed , so sum of only eight rows will displayed. When user will click on "show more" link then eight more rows will be displayed, so sum of sixteen rows will be displayed.
I wrote the code, but it always display sum of all 24 rows, instead of currently displayed rows.
Below is HTML code for datatable:
<table id="multiple-account-table" cellpadding="0" cellspacing="0" class="wide100">
<thead>
<tr>
<th><input type="checkbox" id="select-all-statement" value="" /></th>
<th id="acc-num">Account Number</th>
<th id="acc-name">Account Name</th>
<th id="alias-name">Alias</th>
<th id="dueDate-column">Due Date</th>
<th id="totalDue-column" >Total Due</th>
<th id="payment-column" class="black white-active-bg pad-bottom-0-5">Payment Amount</th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th>Total</th>
<th id="total-due-footer"></th>
<th id="payment-footer"></th>
</tr>
</tfoot>
</table>
Below is javascript code:
$( document ).ready(function() {
generateTable();
var sum = 0.00;
$(this).find(".total-due-class").each(function(){
var temp = $(".total-due-class").html();
sum += parseFloat(temp.substring(1));
});
$("#total-due-footer").html("$"+sum);
});
Any suggestion on this?
Below is code for jquery-datatable inside generateTable()
function generateTable(){
var index = -1;
$('#multiple-account-table').dataTable({
"data": [
{"accountNumber":"034-202553701","name":"Account 1","alias":"dummy1","dueDate":"10/19/2016","statementBalance":"34.60"},
{"accountNumber":"678-202553702","name":"Account 2","alias":"dummy 2","dueDate":"10/19/2015","statementBalance":"14.50"},
{"accountNumber":"989-202553703","name":"Account 3","alias":"Atlanta 3","dueDate":"10/19/2015","statementBalance":"15.50"},
{"accountNumber":"131-202553704","name":"Account 4","alias":"dummy4","dueDate":"10/19/2015","statementBalance":"15.50"},
{"accountNumber":"131-202553705","name":"Account 5","alias":"Atlanta 5","dueDate":"09/19/2016","statementBalance":"100.50"},
{"accountNumber":"131-202553706","name":"Account 6","alias":"Atlanta 6","dueDate":"12/19/2017","statementBalance":"18.50"},
{"accountNumber":"131-202553707","name":"Account 7","alias":"Atlanta 7","dueDate":"01/01/2015","statementBalance":"105.50"},
{"accountNumber":"131-202553708","name":"Account 8","alias":"Atlanta 8","dueDate":"10/19/2015","statementBalance":"15.50"},
{"accountNumber":"131-202553709","name":"Account 9","alias":"Atlanta 9","dueDate":"10/07/2015","statementBalance":"15.50"},
{"accountNumber":"131-202553710","name":"Account 10","alias":"Atlanta 10","dueDate":"10/19/2016","statementBalance":"15.50"},
{"accountNumber":"131-202553711","name":"Account 11","alias":"Atlanta 11","dueDate":"10/19/2015","statementBalance":"15.50"},
{"accountNumber":"131-202553712","name":"Account 12","alias":"Atlanta 12","dueDate":"04/04/2016","statementBalance":"115.50"},
{"accountNumber":"131-202553713","name":"Account 13","alias":"Atlanta 13","dueDate":"05/19/2015","statementBalance":"25.50"},
{"accountNumber":"131-202553714","name":"Account 14","alias":"Atlanta 14","dueDate":"03/19/2015","statementBalance":"135.50"},
{"accountNumber":"131-202553715","name":"Account 15","alias":"Atlanta 15","dueDate":"10/19/2017","statementBalance":"15.50"},
{"accountNumber":"131-202553716","name":"Account 16","alias":"Atlanta 16","dueDate":"10/19/2015","statementBalance":"08.50"},
{"accountNumber":"131-202553717","name":"Account 17","alias":"Atlanta 17","dueDate":"10/08/2015","statementBalance":"10.50"},
{"accountNumber":"131-202553718","name":"Account 18","alias":"Atlanta 18","dueDate":"09/19/2015","statementBalance":"15.50"},
{"accountNumber":"131-202553719","name":"Account 19","alias":"Atlanta 19","dueDate":"10/05/2015","statementBalance":"15.80"},
{"accountNumber":"131-202553720","name":"Account 20","alias":"Atlanta 20","dueDate":"10/19/2015","statementBalance":"39.50"},
{"accountNumber":"131-202553721","name":"Account 21","alias":"Atlanta 21","dueDate":"10/21/2015","statementBalance":"15.50"},
{"accountNumber":"131-202553722","name":"Account 22","alias":"Atlanta 22","dueDate":"10/19/2016","statementBalance":"15.50"},
{"accountNumber":"131-202553723","name":"Account 23","alias":"Atlanta 23","dueDate":"10/19/2015","statementBalance":"32.50"},
{"accountNumber":"131-202553724","name":"Account 24","alias":"Atlanta 24","dueDate":"12/29/2016","statementBalance":"105.50"}
],
"dom": 'it',
"pageLength": 8,
"language": {
"info": "Viewing accounts 1 - _END_ of _TOTAL_ ",
"emptyTable": "No records are available",
},
"columns": [
{"data": null},
{"data": "accountNumber"},
{"data": "name"},
{"data": "alias"},
{"data": "dueDate"},
{"data": "statementBalance"},
{"data": null}
],
"columnDefs": [
{className: "pad-md-left-p-10 pad-top-bottom-p-10 white-active-bg mouse-link", "targets": [0,1,2,3,4,5,6]},
{
'targets': 0,
'orderable': false,
'render': function(data, type, full, meta) {
++index;
return '<input type="checkbox" id="select-checkbox'+index+'" name="payment-checkbox" class="multi-checkbox"/>';
}
},
{
'targets': 1,
'render': function(data, type, full, meta) {
return '<span id="pdf" class="stmt-identifier">'+data+'</span>';
}
},
{
'targets': 4,
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
$(nTd).text(sData);
}
},
{
'targets': 5,
'orderable': false,
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
$(nTd).html('<span class="total-due-class">$'+sData+'</span>');
}
},
{
'targets': 6,
'searchable':false,
'orderable':false,
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
$(nTd).html('<span class="dollar-font">$<input type="number" id="payement-textbox" class="payment" value="" name="payment-textbox" /></span>');
}
}
],
"aaSorting": [[4, 'asc'], [5,'desc'], [1,'asc'] ]
}); //End of datatable function
$('#multiple-account-table_wrapper').append('<span id="md-table-load-more" style="display: none;" class="see-more text-center pad-1 link-enabled bold">Show More</span>');
updateShowMoreLink();
}
There is an example on the datatables site that does exactly what you want.
Check it out at Footer callback example
It will calculate the sum of all columns and the columns currently shown. You are also free to modify what and how it is displayed.
EDIT:
Adding the following part to the generation process of the table:
"footerCallback": function (row, data, start, end, display) {
var api = this.api(), data;
// Remove the formatting to get integer data for summation
var intVal = function (i) {
return typeof i === 'string' ?
i.replace(/[\$,]/g, '') * 1 :
typeof i === 'number' ?
i : 0;
};
// Total over this page
pageTotal = api
.column(5, {page: 'current'})
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
// Update footer
$(api.column(5).footer()).html('$' + pageTotal);
}
and removing following part from document ready handler
var sum = 0.00;
$(this).find(".total-due-class").each(function(){
var temp = $(".total-due-class").html();
sum += parseFloat(temp.substring(1));
});
$("#total-due-footer").html("$"+sum);
gives me the result shown below, which should what you desired:
Despide your code seems to be missing some parts, you can change your JS code to this:
$('#multiple-account-table tbody').find(".total-due-class").each(function(index, item){
var temp = $(item).text();
sum += parseFloat(temp.substring(1));
});
Which should match only rows in current view.
Check fiddle

Categories

Resources