Datatables plugin search specific column not working - html

I try to create the individual search field with this code.
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</head>
<body>
<h1>DataTables Server Side</h1>
Seacrch specific column : <input id="column3_search" type="text"/>
<table id="example" class="display nowrap" style="width:100%; background-color: black; color: white;">
<thead>
<tr>
<th>Column A</th>
<th>Column B</th>
<th>Column C</th>
<th>Column D</th>
</tr>
</thead>
</table>
</body>
<!-- DataTable Pagination-->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/dt-1.10.21/r-2.2.5/datatables.min.css"/>
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.21/r-2.2.5/datatables.min.js"></script>
</html>
<script>
$(document).ready(function() {
var table = $('#example').DataTable({
bProcessing: true,
bServerSide: true,
deferRender: true,
sPaginationType: "full_numbers",
lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]],
bjQueryUI: true,
sAjaxSource: 'load_table_data',
columns: [
{"data": "Column A"},
{"data": "Column B"},
{"data": "Column C"},
{"data": "Column D"}
]
});
$('#column3_search').on( 'keyup', function () {
table.columns(1)
.search( this.value )
.draw();
} );
} );
</script>
Which i specify the <input id="column3_search" type="text"/> to search field of column index 1, but when i do searching it not do any search just showing the processing for a second and done.
And when i remove the .column() out, and try to searching with this code.
$('#column3_search').on( 'keyup', function () {
table.columns(1)
.search( this.value )
.draw();
} );
It working normally by search all column in the table. So what a problem with this code and how can i fix it.
This is my table_schemas.
SERVERSIDE_TABLE_COLUMNS = [
{
"data_name": "A",
"column_name": "Column A",
"default": "",
"order": 1,
"searchable": True
},
{
"data_name": "B",
"column_name": "Column B",
"default": "",
"order": 2,
"searchable": True
},
{
"data_name": "C",
"column_name": "Column C",
"default": 0,
"order": 3,
"searchable": True
},
{
"data_name": "D",
"column_name": "Column D",
"default": 0,
"order": 4,
"searchable": True
}
]

You need to define the target and searchable property in column property.
columns: [
{"data": "Column A","targets":0,"searchable":true},
{"data": "Column B","targets":1,"searchable":true},
{"data": "Column C","targets":2,"searchable":true},
{"data": "Column D","targets":3,"searchable":true}
]
$("#column3_search").on("input", function (e) {
table.columns(1).search($(this).val()).draw();
});

If you want to display only it on your datatable you should add a filter and then draw :
$('#column3_search').on('keyup', function() {
let string = $(this).val();
table.columns(1).data().filter(function(value, index) {
return value === string ? true : false;
}).draw();
});

Related

Converting dropdown menu to select2

I am attempting to create a datatable where the user can filter the table using dropdown menus. The first dropdown menu "project_select" fills with all the unique values from a column of the data table. The second dropdown menu "hr_select" fills with values based on the user's selection from the "project_select" dropdown menu.
Currently, the dropdown menus are mapped to span elements in the html. I am looking to convert these span elements to select2.
This is my desired html code:
<label for="project_select"></label><select id="project_select" class="js-example-basic-single" style="width: 10%">
<option></option>
</select>
<label for="hr_select"></label><select id="hr_select" class="js-example-basic-multiple" multiple="multiple" style="width:15%">
<option></option>
</select>
However, when I try and replace the span elements with that desired HTML code.. it doesn't work.
This is my code: https://jsfiddle.net/dfahsjdahfsudaf/nL6q21g9/16/
Thanks in advance for any help!
I converted my comments to an answer for future visitors to this question:
The steps needed to convert your standard selects to "Select2" selects are:
Add the required libraries to the page:
<link href="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js"></script>
Give IDs to each of the current <select> elements:
select = $('<select id="project_s2"><option value=""></option></select>');
and:
select = $('<select id="hr_s2" multiple><option value=""></option></select>');
Use those IDs to initialize Select2:
$('#project_s2').select2();
$('#hr_s2').select2();
The end result is:
var dataSet = [{
"Project_Name": "A",
"ID": "65",
"HR": "0",
},
{
"Project_Name": "A",
"ID": "65",
"HR": "10",
},
{
"Project_Name": "B",
"ID": "65",
"HR": "0",
},
{
"Project_Name": "B",
"ID": "65",
"HR": "20",
},
{
"Project_Name": "C",
"ID": "65",
"HR": "20",
},
{
"Project_Name": "C",
"ID": "65",
"HR": "100",
},
];
$(document).ready(function() {
var table = $('#example').DataTable({
data: dataSet,
orderCellsTop: true,
columns: [{
data: "Project_Name"
},
{
data: "ID"
},
{
data: "HR"
}
],
initComplete: function() {
this.api().columns([0, 2]).every(function() {
var column = this;
var colIdx = column.index();
var node;
var select;
if (colIdx === 0) {
node = $('#project_select');
select = $('<select id="project_s2" style="width: 40%"><option value=""></option></select>');
} else {
node = $('#hr_select');
select = $('<select id="hr_s2" style="width: 20%" multiple><option value=""></option></select>');
}
select.appendTo($(node).empty())
.on('change', function() {
var val = $(this).val();
if (colIdx === 0) {
val = $.fn.dataTable.util.escapeRegex(val);
column.search(val ? '^' + val + '$' : '', true, false).draw();
rebuildPositionSelect();
} else {
var vals = val.map(x => $.fn.dataTable.util.escapeRegex(x)).join('|');
column.search(vals ? '^' + vals + '$' : '', true, false).draw();
}
});
column.data().unique().sort().each(function(val) {
select.append('<option value="' + val + '">' + val + '</option>')
});
});
$('#project_s2').select2();
$('#hr_s2').select2();
}
});
function rebuildPositionSelect() {
var select = $('#hr_select select').empty().append('<option value=""></option>');
var column = table.column(2, {
search: 'applied'
});
column.search('').draw();
column.data().unique().sort().each(function(val) {
select.append('<option value="' + val + '">' + val + '</option>');
});
}
});
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
<link href="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js"></script>
</head>
<body>
<div style="margin: 20px;">
<div>
<span>Project: </span>
<span id="project_select"></span>
<span> HR: </span>
<span id="hr_select"></span>
</div>
<br><br>
<table id="example" class="display dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Project_Name</th>
<th>ID</th>
<th>HR</th>
</tr>
</thead>
</table>
</div>
</body>
</html>
As mentioned in the comments, this is a very basic set-up for each Select2 drop-down.
To customize them further you can provide options - for example:
$('#project_s2').select2( {
theme: "classic",
placeholder: 'Select an option'
} );
Final Note:
The use of basic <span> elements in the above example, only minimal layout/styling may be insufficient for your needs. So, you will probably want to provide CSS customizations which provide a better overall layout. But those changes should not affect your Select2 elements.
For example, adding in style="width: 40%" (as shown above) makes a difference - but that may not be what you want, in your specific case.

Nested JSON string to Data Table

Please help. I'm unable to match JSON parsed values to customer name using Data tables. I was able to populate table column with contact info, but parsed data is identical for both accounts in the table created by code shown. Is there a better way to loop through the data so it displays correctly.
I've seen a few examples of doing this with a simple table, but I would like to keep the sorting capability of Data Tables if possible. Any help will be greatly appreciated.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Table 01</title>
</head>
<body>
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<table id="tableId" class="table table-condensed responsive"></table>
</body>
<script>
var data01 = [
{
"name": "EXAMPLE Mickey",
"due": "2018-11-22T19:00:00.000Z",
"labels": [
{
"name": "Salesperson_1",
"color": "green"
}
],
"pluginData": [
{
"value": "{\"billContact\":\"Mickey Mouse\",\"billCompany\":\"MM Clubhouse\"}",
"access": "shared"
}
]
},
{
"name": "EXAMPLE Carl",
"due": "2018-11-25T19:00:00.000Z",
"labels": [
{
"name": "Salesperson_2",
"color": "yellow"
}
],
"pluginData": [
{
"value": "{\"billContact\":\"Carl Grimes\",\"billCompany\":\"Rick's Group\"}",
"access": "shared"
}
]
}
];
$('#tableId').DataTable({
data: data01,
"columns": [
{"data": "name"},
{"data": "due"},
{"data": "labels.0.name"},
{"data": "pluginData.0.value"},
{"data": function(){
for (var i=0; i < data01.length; i++){
var values = data01[i].pluginData[0].value;
var parsedVal = JSON.parse(values);
var contact = parsedVal.billContact;
return contact;
//console.log(contact);
}
}}
]
});
</script>
</html>
When you pass a function to a column, an argument is passed to that function which represents one entry of your data. So there is no need to iterate over your data by yourself, jQuery is doing that for you.
$('#tableId').DataTable({
data: data01,
"columns": [
{"data": "name"},
{"data": "due"},
{"data": "labels.0.name"},
{"data": "pluginData.0.value"},
{"data": function (row){
let values = row.pluginData[0].value;
let parsedVal = JSON.parse(values);
let contact = parsedVal.billContact;
return contact;
}}
]
});
If you do the iteration by yourself, the function will terminate at the return statement. So everytime the function is called it just see the first entry and return it and stop at that point.

How can I parse column of .csv file instead of writing the values manually

I want to be able to represent a bar chart by using only two columns in my .csv file, I have written a temporary solution by writing manually the values of the columns.. But if I have more columns, or more values in every column it may become impossible to write it manually. I'd love to get some help on how to transform my code to read the columns from the .csv file, so far I've been able to get a single bar chart and wasn't able to further edit the code for using more columns to get a multiple bar chart. Also, after finding the code for multiple bar charts - it traversed on all the columns on the .csv file and it showed all the columns in the chart, then when I tried editing the for loop for just the first two columns, and it didn't work, so I decided to write it manually for now.
Question: How to read .csv columns for bar chart representation (just two columns) instead of writing the column's values manually as I did.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</head>
<body>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer",{
title:{
text: ""
},
axisX:{
title: "car type"},
axisY:{
title:"$",
interval: 5000,
},
data: [
{
type: "column",
yValueFormatString: "#.####",
showInLegend: true,
name: "DealerCost",
dataPoints: [
{ "label": "Regular", y: 27446.14286 },
{ "label": "Sports.car", y: 48473.16327 },
{ "label": "SUV", y: 31625.35},
{ "label": "Wagon", y: 26645.63333 },
{ "label": "Minivan", y: 25355.5 },
{ "label": "Pickup", y: 22616.75},
]
},
{
type: "column",
showInLegend: true,
name: "RetailPrice",
yValueFormatString: "#.####",
dataPoints: [
{ "label": "Regular", y: 29814.3591836735 },
{ "label": "Sports.car", y: 53387.06122 },
{ "label": "SUV", y: 34790.25},
{ "label": "Wagon", y: 28840.53333 },
{ "label": "Minivan", y: 27796.5 },
{ "label": "Pickup", y: 24941.375},
]
},
]
});
chart.render();
}
</script>
<div id="chartContainer" style="height: 100%; width: 50%;">
</body>
</html>

How To Total Sum Inside Of Array Values In Angularjs?

I am using MEAN stack in my application with AngularJS as my front-end. How to total sum inside of array values in angularjs , actually we have used ng-repeat inside of one more ng-repeat to fetch the value in table and I got the fetched value like 250 in Sprice then I'm expecting to totalsum the sprice value like as a ans= 250.
My Plunker.
We have used two ng-repeat to get the sprice values in table because sprice is in inside of the [array].
We need to calculate total sum of sprice of value in table.
We have filter functionality to calculate the totalsum of ng-module value if it is in without array.
Actually we dont' know how to use resultValue= in ng-repeat.
For example: sprice value is 250 in table means the totalsum value need to be in 250, if sprice value is 250 and 300 means expecting answer like 550.
Without array totalsum functionality: My Plunker
With array totalsum functionality: My Plunker
My Controller:
.filter('sumOfValue', function () {
return function (data, key) {
debugger;
if (angular.isUndefined(data) && angular.isUndefined(key))
return 0;
var sum = 0;
angular.forEach(data,function(v,k){
sum = sum + parseFloat(v[key]);
});
return sum.toFixed(2);
}
})
My Data:-
$scope.orders = [
{
"_id": "5836b64083d9ce0f0078eae8",
"user": {
"_id": "579bdf6123f37f0e00a40deb",
"displayName": "Table 1"
},
"__v": 8,
"total": "1824",
"ordercar": [],
"orderfood": [
{
"qty": "1",
"confirm": "placed",
"sprice": 250,
"price": 250,
"customise": "With Onion,Without Onion",
"name": "Baasha Pizza"
}
],
"phone": null,
"order_source": "",
"comment": "",
"payment_mode": "",
"nop": null,
"rating": null,
"bill": false,
"complete": false,
"laundry": false,
"clean": false,
"roomservice": false,
"napkin": false,
"waiter": false,
"water": false,
"name": "fgg",
"created": "2016-11-24T09:43:28.413Z",
"isCurrentUserOwner": true
}]
My Html:-
<table ng-table="tableParams" class="table table-bordered ">
<thead>
<tr>
<th rowspan="2">s.no</th>
<th rowspan="2"> sprice </th>
</tr>
</thead>
<tr ng-repeat="order in orders">
<td>{{$index + 1}}</td>
<td ng-repeat="ram in order.orderfood">{{ram.sprice }}</td>
</tr>
<tr>
<td>sum</td>
<td>{{resultValue | sumOfValue:'sprice'}}</td>
</tr>
</table>
*We expecting for total sum in array values.
Used ng-repeat:
<tr ng-repeat="order in orders">
<td>{{$index + 1}}</td>
<td ng-repeat="ram in order.orderfood">{{ram.sprice }}</td>
ng-repeat is not looping properly .. I fixed it .. Check below snippet and also i added one more array to it.......... let me know..
var app = angular.module('plunker', []);
app.filter('sumOfValue', function () {
return function (data, key) {
debugger;
if (angular.isUndefined(data) && angular.isUndefined(key))
return 0;
var sum = 0;
angular.forEach(data,function(v,k){
sum = sum + parseFloat(v[key]);
});
return sum.toFixed(2);
}
}).controller('MainCtrl', function($scope) {
$scope.orders = [
{
"_id": "5836b64083d9ce0f0078eae8",
"user": {
"_id": "579bdf6123f37f0e00a40deb",
"displayName": "Table 1"
},
"__v": 8,
"total": "1824",
"ordercar": [],
"orderfood": [
{
"qty": "1",
"confirm": "placed",
"sprice": 250,
"price": 250,
"customise": "With Onion,Without Onion",
"name": "Baasha Pizza"
},
{
"qty": "2",
"confirm": "placed",
"sprice": 250,
"price": 250,
"customise": "With Onion,Without Onion",
"name": "Baasha Pizza"
}
],
"phone": null,
"order_source": "",
"comment": "",
"payment_mode": "",
"nop": null,
"rating": null,
"bill": false,
"complete": false,
"laundry": false,
"clean": false,
"roomservice": false,
"napkin": false,
"waiter": false,
"water": false,
"name": "fgg",
"created": "2016-11-24T09:43:28.413Z",
"isCurrentUserOwner": true
}]
});
body {
font-size: 14px;
}
table
{
border-collapse:collapse;
}
table, td, th
{
border:1px solid black;
}
td{
padding: 2px;
}
.servicetaxinclusivetrue:before{
color: green!important;
content: "\f00c";
}
.servicetaxinclusivefalse:before{
color: red!important;
content: "\f00d";
}
.servicetaxexclusivetrue:before{
color: green!important;
content: "\f00c";
}
.servicetaxexclusivefalse:before{
color: red!important;
content: "\f00d";
}
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
</head>
<body ng-controller="MainCtrl">
<table ng-table="tableParams" class="table table-bordered ">
<thead>
<tr>
<th rowspan="2">s.no</th>
<th rowspan="2"> sprice </th>
</tr>
</thead>
<tbody ng-repeat="order in orders">
<tr ng-repeat="ram in resultValue=(order.orderfood)">
<td>{{$index + 1}}</td>
<td >{{ram.sprice }}</td>
</tr>
<tr>
<td>sum</td>
<td>{{resultValue | sumOfValue:'sprice'}}</td>
</tr>
</tbody>
</table>
</body>
</html>
Here you can call function using "ng-init", so that angularjs will call function before execution of "ng-repeat".
In that function you can perform iteration and calculate total and hold it in scope variable to display it.

DataTables with Codeigniter MYSQL query

I'm trying to display three data tables as shown on this page with the variant of getting the data from my database, as shown here.
I first tested the page with the static data (from arrays.txt - first link) and it worked fine. However I'm now struggling with the MYSQL data and the JSON.
An info message showing "Processing..." shows up but the tables stay empty.
My Javascript:
$(document).ready(function(){
$('a[data-toggle="tab"]').on( 'shown.bs.tab', function (e) {
$.fn.dataTable.tables( {visible: true, api: true} ).columns.adjust();
} );
$('table.table').DataTable( {
"processing": true,
"serverSide": true,
"ajax": {
"dataSrc": "Data", // Tried adding this but didn't help
"url": "/hireStaffController/getDataTable",
"type": "POST"
},
"columns": [
{ "data": "id_staff" },
{ "data": "name_english" },
{ "data": "name_french" },
{ "data": "position" },
{ "data": "efficiency" },
{ "data": "salary" }
]
} );
}
My controller:
public function getDataTable(){
$data = $this->staffModel->get_all_staff_DB();
echo json_encode($data);
}
My Model:
public function get_all_staff_DB(){
$query = $this->db
->select('*')
->from('game_staff')
->get();
return $query->result();
}
The JSON Response from Firebug seems correct:
[{
"id_staff": "1",
"name_english": "Ski patrol 1",
"name_french": "Pisteur secouriste 1",
"position": "skipatrol",
"efficiency": "50",
"salary": "1500"
}, {
"id_staff": "10",
"name_english": "Bus driver 2",
"name_french": "Chauffeur de bus 2",
"position": "driver",
"efficiency": "55",
"salary": "1380"
}]
Firebug throws this error:
TypeError: c is undefined
...iRecordsDisplay=parseInt(f,10);d=0;for(e=c.length;d<e;d++)N(a,c[d]);a.aiDisplay=...
^
So I've tried to add "dataSrc": "Data", in the Ajax, as described here but no luck, same error. WHat is this Data? I tried with a small "d" as well.
Can you see what is wrong?
My HTML code:
<div class="tab-pane active" id="tab-table1">
<table id="myTable1" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Extn.</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
</table>
</div>
<div class="tab-pane" id="tab-table2">
<table id="myTable2" class="table table-striped table-bordered" cellspacing="0" width="100%">
//same ...
</table>
</div>
try including "Data" as key to the echoed data:
public function getDataTable(){
$data = $this->staffModel->get_all_staff_DB();
echo json_encode(array('Data' => $data));
}
When you specify dataSrc as "Data", datatables looks for a "Data" property in the json returned by the ajax call, and uses that property as source for the table.
I hope the HTML table with is present there.
Try using ID instead of class.
Everything else you have done looks fine.
$('#ID').DataTable( {
"processing": true,
"serverSide": true,
"ajax": {
"url": "/hireStaffController/getDataTable",
"type": "POST"
},
"columns": [
{ "data": "id_staff" },
{ "data": "name_english" },
{ "data": "name_french" },
{ "data": "position" },
{ "data": "efficiency" },
{ "data": "salary" }
]
} );