I have a HTML table with QRcode as one of its column values; I use QRcode.min js library to convert the string to QRcode;
json = $.parseJSON(JSON.stringify(res.d));
// console.log('data ' , json);
$.each(json, function (i, item) {
// console.log(item.medicine);console.log(item.Medicine);
if (item.QrImg1 == null) {
td1 = $('<td>').text(' ');
} else {
td1 = $('<td>').qrcode({ width: 100, height: 100, text: item.QrImg1 })
}
if (item.QrImg2 == null) {
td2 = $('<td>').text(' ');
} else {
td2 = $('<td>').qrcode({ width: 100, height: 100, text: item.QrImg2 })
}
var $tr = $('<tr>').append(
$('<td style="width:30%">').text(item.Medicine),
$('<td>').text(item.BatchCode),
td1,
td2
).appendTo('#meds');
}
This is a pharmacy app, where in all the medicines along with their batch code(as QRCode) is displayed. They will have to do quick filter search on the medicine name so pagination wont help.
The issue is that I have around 6000+ row so while loading it takes time specially on a tablet. Is there some way I can get this loaded faster.
if you get the data one time from the server and you do search on client side from table then jquery.DataTables will help you filter rows https://datatables.net/
it has many options customize the view of table & functionality like sort / search / group
<html>
<head>
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css">
</head>
<body>
<table id="example">
<thead>
<tr><th class="site_name">Name</th><th>Url </th><th>Type</th><th>Last modified</th></tr>
</thead>
<tbody>
</tbody>
</table>
<script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.2.min.js"></script>
<script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
<script>
$("#example").dataTable({
"aaData":[
["Sitepoint","http://sitepoint.com","Blog","2013-10-15 10:30:00"],
["Flippa","http://flippa.com","Marketplace","null"],
["99designs","http://99designs.com","Marketplace","null"],
["Learnable","http://learnable.com","Online courses","null"],
["Rubysource","http://rubysource.com","Blog","2013-01-10 12:00:00"]
],
"aoColumnDefs":[{
"sTitle":"Site name"
, "aTargets": [ "site_name" ]
},{
"aTargets": [ 1 ]
, "bSortable": false
, "mRender": function ( url, type, full ) {
return '' + url + '';
}
},{
"aTargets":[ 3 ]
, "sType": "date"
, "mRender": function(date, type, full) {
return (full[2] == "Blog")
? new Date(date).toDateString()
: "N/A" ;
}
}]
});
</script>
</body>
</html>
Related
I am using basic column visibility and individual column searching (text inputs).
The problem is that when the user adds a previously-hidden column to the table, the text field box for that column does not appear. Thus, the user cannot filter that column.
Does anyone know how to enable filters for hidden columns as well? Ideally, this would not cause a byproduct of clearing the text in the other filters (if the user did enter text in the other filters).
Here is my filtering code:
<script type="text/javascript">
$(document).ready(function() {
// Setup - add a text input to each footer cell
$('#tableID tfoot th').each( function () {
var title = $(this).text();
if ((title != '') && !(title.includes("$"))) {
// Then the current column is *not* the Action column.
$(this).html( '<span style="color: #515151; font-size:15px;"><i>Filter</i></span> <br> <input type="text" style="margin-top:10px;" placeholder="'+title+'" /> ' );
}
} );
var table = $('#tableID').DataTable();
// Apply the search
table.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
});
} );
} );
</script>
I am using this line to hide the columns that I want to be hidden from view by default:
(table.column('.hideCol')).visible(false);
There's a custom column-visibility event in DataTables. So, you may revise your <input> elements visibility based on current status of the column.
E.g. you have <input> rendering function, like that:
//function to render input elements
const renderTfootInputs = () => {
//grab previous inputs into array
const prevInputs = [];
dataTable.columns().every(function(){
prevInputs.splice(this.index(), 1, $(`#example tfoot [colindex="${this.index()}"]`).val());
});
//purge <tfoot> row contents
$('#example tfoot tr').empty()
//iterate through table columns
dataTable.columns().every(function(){
//if the column is visible
this.visible() ?
//append corresponding footer <input>
$('#example tfoot tr').append(`<th><input colindex="${this.index()}" placeholder="${$(this.header()).text()}" value="${prevInputs[this.index()] || ''}"></input></th>`) :
true;
});
};
Than, you may call it upon column visibility changes:
$('#example').on('column-visibility.dt', renderTfootInputs);
Complete demo of this approach might look as follows:
//sample data source
const dataSrc = [
{id: 1, title: 'apple', cat: 'fruit'},
{id: 2, title: 'pear', cat: 'fruit'},
{id: 3, title: 'banana', cat: 'fruit'},
{id: 4, title: 'carrot', cat: 'vegie'},
{id: 5, title: 'eggplant', cat: 'vegie'}
];
//datatables initialization
const dataTable = $('#example').DataTable({
data: dataSrc,
dom: 'Bfrtip',
buttons: ['colvis'],
columns: ['id','title','cat'].map(header => ({title: header, data: header})),
columnDefs: [
{targets: 0, visible: false}
]
});
//append blank footer to the table
$('#example').append('<tfoot><tr></tr></tfoot>');
//function to render input elements
const renderTfootInputs = () => {
//grab previous inputs into array
const prevInputs = [];
dataTable.columns().every(function(){
prevInputs.splice(this.index(), 1, $(`#example tfoot [colindex="${this.index()}"]`).val());
});
//purge <tfoot> row contents
$('#example tfoot tr').empty()
//iterate through table columns
dataTable.columns().every(function(){
//if the column is visible
this.visible() ?
//append corresponding footer <input>
$('#example tfoot tr').append(`<th><input colindex="${this.index()}" placeholder="${$(this.header()).text()}" value="${prevInputs[this.index()] || ''}"></input></th>`) :
true;
});
};
//initial call of above function
renderTfootInputs();
//call that function each time upon column visibility changes
$('#example').on('column-visibility.dt', renderTfootInputs);
//individual search
$('#example').on('keyup', 'tfoot input', function(event){
dataTable.column($(event.target).attr('colindex')).search($(event.target).val()).draw();
});
tfoot input {
display: block;
}
tfoot th {
padding-left: 10px !important;
}
<!doctype html>
<html>
<head>
<script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script type="application/javascript" src="https://cdn.datatables.net/buttons/1.5.6/js/dataTables.buttons.min.js"></script>
<script type="application/javascript" src="https://cdn.datatables.net/buttons/1.5.6/js/buttons.colVis.min.js"></script>
<script type="application/javascript" src="test.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.5.6/css/buttons.dataTables.min.css">
</head>
<body>
<table id="example"></table>
</body>
</html>
I have worked with this small snippet to hide/Unhide the Individual Column Search, Integrated with Column Visibility Event of Datatables.
$('#table').on( 'column-visibility.dt', function ( e, settings, column, state ) {
columnv = settings.aoColumns[column].bVisible;
if(columnv === false){
$('#table').find("tr.filters th:eq('"+column+"')").hide();
}else{
$('#table').find("tr.filters th:eq('"+column+"')").show();
}
});
I have a sample JSON like this:
}
"vehicles":"4door",
"cars": {
"Toyota":"Camry",
"Ford":"Explorer",
"Nissan":"Altima",
"Jeep":"Wrangler"
},
"color":"red"
}
I'm trying to make an HTML table with 2 columns called something like "Make" and "Model" using the sample JSON with JQuery using the "cars" array out of the JSON without taking the other items vehicles and color. The "Make" would be the keys of the JSON and the "Model" would be the values of the keys. I'm trying to get it to look something like this below but in a table format. Any help or advice would be greatly appreciated.
Make Model
Toyota Camry
Ford Explorer
Nissan Altima
Jeep Wrangler
Use Object.keys which will give an array of keysThen you can iterate it and get the key value from the object and use template literals to create a row and finally append to the table
let cars = {
"Toyota": "Camry",
"Ford": "Explorer",
"Nissan": "Altima",
"Jeep": "Wrangler"
}
let getKeys = Object.keys(cars);
let row = '';
for (let i = 0; i < getKeys.length; i++) {
row += `<tr><td>${getKeys[i]}</td><td>${cars[getKeys[i]]}</td></tr>`
}
$('#carTable').append(row)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id='carTable'>
</table>
Use Object.keys to get an array of the cars and loop through them using forEach loop. Using append in jquery append the row to the table
var data = {
"vehicles": "4door",
"cars": {
"Toyota": "Camry",
"Ford": "Explorer",
"Nissan": "Altima",
"Jeep": "Wrangler"
},
"color": "red"
}
var str='';
Object.keys(data.cars).forEach(e => {
str+='<tr><td>' + e + '</td><td>' + data.cars[e] + '</td></tr>';
})
$('#data').append(str)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="data">
<tr>
<td>Make</td>
<td>Model</td>
</tr>
</table>
You can also create your entire html from the script
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var html = ""
var json = {
"vehicles":"4door",
"cars": {
"Toyota":"Camry",
"Ford":"Explorer",
"Nissan":"Altima",
"Jeep":"Wrangler"
},
"color":"red"
}
html = "<table><thead><th><td>Make</td><td>Model</td></th></thead><tbody>"
for(var x in json.cars){
html+= "<tr><td>"+ x +"</td><td>"+ json.cars[x] +"</td></tr>"
}
html+="</tbody></table>"
$("#main").append(html)
});
</script>
</head>
<body>
<div id="main"></div>
</body>
</html>
Here I seen json format was not correct also get jsonObject.KeyName hold in variable then loop json that holds variable.
var obj = {"Toyota":"Camry", "Ford":"Explorer", "Nissan":"Altima", Jeep":"Wrangler"};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var val = obj[key];
console.log(val);
}
}
After that you implement in html format.
var data = {
"vehicles": "4door",
"cars": {
"Toyota": "Camry",
"Ford": "Explorer",
"Nissan": "Altima",
"Jeep": "Wrangler"
},
"color": "red"
};
var cars = data.cars; // for better performance if large table
var tableData = Object.keys(cars).map(item => '<tr><td>' + item + '</td><td>' + cars[item] + '</td></tr>').join('');
$('#main>table').append(tableData)
<div id="main">
<table>
<tr>
<td>Make</td>
<td>Model</td>
</tr>
</table>
</div>
I want to make excel like cell system but dynamically, Where i have to select every cell individually.
My desired output:
If i have 2 and 10, the output will be like that(above image). 2 means 2 row and 10 means 10 columns. the 2 and 10 is from database then javascript/angularjs should make the table according to those values. The second thing is that i have to select every individual cell using javascript. For example, i want to select B7 and if i click on that cell, an alert box will be shown with the selected cell number.
In real i want to store some values regarding that cell. How can i make every cell clickable? Any suggestion? I prefer angularjs.
Edit:
Acually i want to make Yard graphical view. Staff will select cell and input goods weight(in bootstrap modal). Then save. Next time if a cell/slot has weight before, it will be in different color(red-means the cell/slot is already filled with goods) and if he click on that cell , all details will be shown regarding to that cell like weight. Database table will store yard_id,cell_id,weiight. How can make query to get details from database to have my cell filled with color and show details if the cell has details before?
Edit 2:
You make an object in factory to set value in cell :
database[createKey({
row: 'A',
column: 1
})] = 12;
Here row A and column 1 is red colored by default. But in real app, i will have data for some cells like:
[{"row":"A","column":1,"weight":100},
{"row":"A","column":2,"weight":200}
].
Then how can i set those value on specific cells and have different bg color?
I want to use this method( loadData() ) to set color(like the one you set-red color) in the cell those have value stored in database when page load for the first time :
function loadData() {
fakeHttp.get('api/weights').then(function (result) {
$scope.weights = result.data;
console.log(result.data)
});
};
I will pass json data in result.data parameter(given above).
...in real app, i will have data for some cells like:... how can i set those value on specific cells and have different bg color?
You can keep loadData the same and change $scope.getWeight to accommodate the format of the data. This takes a dependency on lodash's find, since that makes things more concise. If you don't want to do that you can replace _.find with your own find method that does the same thing - I'll leave that as an exercise for you :)
http://plnkr.co/edit/b0q4qTyNjQp7J2IB7ayf?p=preview
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.0.1/lodash.js"></script>
JavaScript
$scope.getWeight = function (row, column) {
if ($scope.weights) {
// See if there's a record with the row and column.
var record = _.find($scope.weights, {
row: row,
column: column
});
// Was a record found with the row and column?
if (record) {
// If so return its weight.
return record.weight;
}
}
};
Staff will select cell and input goods weight(in bootstrap modal). Then save. Next time if a cell/slot has weight before, it will be in different color(red-means the cell/slot is already filled with goods) and if he click on that cell , all details will be shown regarding to that cell like weight...How can make query to get details from database to have my cell filled with color and show details if the cell has details before?
I didn't completely understand, but here's roughly what you could do for the parts I did understand. This assumes you have 3 endpoints - GET api/weights to get the weights; GET api/weight to get the weight for a single cell and POST api/weight to update a weight. You'll need to replace fakeHttp with $http and the actual url's. I don't know what Yard or Yard_id is.
http://plnkr.co/edit/aAiYbChTqmAwgky0WOJ3?p=preview
// TODO: Replace fakeHttp with $http
var module = angular.module('myApp', ['ui.bootstrap']);
module.controller('MainCtrl', function ($scope, $uibModal, fakeHttp) {
$scope.rows = [
'A',
'B'
];
$scope.columns = [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
];
$scope.select = function (row, column) {
var modalInstance = $uibModal.open({
templateUrl: 'myModal.html',
controller: 'ModalInstanceCtrl',
resolve: {
row: function () {
return row;
},
column: function () {
return column;
}
}
});
modalInstance.result.then(loadData);
};
$scope.getWeight = function (row, column) {
if ($scope.weights) {
var key = createKey({
row: row,
column: column
});
return $scope.weights[key];
}
};
loadData();
function loadData() {
fakeHttp.get('api/weights').then(function (result) {
$scope.weights = result.data;
});
};
function createKey(data) {
var key = {
row: data.row,
column: data.column
};
return JSON.stringify(key);
}
});
module.controller('ModalInstanceCtrl', function ($scope, row, column, fakeHttp, $uibModalInstance) {
$scope.row = row;
$scope.column = column;
fakeHttp.get('api/weight', {
row: row,
column: column
}).then(function (result) {
$scope.weight = result.data;
});
$scope.save = function () {
fakeHttp.post('api/weight', {
row: row,
column: column,
weight: $scope.weight
}).then(function () {
$uibModalInstance.close();
});
};
});
module.factory('fakeHttp', function ($q) {
var fakeHttp = {};
var database = {};
database[createKey({
row: 'A',
column: 1
})] = 12;
fakeHttp.get = function (url, data) {
if (url === 'api/weight') {
var key = createKey(data);
return $q.when({ data:
database[key]
});
} else if (url === 'api/weights') {
return $q.when({ data:
database
});
} else {
alert('invalid url: ' + url);
}
};
fakeHttp.post = function (url, data) {
if (url === 'api/weight') {
var key = createKey(data);
database[key] = data.weight;
return $q.when({});
} else {
alert('invalid url: ' + url);
}
};
return fakeHttp;
function createKey(data) {
var key = {
row: data.row,
column: data.column
};
return JSON.stringify(key);
}
});
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link data-require="bootstrap#3.3.7" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script data-require="angular.js#1.6.2" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
<script data-require="angular.js#1.6.2" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular-route.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.3/ui-bootstrap-tpls.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<table border="1" cellspacing="0">
<tbody>
<tr ng-repeat="row in rows">
<td ng-repeat="column in columns" style="width: 100px; cursor: pointer"
ng-style="{ background: getWeight(row, column) ? 'red' : '' }"
ng-click="select(row, column)">
{{row}}{{column}}
</td>
</tr>
</tbody>
</table>
</body>
</html>
myModal.html
<div class="modal-body">
Please enter weight for {{ row }}{{ column }}
<input type="text" class="form-control"
ng-model="weight" />
<button class="btn btn-primary"
ng-click="save()">Save</button>
</div>
How can i make every cell clickable?
Here's how to make every cell clickable in AngularJS.
http://plnkr.co/edit/XKa5WwjyYTugDZ744iWB?p=preview
Your question was very unclear. I couldn't tell what you wanted, exactly.
JavaScript:
module.controller('MainCtrl', function($scope) {
$scope.rows = [
'A',
'B'
];
$scope.columns = [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
];
$scope.select = function(row, column) {
if ($scope.selectedRow === row && $scope.selectedColumn === column) {
$scope.selectedRow = undefined;
$scope.selectedColumn = undefined;
} else {
$scope.selectedRow = row;
$scope.selectedColumn = column;
}
};
});
HTML:
<body ng-controller="MainCtrl">
<table border="1" cellspacing="0">
<tbody>
<tr ng-repeat="row in rows">
<td ng-repeat="column in columns" style="width: 100px; cursor: pointer"
ng-click="select(row, column)"
ng-style="{ background: row == selectedRow && column == selectedColumn ? 'yellow' : 'none' }">
{{row}}{{column}}
</td>
</tr>
</tbody>
</table>
<br>
Selected (row, column):
<br>
({{selectedRow || 'undefined'}}, {{selectedColumn || 'undefined'}})
</body>
I am using datatables. Trying to use select and keytable features together. Please see this jsfiddle.
$(document).ready(function() {
$('#data-table')
.DataTable({
"select": {
"style": "os"
},
"keys": true
}).on('key-focus', function() {
$('#data-table').DataTable().row(getRowIdx()).select();
})
.on('click', 'tbody td', function() {
var rowIdx = $('#data-table').DataTable().cell(this).index().row;
$('#data-table').DataTable().row(rowIdx).select();
}).on('key', function(e, datatable, key, cell, originalEvent) {
if (key === 13) {
var data = $('#data-table').DataTable().row(getRowIdx()).data();
$("#output").html("Code: " + data[0] + ". Description: " + data[1]);
}
});
});
function getRowIdx() {
return $('#data-table').DataTable().cell({
focused: true
}).index().row;
}
It almost works perfect except when press key down it doesn't unselect the first row that I clicked. It acts like as if I have pressed the shift key.
My second problem that when I press enter it shows the first column data but I need to show the row id.
I would appreciate a lot if you could help me to solve these two problems
you need to use deselect() all rows before select()
also keep a reference of $('#data-table').DataTable() as table instead of calling it everytime.
$(document).ready(function() {
var shiftKey, ctrlKey, table = $('#data-table').DataTable({
select: { style: 'os' },
keys: true
}).on('key-focus', function() {
if(!shiftKey && !ctrlKey) table.rows().deselect();
table.row(getRowIdx()).select();
})
.on('key', function(e, datatable, key, cell, originalEvent) {
if (key === 13) {
var data = table.row(getRowIdx()).data();
$('#output').html('Code: ' + data[0] + '. Description: ' + data[1]);
}
});
function getRowIdx() {
return table.cell({ focused: true }).index().row;
}
$(document).on('keyup keydown', function(e){
shiftKey = e.shiftKey;
ctrlKey = e.ctrlKey;
return true;
});
});
table.dataTable th.focus,
table.dataTable td.focus {
outline: none !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdn.datatables.net/1.10.11/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="https://cdn.datatables.net/1.10.11/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/select/1.1.2/css/select.dataTables.min.css" rel="stylesheet" />
<script src="https://cdn.datatables.net/select/1.1.2/js/dataTables.select.min.js"></script>
<link href="https://cdn.datatables.net/keytable/2.1.1/css/keyTable.dataTables.css" rel="stylesheet" />
<script src="https://cdn.datatables.net/keytable/2.1.1/js/dataTables.keyTable.min.js"></script>
<div>Result: <span id="output"></span></div><br/>
<table id="data-table" class="display compact articulos table0">
<thead><tr><th>Code</th><th>Description</th></tr></thead>
<tbody>
<tr id="1001"><td>1</td><td>Description 1</td></tr>
<tr id="1002"><td>2</td><td>Description 2</td></tr>
<tr id="1003"><td>3</td><td>Description 3</td></tr>
<tr id="1004"><td>4</td><td>Description 4</td></tr>
<tr id="1005"><td>5</td><td>Description 5</td></tr>
</tbody>
</table>
I'm using jQuery DataTables plugin to show the records from my database. In my database I have this table named size and it contains varchar datatype that stores file sizes so here are samples of what I have
When displayed in my tables I have this button that is supposed to sort the file sizes into asc or desc order but it does not sort the records properly say for example this one
my code right now to sort the filesize looks like this
$("#sortfilesize").click(function() {
if(checkb ==0){
oTable.order( [ 5, 'asc' ] );
checkb = 1;
}else{
oTable.order( [ 5, 'desc' ] );
checkb = 0;
}
oTable.draw();
});
update
i have downloaded file-size.js then when initializing my detail table it looks like this
<script type="text/javascript">
$(document).ready(function(){
$('#detailTable').DataTable({
bPaginate: false,
"columnDefs": [{ "type": "file-size", "targets": 5 }],
"aoColumnDefs": [{ "bVisible": false, "aTargets": [1,6,7,8,9,10,11] }],
"aaSorting": [[ 1, "asc" ]],
});
});
</script>
Any ideas on how to do this properly?
There is a DataTables sorting plug-in for that - File size. From the manual:
When dealing with computer file sizes, it is common to append a post
fix such as B, KB, MB or GB to a string in order to easily denote the
order of magnitude of the file size. This plug-in allows sorting to
take these indicates of size into account.
In addition to jQuery and DataTables library you need to include the latest plug-in script (see plug-in page for the up-to-date link).
Sample initialization code is shown below:
$('#example').DataTable({
"columnDefs": [
{ "type": "file-size", "targets": 1 }
]
});
Property targets indicates zero-based column index that contains file sizes.
See example below for demonstration.
$(document).ready(function() {
$('#example').DataTable({
"columnDefs": [
{ "type": "file-size", "targets": 1 }
]
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<link href="//cdn.datatables.net/1.10.7/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
<script src="//cdn.datatables.net/plug-ins/1.10.7/sorting/file-size.js"></script>
</head>
<body>
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Size</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Name</th>
<th>Size</th>
</tr>
</tfoot>
<tbody>
<tr>
<td>Small.mp3</td>
<td>9 KB</td>
</tr>
<tr>
<td>Normal.mp3</td>
<td>8 MB</td>
</tr>
<tr>
<td>Large.mp3</td>
<td>7 GB</td>
</tr>
<tr>
<td>Smallest.mp3</td>
<td>10 B</td>
</tr>
</tbody>
</table>
</body>
</html>
Here's my solution which works for KB and MB. You could account for GB with another elseif conditional. This works for data like this:
128 <- bytes
16KB <- 16 Kilobytes
1.4MB <- 1.4 Megabytes
Use my code in case you don't want to mess with the plugin or can't get it working.
jQuery.fn.dataTableExt.oSort['file-size-asc'] = function (a, b) {
if (a.includes('KB')) {
a = parseFloat(a.replace('KB','')) *1024;
} else
if (a.includes('MB')) {
a = parseFloat(a.replace('MB','')) *1024*1024;
}
if (b.includes('KB')) {
b = parseFloat(b.replace('KB','')) *1024;
} else
if (b.includes('MB')) {
b = parseFloat(b.replace('MB','')) *1024*1024;
}
return (( a > b ) ? 1 : -1);
};
jQuery.fn.dataTableExt.oSort['file-size-desc'] = function (a, b) {
if (a.includes('KB')) {
a = parseFloat(a.replace('KB','')) *1024;
} else
if (a.includes('MB')) {
a = parseFloat(a.replace('MB','')) *1024*1024;
}
if (b.includes('KB')) {
b = parseFloat(b.replace('KB','')) *1024;
} else
if (b.includes('MB')) {
b = parseFloat(b.replace('MB','')) *1024*1024;
}
return (( a > b ) ? -1 : 1);
};
$(document).ready(function() {
$("#my_data_table").dataTable( {
"pageLength": 25,
"aoColumns": [{"sType": "file-size"}],
"aaSorting": [[ 0, "desc" ]],
} );
});