Jquery Datatable drag and drop with row grouping - javascript

I have used jquery dataTable and I have a requirement as below:
If I drag the row (- BRAND NAME:....) then it should drag between rows only and with all it's content.
If I drag content of the row group then it should not overlap with other group.
Here is what I have done so far:
HTML:
<table id="example">
<thead>
<tr>
<th>Name</th>
<th>type</th>
<th>age</th>
</tr>
</thead>
<tbody id="sortable">
<tr id="1">
<td>Name</td>
<td>Type1</td>
<td>Age</td>
</tr>
<tr id="2">
<td>Name</td>
<td>Type1</td>
<td>Age</td>
</tr>
<tr id="3">
<td>Name</td>
<td>Type2</td>
<td>Age</td>
</tr>
<tr id="4">
<td>Name</td>
<td>Type2</td>
<td>Age</td>
</tr>
</tbody>
</table>
Jquery:
var table = $('#example').DataTable({
"searching": false,
"paging": false,
"info": false,
"order": [[0, "asc"]],
drawCallback: function (settings) {
var api = this.api();
var rows = api.rows({ page: 'current' }).nodes();
var last = null;
api.column(1, { page: 'current' }).data().each(function (group, i) {
if (last !== group) {
$(rows).eq(i).before(
'<tr class="groups"><td class="tdgroups" colspan="22" style="Cursor:hand !important;BACKGROUND-COLOR:rgb(237, 208, 0);font-weight:700;color:#006232;">' + '- BRAND NAME: ' + group + '</td></tr>'
);
last = group;
}
});
}
});
$("#sortable").sortable();
$("#sortable").disableSelection();
Link of Jsfiddle: DEMO

You can change your markup a little bit. Place each row group in separate <tbody>
and make those sortable.
var table = $('#example').DataTable({
"searching": false,
"bSort": false,
"paging": false,
"info": false,
});
$("#example>tbody").sortable({
items: "tr:not(.group-row)"
});
$("#example").sortable({
items: "tbody"
}).disableSelection();
table.dataTable tbody tr.group-row {
cursor: move;
background-color: rgb(237, 208, 0);
font-weight: 700;
color: #006232;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.9/js/jquery.dataTables.js"></script>
<link rel="stylesheet" href="http://cdn.datatables.net/1.10.0/css/jquery.dataTables.css">
<script type="text/javascript" src="//code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
<table id="example">
<thead>
<tr>
<th>Name</th>
<th>type</th>
<th>age</th>
</tr>
</thead>
<tbody>
<tr class="group-row">
<td>- BRAND NAME: Type 1</td>
<td></td>
<td></td>
</tr>
<tr id="1">
<td>NameA</td>
<td>Type1</td>
<td>Age</td>
</tr>
<tr id="2">
<td>NameB</td>
<td>Type1</td>
<td>Age</td>
</tr>
</tbody>
<tbody>
<tr class="group-row">
<td>- BRAND NAME: Type 2</td>
<td></td>
<td></td>
</tr>
<tr id="3">
<td>NameD</td>
<td>Type2</td>
<td>Age</td>
</tr>
<tr id="4">
<td>NameC</td>
<td>Type2</td>
<td>Age</td>
</tr>
</tbody>
</table>

Inspired by the answer by Munim Munna, I created a version that automatically modifies the table-structure by utilizing only javascript/jquery.
let table = $('#example').DataTable({
"searching": false,
"sort": false,
"order": [[1, "asc"], [0, "asc"]],
"paging": false,
"info": false,
drawCallback: function (settings) {
let api = this.api();
let rows = api.rows({ page: 'current' }).nodes();
if ($(rows).parent().is("tbody")) {
$(rows).unwrap();
}
let last = null;
let group_index = -1;
api.column(1, { page: 'current' }).data().each(function (group, i) {
if (last !== group) {
// make previous group sortable
if (last) {
$("#example > tbody[data-group='" + group_index + "']").sortable({
items: "tr.group-row",
containment: "#example > tbody[data-group='" + group_index + "']",
opacity: 0.75
});
}
group_index++;
// add group-header before new group
$(rows).eq(i).before(
'<tbody data-group="' + group_index + '"><tr class="group-header"><td colspan="3">' + '- BRAND NAME: ' + group + '</td></tr></tbody>'
);
last = group;
}
// modify row and append to tbody
$(rows).eq(i).attr('data-group', group_index).addClass('group-row').appendTo("tbody[data-group='" + group_index + "']");
});
// make last group also sortable
$("#example > tbody[data-group='" + group_index + "']").sortable({
items: "tr.group-row",
containment: "#example > tbody[data-group='" + group_index + "']",
opacity: 0.75
});
// make the tbody-elements sortable and disable selection in table
$("#example").sortable({
items: "tbody",
placeholder: "tbody-placeholder",
forcePlaceholderSize: true,
opacity: 0.75
})
.disableSelection();
}
});
table.dataTable tbody tr.group-header {
cursor: move;
background-color: rgb(237, 208, 0);
font-weight: 700;
color: #006232;
}
table.dataTable .tbody-placeholder {
display: table-row;
height: 50px;
}
<link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<link rel="stylesheet" href="http://cdn.datatables.net/1.10.0/css/jquery.dataTables.css">
<script src="https://cdn.datatables.net/1.10.9/js/jquery.dataTables.js"></script>
<table id="example">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr id="1">
<td>Name1</td>
<td>Type1</td>
<td>13</td>
</tr>
<tr id="2">
<td>Name2</td>
<td>Type1</td>
<td>42</td>
</tr>
<tr id="3">
<td>Name3</td>
<td>Type2</td>
<td>33</td>
</tr>
<tr id="4">
<td>Name4</td>
<td>Type2</td>
<td>17</td>
</tr>
</tbody>
</table>

Related

get selected multiple rows of checkbox by inserting no of rows in input box

How can i get selected checkbox of the datatable by inputing numbers
I'm trying to code a bootstrap data table which able to select check box of the rows by inserting no of rows in the input box
I dont have any idea about how to do it.
e.g: I typed number three in the input box then automatically checkbox table of two rows will get selected at [the beginning -> no problem]
<!DOCTYPE html>
<html><head>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.css">
<script src="//code.jquery.com/jquery.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.js"></script>
</head>
<body>
<div class="container text-center">
<label for="fname">insert number for select multiple check box</label>
<input type="number" id="selectcheckbox" name="selectcheckbox">
<table data-toggle="table"
data-classes="table table-hover table-condensed"
data-row-style="rowColors"
data-striped="true"
data-sort-name="Quality"
data-sort-order="desc"
data-pagination="true"
data-click-to-select="true"
>
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th class="col-xs-1" data-field="Product_Name" data-sortable="true">Product Name</th>
<th class="col-xs-1" data-field="Quality" data-sortable="true">Quality</th>
<th class="col-xs-6" data-field="Quantity" >Quantity</th>
</tr>
</thead>
<tbody>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Wheat</td>
<td>Good</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Rice</td>
<td>Good</td>
<td>100 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Rice</td>
<td>Good</td>
<td>100 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Maze</td>
<td>Fine</td>
<td>10 Packs</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
</tbody>
</table>
</div>
<script>
function queryParams() {
return {
type: 'owner',
sort: 'updated',
direction: 'desc',
per_page: 100,
page: 1
};
}
function rowColors(row, index) {
var classes = ['active', 'success', 'info', 'warning', 'danger'];
if (index % 2 === 0 && index / 2 < classes.length) {
return {
classes: classes[index / 2]
};
}
return {};
}
</script>
</body>
</html>
My actual code is here
<html>
<body>
<label for="fname">insert number for select multiple check box</label>
<input type="number" id="selectcheckbox" name="selectcheckbox">
<table class="table table-striped table-bordered" id="tbl">
<thead>
<tr>
<th>SELECT check box is here</th>
<th>Value</th>
<th>Value</th>
<th>Value</th>
<th>Value</th>
<th>Value</th>
<th>Value</th>
<th>Value</th>
<th>Value</th>
<th>Value</th>
<th>Value</th>
<th>Value</th>
<th>Value</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
$(document).ready(
function()
{
var table = $('#tbl').DataTable({
"columnDefs":
[
{
orderable: false,
className: 'select-checkbox',
targets: 0
}
],
destroy:true,
"fnRowCallback" :
function(nRow, aData, iDisplayIndex)
{
$("td:first", nRow).html(iDisplayIndex +1);
return nRow;
},
'select':
{
style: 'multi',
selector:'td:nth-child(1)'
},
'order': [[ 1, 'asc' ]],
});
$.ajax({
type:"POST",
url:"fetch_data.php",
data:'value='+value,
success: function(data)
{
if(data['error'] == '0')
{
console.log(data);
//set Finish Data
table.clear().draw();
for(i = 0; i < data['chemical_date'].length; i++)
{
table.row.add([
data['chemical_date'][i]['value'],
data['chemical_date'][i]['value'],
data['chemical_date'][i]['value'],
data['chemical_date'][i]['value'],
data['chemical_date'][i]['value'],
data['chemical_date'][i]['value'],
data['chemical_date'][i]['value'],
"<input type='text' value='' class='form-control' id='selectedqty"+i+"' onkeyup='sqty(this.id);' name='selectedqty"+i+"'/>",
"<input type='text' value='' class='form-control ' id='note"+i+"' name='note"+i+"' />",
"<input type='text' value='' class='form-control ' id='location"+i+"' name='location"+i+"' />",
'',
'',
''
]).draw(false);
}
}
}
})
});
</script>
</body>
</html>
fetch_data.php
<?php
$response = array();
if($_SERVER['REQUEST_METHOD']=='POST')
{
extract($_POST);
//Top data
$data = array();
$obj = array();
$sql = "some query here...";
$result = mysqli_query($db, $sql);
$chemical = array();
while ($row = mysqli_fetch_assoc($result))
{
//Finish Data
$row1 = array();
$row1['value'] = $row['value'];
$row1['value'] = $row['value'];
$row1['value'] = $row['value'];
$row1['value'] = $row['value'];
$row1['value'] = $row['value'];
$row1['value'] = $row['value'];
$row1['value'] = $row['value'];
array_push($chemical, $row1);
//Stock Data
}
$response['chemical_date'] = $chemical;
//Process Data
$response['error'] = "0";
}
else
$response['error'] = "1";
echo json_encode($response);
?>
You can use for-loop then inside this use :eq() to checked checkboxes according to index values .
Demo Code :
function queryParams() {
return {
type: 'owner',
sort: 'updated',
direction: 'desc',
per_page: 100,
page: 1
};
}
function rowColors(row, index) {
var classes = ['active', 'success', 'info', 'warning', 'danger'];
if (index % 2 === 0 && index / 2 < classes.length) {
return {
classes: classes[index / 2]
};
}
return {};
}
$("#selectcheckbox").on("change", function() {
$("[name=btSelectItem]").prop("checked", false) //unchecked..
//loop
for (let i = 0; i < $(this).val(); i++) {
//if that elemnt exist
if ($("[name=btSelectItem]:eq(" + i + ")").length > 0) {
$("[name=btSelectItem]:eq(" + i + ")").prop("checked", true) //checked it
}
}
})
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.css">
<script src="//code.jquery.com/jquery.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.js"></script>
<label for="fname">insert number for select multiple check box</label>
<input type="number" id="selectcheckbox" name="selectcheckbox">
<table data-toggle="table" data-classes="table table-hover table-condensed" data-row-style="rowColors" data-striped="true" data-sort-name="Quality" data-sort-order="desc" data-pagination="true" data-click-to-select="true">
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th class="col-xs-1" data-field="Product_Name" data-sortable="true">Product Name</th>
<th class="col-xs-1" data-field="Quality" data-sortable="true">Quality</th>
<th class="col-xs-6" data-field="Quantity">Quantity</th>
</tr>
</thead>
<tbody>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Wheat</td>
<td>Good</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Rice</td>
<td>Good</td>
<td>100 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Rice</td>
<td>Good</td>
<td>100 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Maze</td>
<td>Fine</td>
<td>10 Packs</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
<tr id="tr-id-2" class="tr-class-2">
<td></td>
<td>Sugar</td>
<td>Prime</td>
<td>200 Bags</td>
</tr>
</tbody>
</table>
Update 1 :
As you are using select-checkbox so plugin doesn't create checkbox itself they are handle by css code(adding checked) . So , after looking at html generated when we check any checkbox it adds selected class to tr so we can simply use addClass("selected") to make the row selected and checked.
Demo Code :
$(document).ready(function() {
var table = $('#example').DataTable({
columnDefs: [{
orderable: false,
className: 'select-checkbox',
targets: 0
}],
select: {
style: 'multi',
selector: 'td:nth-child(1)'
},
order: [
[1, 'asc']
]
});
$("#selectcheckbox").on("change", function() {
//remove selected class
$("#example tr").removeClass("selected")
for (let i = 0; i < $(this).val(); i++) {
//check if td there ...
if ($("#example td.select-checkbox:eq(" + i + ")").length > 0) {
//add selected class..
$("#example td.select-checkbox:eq(" + i + ")").closest("tr").addClass("selected") //try with `.click()` as well..
}
}
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.3/css/select.dataTables.min.css">
<script type="text/javascript" src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/select/1.3.3/js/dataTables.select.min.js"></script>
<input type="number" id="selectcheckbox" name="selectcheckbox">
<table id="example" class="stripe row-border order-column nowrap" style="width:100%">
<thead>
<tr>
<th></th>
<th>First name</th>
<th>Last name</th>
<th>Position</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>Garrett</td>
<td>Winters</td>
<td>Accountant</td>
</tr>
<tr>
<td></td>
<td>Ashton</td>
<td>Cox</td>
<td>Junior Technical Author</td>
</tr>
<tr>
<td></td>
<td>Cedric</td>
<td>Kelly</td>
<td>Senior Javascript Developer</td>
</tr>
<tr>
<td></td>
<td>Airi</td>
<td>Satou</td>
<td>Accountant</td>
</tr>
</tbody>
</table>
But, I am not sure if this is right solution :)
This should select the checkbox in the first TD of every row based on the number
$('#selectcheckbox').on('input', function() {
let num = $(this).val();
$('.table td:first-child input[type="checkbox"]').each(function (index) {
if (index <= num-1) $(this).prop("checked", true);
})
})
Here's one example in vanilla JS.
// Grab the input, and the input boxes
const input = document.querySelector('input');
const inputs = document.querySelectorAll('table input[type="checkbox"]');
// Add an event listener to the input to watch for changes
input.addEventListener('change', handleClick, false);
function handleClick() {
// Grab the number from the input box
// (it's a string so you have to coerce it to a number)
const number = Number(input.value);
// If the number is less than or equal to the
// number of input boxes...
if (number <= inputs.length) {
// ...loop through the boxes
// and check them if they match the number
// and uncheck them if they don't
for (let i = 0; i < inputs.length; i++) {
if (i < number) {
inputs[i].checked = 'checked';
} else {
inputs[i].checked = '';
}
}
}
}
<input type="number" />
<table>
<tbody>
<tr><td><input type="checkbox" /></td></tr>
<tr><td><input type="checkbox" /></td></tr>
<tr><td><input type="checkbox" /></td></tr>
<tr><td><input type="checkbox" /></td></tr>
</tbody>
</table>

How to add strikethrough to dropdown select box on jquery datatable and filter out on the basis of it

I have jquery Datatable as follows, and there is also a strikethrough text and I want to make it filterable, but upto now its not even being showing with strikethrough on the dropdown. My jquery datatable is as follows:
$(document).ready(function() {
var table = $("#example").DataTable({
"order": [ 1, "asc" ],
// "lengthMenu": [[ 100, 200, 500,-1], [ 100, 200, 500,'All']],
"pageLength": -1,
"lengthChange": false,
"bFilter": "false",
"searchable": false,
orderCellsTop: true,
"bPaginate": false,
"bInfo": false
});
$('.filterRow th').each( function (i) {
var title = $(this).text();
var select = $('<select><option value="">All</option></select>')
.appendTo( $(this).empty() )
.on( 'change', function () {
var term = $(this).val();
table.column( i ).search(term, false, false ).draw();
} );
let includedArr = [];
let colData = table.column( i ).data().unique().sort().each( function ( d, j ) {
if(d != ""){
select.append( '<option value="'+d+'">'+d+'</option>' );
}
});
} );
} );
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css">
<table id="example" class="display" style="width:100%">
<tbody>
<tr>
<td>N</td>
<td>101</td>
<td>1</td>
<td>01</td>
<td>10</td>
<td>20</td>
</tr>
<tr>
<td>N</td>
<td>102</td>
<td>1</td>
<td>02</td>
<td>(20)</td>
<td>20</td>
</tr>
<tr>
<td>N</td>
<td>103</td>
<td>1</td>
<td>03</td>
<td>
<del>10</del>
</td>
<td>20</td>
</tr>
</tbody>
<thead>
<tr>
<th rowspan="2">Bldg</th>
<th rowspan="2">Unit</th>
<th rowspan="2">Floor</th>
<th rowspan="2">Stack</th>
<th colspan="2">
Floor Level
</th>
</tr>
<tr>
<th>Floor 1</th>
<th>Floor 2</th>
</tr>
<tr class="filterRow">
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
</table>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
Here you can see on floor1 column with strikethrough text, but it is not showing on the dropdown value.
I have even tried to adding inline classes as:
if (d.indexOf("del") >= 0){
select.append( '<option style="text-decoration: line-through;" value="'+d+'">'+d+'</option>' );
}else{
select.append( '<option value="'+d+'">'+d+'</option>' );
}
But, this to does not seems to working. How could I add strikethrough text on select box, and make it filterable.
I am not sure if you can do that with select option. Maybe do it using jQuery and bootstrap instead by using ul and li -
$(document).ready(function() {
var table = $("#example").DataTable({
"order": [1, "asc"],
// "lengthMenu": [[ 100, 200, 500,-1], [ 100, 200, 500,'All']],
"pageLength": -1,
"lengthChange": false,
"bFilter": "false",
"searchable": false,
orderCellsTop: true,
"bPaginate": false,
"bInfo": false
});
$('.filterRow th').each(function(i) {
var title = $(this).text();
var select = $('<div class="dropdown" id="select' + i + '"><a aria-expanded="false" aria-haspopup="true" role="button" data-toggle="dropdown" class="dropdown-toggle" href="#"><span class="selectedvalue">All</span><span class="caret"></span><ul class="dropdown-menu"><li data-value="">All</li></ul></div>')
.appendTo($(this).empty());
let includedArr = [];
let colData = table.column(i).data().unique().sort().each(function(d, j) {
if (d != "") {
var cell = table.column(i).nodes().toArray().find(f => f.innerHTML.trim() == d);
var searchValue = $(cell).attr("data-search");
select.find('ul').append('<li data-value="' + searchValue + '">' + d + '</li>');
}
});
select.find('.dropdown-menu a').click(function(e) {
var term = $(this).closest("li").attr("data-value");
var text = $(this).html();
$(this).closest(".dropdown").find(".selectedvalue").html(text);
if (term == "") {
table.column(i).search('').draw();
return;
}
table.column(i).search("^" + escapeRegExp(term) + "$", true, false, true).draw();
});
});
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
});
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<table id="example" class="display" style="width:100%">
<tbody>
<tr>
<td data-search="N">N</td>
<td data-search="101">101</td>
<td data-search="1">1</td>
<td data-search="01">01</td>
<td data-search="10">10</td>
<td data-search="20">20</td>
</tr>
<tr>
<td data-search="N">N</td>
<td data-search="102">102</td>
<td data-search="1">1</td>
<td data-search="02">02</td>
<td data-search="(20)">(20)</td>
<td data-search="20">20</td>
</tr>
<tr>
<td data-search="N">N</td>
<td data-search="103">103</td>
<td data-search="1">1</td>
<td data-search="03">03</td>
<td data-search="-10-">
<del>10</del>
</td>
<td data-search="20">20</td>
</tr>
</tbody>
<thead>
<tr>
<th rowspan="2">Bldg</th>
<th rowspan="2">Unit</th>
<th rowspan="2">Floor</th>
<th rowspan="2">Stack</th>
<th colspan="2">
Floor Level
</th>
</tr>
<tr>
<th>Floor 1</th>
<th>Floor 2</th>
</tr>
<tr class="filterRow">
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
</table>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
Note: I have not styled the dropdowns.

Jquery:- Count number of td in each tr

How can I count td in each row, It should say row 1 have two td and row 3 have one td.
I need to count td per row(tr)
$(function() {
$('.Create-New-Order').click(function() {
var total = $('#mytbl td').length;
alert('tr count = ' + total);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<table border="1px solid red">
<tr>
<th>Name</th>
<th>Email</th>
</tr>
<tbody id="mytbl">
<tr>
<td>sfdsd</td>
<td>tsdaf#ymail.com</td>
</tr>
<tr>
<td>sfdsd</td>
<td>tsdaf#ymail.com</td>
</tr>
<tr>
<td>sfdsd</td>
</tr>
</tbody>
</table>
<br>
<br>
Create-New-Order
You need to loop over each row and then get the number of cells with $(this).find('td').length:
$('.Create-New-Order').click(function() {
var total = $('#mytbl tr').each(function() {
console.log($(this).find('td').length)
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<table border="1px solid red">
<tr>
<th>Name</th>
<th>Email</th>
</tr>
<tbody id="mytbl">
<tr>
<td>sfdsd</td>
<td>tsdaf#ymail.com</td>
</tr>
<tr>
<td>sfdsd</td>
<td>tsdaf#ymail.com</td>
</tr>
<tr>
<td>sfdsd</td>
</tr>
</tbody>
</table>
<br>
<br>
Create-New-Order
This is easy first get all rows the loop throw each and count the td.
See below
$(function() {
$('.Create-New-Order').click(function() {
var trs=document.querySelectorAll("#mytbl tr")
trs.forEach(function(tr){
console.log(tr.querySelectorAll("td").length)
})
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<table border="1px solid red">
<tr>
<th>Name</th>
<th>Email</th>
</tr>
<tbody id="mytbl">
<tr>
<td>sfdsd</td>
<td>tsdaf#ymail.com</td>
</tr>
<tr>
<td>sfdsd</td>
<td>tsdaf#ymail.com</td>
</tr>
<tr>
<td>sfdsd</td>
</tr>
</tbody>
</table>
<br>
<br>
Create-New-Order

Adding the sum of a field in Datatables

This question has been asked before but as an absolute beginner with JavaScript I don't know how to apply this to my code. I would like the sum for both the 'G' field and sum for the 'AB' field to be displayed in the footer of my table.
Here's my code
<div align="center">
<table id = 'battingtbl' class="display compact nowrap">
<thead>
<tr>
<th>YEAR</th>
<th>AGE</th>
<th>G</th>
<th>AB</th>
</tr>
</thead>
<tbody>
{% for stat in playerdata.masterbatting_set.all %}
<tr>
<td>{{ stat.year }}</td>
<td>{{ stat.age }}</td>
<td>{{ stat.g }}</td>
<td>{{ stat.ab }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<script>
$(document).ready(function () {
$('#battingtbl').DataTable({
"searching": true,
"pageLength": 40,
"scrollX": true,
"paging": false,
"info": false,
})
});
</script>
I normally do not suggest to populate DataTable with HTML source, I find this way tedious and slow.
However, assuming you want those totals to get recalculated upon each re-draw (table filtering), I'd suggest to employ drawCallback option to populate your totals:
drawCallback: () => {
// grab DataTables insurance into the variable
const table = $('#battingtbl').DataTable();
// extract all the data for all visible columns
const tableData = table.rows({search:'applied'}).data().toArray();
// summarize row data for columns 3,4 (indexes 2, 3)
const totals = tableData.reduce((total, rowData) => {
total[0] += parseFloat(rowData[2]);
total[1] += parseFloat(rowData[3]);
return total;
// starting point for reduce() totals for 2 columns equal to zero each
}, [0,0]);
// populate footer cells for columns 3, 4 (indexes 2, 3) with corresponding array total
$(table.column(2).footer()).text(totals[0]);
$(table.column(3).footer()).text(totals[1]);
}
Above requires you to append <tfoot> section to the static HTML part you prepare server-side:
<tfoot>
<tr>
<th colspan="2">Totals:</th>
<th></th>
<th></th>
</tr>
</tfoot>
So, complete example might look something, like this:
<!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>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
<div align="center">
<table id = 'battingtbl' class="display compact nowrap">
<thead>
<tr>
<th>YEAR</th>
<th>AGE</th>
<th>G</th>
<th>AB</th>
</tr>
</thead>
<tbody>
<tr>
<td>2016</td>
<td>24</td>
<td>15</td>
<td>6</td>
</tr>
<tr>
<td>2018</td>
<td>32</td>
<td>5</td>
<td>7</td>
</tr>
<tr>
<td>2016</td>
<td>28</td>
<td>14</td>
<td>9</td>
</tr>
<tr>
<td>2015</td>
<td>25</td>
<td>9</td>
<td>7</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2">Totals:</th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
<script>
$(document).ready(function () {
$('#battingtbl').DataTable({
"searching": true,
"pageLength": 40,
"scrollX": true,
"paging": false,
"info": false,
drawCallback: () => {
const table = $('#battingtbl').DataTable();
const tableData = table.rows({
search: 'applied'
}).data().toArray();
const totals = tableData.reduce((total, rowData) => {
total[0] += parseFloat(rowData[2]);
total[1] += parseFloat(rowData[3]);
return total;
}, [0, 0]);
$(table.column(2).footer()).text(totals[0]);
$(table.column(3).footer()).text(totals[1]);
}
})
});
</script>
</body>
</html>

DataTables iniating multiple child tables with columnDefs intact

Background: I have 7 DataTables being created by a PHP loop (HTML is created directly on the page - not sourced from AJAX or anywhere else). Within these summary level DataTables, I have a further 6 detail level DataTables in a nested loop (one for each of the summary level tables - apart from one). These are in the last column of each summary table and using the responsive option I am able to have the content of the detail tables pushed to a child row as per https://datatables.net/examples/api/row_details.html
Problem: I am trying to initiate each child (detail) table in the initComplete: function(){} of the parent table. It seems to be doing something although the table doesn't retain any of the DataTables libraries functionality (column definition widths for example).
My main issue is that is ignoring my DataTable options (setting widths via columnDefs in this case is vital:
Am I missing something? Is there a reason it's choosing to override/ignore my column widths. The parent table allows responsive and columnDefs.
See snippet for example:
$('#summary_table').DataTable({
paging: false,
autoWidth: false,
searching: false,
columnDefs: [{
'width': '3%',
'targets': [0]
},
{
'width': '10%',
'targets': [1, 2]
},
{
"className": "dt-center",
"targets": "_all"
},
],
initComplete: function() {
console.log("Initialisation of table complete");
var sub_table = $('#summary_table').find('.ic-detail-table');
if (sub_table.length > 0) {
var sub_table_inst = $(sub_table).DataTable({
paging: false,
autoWidth: false,
searching: false,
columnDefs: [
//IGNORED????
{
'width': '10%',
'targets': [0]
},
{
'width': '25%',
'targets': [1]
},
{
'width': '25%',
'targets': [2]
},
{
'width': '40%',
'targets': [3]
},
{
"className": "dt-center",
"targets": "_all"
},
],
ordering: true,
sorting: true,
initComplete: function() {
console.log("SUB TABLE INIT COMPLETE");
},
responsive: true,
dom: '<"clear">rt',
order: [
[1, 'asc']
]
});
}
},
ordering: false,
responsive: true,
dom: '<"clear">rt',
order: [
[1, 'asc']
]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/v/dt/dt-1.10.18/b-1.5.4/r-2.2.2/sl-1.2.6/datatables.min.js"></script>
<link href="https://cdn.datatables.net/v/dt/dt-1.10.18/b-1.5.4/r-2.2.2/sl-1.2.6/datatables.min.css" rel="stylesheet" />
<table class='table table-bordered display compact' id='summary_table'>
<thead>
<tr>
<th></th>
<th>Heading one</th>
<th>Heading two</th>
<th>Heading three</th>
<th class='none'>Detail table</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>cell one</td>
<td>cell two</td>
<td>cell three</td>
<td>
<table class='table compact' class='ic-detail-table'>
<thead>
<tr>
<th>Heading one</th>
<th>Heading two</th>
<th>Heading three</th>
<th>Heading four</th>
</tr>
</thead>
<tbody>
<tr>
<td>Heading one</td>
<td>Heading two</td>
<td>Heading three</td>
<td>Heading four</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
What you're looking to do isn't by default part of datatables, but you can hack your way through it by adding a maximum for width for the classes dtr-details and compact
$('#summary_table').DataTable({
paging: false,
autoWidth: false,
searching: false,
columnDefs: [{
'width': '3%',
'targets': [0]
},
{
'width': '10%',
'targets': [1, 2, 3]
},
{
"className": "dt-center",
"targets": "_all"
},
],
initComplete: function() {
console.log("Initialisation of table complete");
var sub_table = $('#summary_table').find('.ic-detail-table');
if (sub_table.length > 0) {
var sub_table_inst = $(sub_table).DataTable();
}
},
ordering: false,
responsive: true,
dom: '<"clear">rt',
order: [
[1, 'asc']
]
});
.dtr-details,
.compact {
width: 100%!important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/v/dt/dt-1.10.18/b-1.5.4/r-2.2.2/sl-1.2.6/datatables.min.js"></script>
<link href="https://cdn.datatables.net/v/dt/dt-1.10.18/b-1.5.4/r-2.2.2/sl-1.2.6/datatables.min.css" rel="stylesheet" />
<table class='table table-bordered display compact' id='summary_table'>
<thead>
<tr>
<th></th>
<th>Heading one</th>
<th>Heading two</th>
<th>Heading three</th>
<th class='none'>Detail table</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>cell one</td>
<td>cell two</td>
<td>cell three</td>
<td>
<table class='table compact' class='ic-detail-table'>
<thead>
<tr>
<th>Heading one</th>
<th>Heading two</th>
<th>Heading three</th>
<th>Heading four</th>
</tr>
</thead>
<tbody>
<tr>
<td>Heading one</td>
<td>Heading two</td>
<td>Heading three</td>
<td>Heading four</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Also note that I changed your 'targets': [1, 2] to 'targets': [1, 2, 3] and you don't need any options in the child datatables, as they won't be taken into account.
If you add an id to the inner table, for example innerTable you could then just add this css to make the first column's width 3% :
#innerTable thead tr th:first-child,
#innerTable tbody tr td:first-child {
width: 3%!important;
}
$('#summary_table').DataTable({
paging: false,
autoWidth: false,
searching: false,
columnDefs: [{
'width': '3%',
'targets': [0]
},
{
'width': '10%',
'targets': [1, 2, 3]
},
{
"className": "dt-left",
"targets": "_all"
},
],
initComplete: function() {
console.log("Initialisation of table complete");
var sub_table = $('#summary_table').find('.ic-detail-table');
if (sub_table.length > 0) {
var sub_table_inst = $(sub_table).DataTable();
}
},
ordering: false,
responsive: true,
dom: '<"clear">rt',
order: [
[1, 'asc']
]
});
.dtr-details,
.compact {
width: 100% !important;
}
#innerTable thead tr th:first-child,
#innerTable tbody tr td:first-child {
width: 3% !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/v/dt/dt-1.10.18/b-1.5.4/r-2.2.2/sl-1.2.6/datatables.min.js"></script>
<link href="https://cdn.datatables.net/v/dt/dt-1.10.18/b-1.5.4/r-2.2.2/sl-1.2.6/datatables.min.css" rel="stylesheet" />
<table class='table table-bordered display compact' id='summary_table'>
<thead>
<tr>
<th></th>
<th>Heading one</th>
<th>Heading two</th>
<th>Heading three</th>
<th class='none'>Detail table</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>cell one</td>
<td>cell two</td>
<td>cell three</td>
<td>
<table id="innerTable" class='table compact' class='ic-detail-table'>
<thead>
<tr>
<th>Id</th>
<th>Heading two</th>
<th>Heading three</th>
<th>Heading four</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Heading two</td>
<td>Heading three</td>
<td>Heading four</td>
</tr>
<tr>
<td>2</td>
<td>Heading two</td>
<td>Heading three</td>
<td>Heading four</td>
</tr>
<tr>
<td>3</td>
<td>Heading two</td>
<td>Heading three</td>
<td>Heading four</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
JSFiddle : https://jsfiddle.net/6fp3kbnh/

Categories

Resources