DataTables : aoColumns doesn't show a toggle image column - datatables

I'm using DataTables as a data grid manager on my app. Everything works fine but until I'm equipped a hidden row info plugin. I tried many ways to change things but the first column of toggle image never showed up. Here's my code:
Javascript
var oTable;
/* Formating function for row details */
function fnFormatDetails(nTr){
var aData=oTable.fnGetData(nTr);
var sOut='<table cellpadding="7" cellspacing="0" border="0" style="border:solid 1px red;padding-left:50px;">';
sOut+='<tr><td>Renderingengine:</td><td>'+aData[2]+''+aData[3]+'</td></tr>';
sOut+='<tr><td>Linktosource:</td><td>Couldprovidealinkhere</td></tr>';
sOut+='<tr><td>Extrainfo:</td><td>Andanyfurtherdetailshere(imagesetc)</td></tr>';
sOut+='</table>';
return sOut;
}
$(document).ready(function() {
oTable=$('#labour_show').dataTable({
"fnDrawCallback": function(){//row highlighter
$('table#labour_show td').bind('mouseenter', function () { $(this).parent().children().each(function(){$(this).addClass('datatablerowhighlight');}); });
$('table#labour_show td').bind('mouseleave', function () { $(this).parent().children().each(function(){$(this).removeClass('datatablerowhighlight');}); });
},
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "inc/_labour_show_ajax.php",
"aoColumns":[null,null,null,{"fnRender": function(oObj){return "<a href='main.php?do=labour&action=edit&sid=" + oObj.aData[7] + "'>Edit</a>";} }],"aaSorting": [[1, 'asc']]
});
$('#labour_show tbody td img').live('click',function(){
var nTr = this.parentNode.parentNode;
if(this.src.match('details_close')){
/* This row is already open - close it */
this.src = "images/ico_expand.png";
oTable.fnClose( nTr );
}else{
/* Open this row */
this.src = "images/ico_collapse.png";
oTable.fnOpen( nTr, fnFormatDetails(nTr), 'details' );
}
});
});
_labour_show_ajax.php
This is an arrays from a server-side script
$aColumns = array('labr_uid', 'labr_fname', 'emplyr_comp','labr_sid');
HTML Code:
<table cellpadding="0" cellspacing="0" border="0" class="display" id="labour_show">
<thead>
<tr>
<th></th>
<th>Passport</th>
<th>Name</th>
<th width="30%">Employer</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="5" class="dataTables_empty"><img src="images/loading.gif" /></td>
</tr>
</tbody>
Screen Shot
No matter I've tried. The first column never shown up. Please suggest.

I count 5 columns in your html table, and 4 in your aoColumns
Either add another null
"aoColumns":[
null,
null,
null,
null,
{"fnRender": function(oObj){return "<a href='main.php?do=labour&action=edit&sid=" + oObj.aData[7] + "'>Edit</a>";} }],
or do mData and add this
{ "mData": null ,
"mRender" : function ( data, type, full ) {
return '<img src="images/ico_open.png" />';}
},
Matter of fact, i believe mRender is the choice now over fnRender, and you could replace your fnRender as well like this
{ "mData": null , // or aAData[4] or aaData['labor_sid']
"mRender" : function ( data, type, full ) {
return 'Edit';}
},
Heres a link to another SO i answered about it Adding a link to datatables for more information

try this one,, i think your missing the { "sClass": "" } on the others
"aoColumns": [
{ "sClass": "", "bSortable": false },
null,
null,
null,
{ "sClass": "" },
{ "sClass": "" },
{"fnRender": function(oObj){return "<a href='main.php?do=labour&action=edit&sid=" + oObj.aData[7] + "'>Edit</a>";}}
],

Related

Update Export-Data on DataTable [duplicate]

I've been struggling with this code. I need to avoid specific columns from being exported. I have done that but I don't know how to export the text inside any input element.
Here is the code:
$("#campaignMaterialsTable table").DataTable({
dom: 'Bfrtip',
buttons: [
{
extend: 'excel',
className: 'export-button',
text: 'Export as Excel',
columns: ':not(.notexport)',
//exportOptions: {
// format: {
// body: function (data, row, column, node) {
// //
// //check if type is input using jquery
// return $(data).is("input") ?
// $(data).val() :
// data;
// },
// columns: ':not(.notexport)'
// }
//},
title: 'Campaign Materials'
}]
});
I don't know here to put the code at the right place.. while initializing..
I referred to this links, but still not getting what I want:
https://datatables.net/forums/discussion/50724/export-values-typed-in-input-box-excelhtml5
https://datatables.net/forums/discussion/42205/export-data-with-text-box-in-td-of-data-table#latest
https://datatables.net/extensions/buttons/examples/html5/outputFormat-function.html
https://datatables.net/forums/discussion/50724/export-values-typed-in-input-box-excelhtml5
I assume you have a DataTable containing one or more input fields, something like this:
The user can type values into the input fields.
You want to export data to Excel, so that the result looks like this:
Here we can see the user-provided data as well as the standard table data.
To achieve this, I used the following table data:
<table id="example" class="display nowrap dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Adélaïde Nixon</td>
<td>System Architect</td>
<td><input type="text" id="office" name="office"></td>
<td>432434</td>
<td>2011/04/25</td>
<td>$320,800</td>
</tr>
<tr>
<td>John Smith</td>
<td>Maager</td>
<td><input type="text" id="office" name="office"></td>
<td>6123</td>
<td>2011/04/25</td>
<td>$320,800</td>
</tr>
<tr>
<td>John Smith 2</td>
<td>Director</td>
<td><input type="text" id="office" name="office"></td>
<td>6123</td>
<td>2011/04/25</td>
<td>$320,800</td>
</tr>
</tbody>
</table>
And I used the following DataTable initialization code:
<script type="text/javascript">
$(document).ready(function() {
$('#example').DataTable({
dom: 'Bfrtip',
buttons: [
{
extend: 'excel',
exportOptions: {
format: {
body: function ( inner, rowidx, colidx, node ) {
if ($(node).children("input").length > 0) {
return $(node).children("input").first().val();
} else {
return inner;
}
}
}
}
}
]
});
});
</script>
The body function assumes that, for input fields, there is only an input field in the cell (i.e. the input field is not contained in a form or any other element).
It uses the node parameter to check for input data, to avoid data formatting issues that could occur (e.g. with dates). I recommend doing that rather than using $(data).is("input").
If there is no input field found in the cell, then the cell contents (inner) are returned.
If the structure of your table does not match these assumptions, then you may need to adjust the above code, of course.
Edit
Regarding the follow-up question about choosing which columns to export, there are various ways.
You can hard-code the column indexes you want to export (where index 0 means the first column). For example:
exportOptions: {
columns: [ 0, 1, 2, 3, 5 ],
format: {
body: function ( inner, rowidx, colidx, node ) {
if ($(node).children("input").length > 0) {
return $(node).children("input").first().val();
} else {
return inner;
}
}
}
}
This exports all columns apart from the Start Date column (index 4).
Or you can use the approach in your question, based on a class, I believe. I have not actually tried that one.
Take note of where the columns: [ 0, 1, 2, 3, 5 ] directive is placed - it is inside the exportOptions section.
you can use
exportOptions:{
columns: ':visible'
}
in below buttons
buttons: [
{
extend: 'pdf',
footer: true,
exportOptions: {
columns: ':visible'
}
},
it will export only visible columns

How to add multiple custom buttons in one row dynamically ? [JQuery Datatables]

I am using Datatables API but am not able to add multiple buttons in one row.
var table = $('#table_invdata').DataTable({
"columnDefs": [{
"targets": -1,
"data": null,
"defaultContent":
'<button class="btn-view" type="button">EDIT</button>'
}]
});
Try this code
var table = $('#table_invdata').DataTable({
"columnDefs": [{
"targets": -1,
"data": null,
"defaultContent":
'<button class="btn-view" type="button">EDIT</button>'
+ '<button class="btn-delete" type="button">Delete</button>'
}]
});
Or
var table = $('#table_invdata').DataTable({
"columnDefs": [{
"targets": -1,
"data": null,
"defaultContent":
'<button class="btn-view" type="button">EDIT</button> <button class="btn-delete" type="button">Delete</button>'
}]
});
Update :
You can use datatable render function to update the column values.
<table class="table" id="datatable" >
<thead>
<tr>
<th>Name </th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Jquery Datatable Code :
$('#datatable').DataTable ({
"data" : FinalResult,
"columns" : [
{ "data" : Name},
{ "data" : null,render: function ( data, type, row ) {
return '<button class="btn-view" type="button">EDIT</button>';
} },
{ "data" : null,render: function ( data, type, row ) {
return '<button class="btn-delete" type="button">Delete</button>';
} }
]
});
Fiddel Link : https://jsfiddle.net/jijomonkmgm/j6madey4/
<table id="table_invdata" class="table table-striped table-bordered">
<tr>
<th>EmpID</th>
<th>EmpName</th>
<th>Email-id</th>
<th>Salary</th>
<th>Position</th>
<th></th>
</tr>
</table>

Datatables plugin for jQuery. How to hide rows? Export to Excel still showing hidden rows

I was able to figure out how to hide the rows I wanted using JQuery. I have a modal that pops out for the user deselects the checkbox on what rows they want to hide. It works perfectly but when I export it to excel it still displays the hidden rows. I am not using the API at all and I think that's my problem. I am hiding the rows by using .show() and .hide(). I am using the API to hide the columns and when I click my export to excel button it works just fine. Could anyone help me figure out how to hide rows and be able to export it to excel with the rows not showing on the spreadsheet?
HTML
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.2.4/js/dataTables.buttons.min.js">
</script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js">
</script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.2.4/js/buttons.html5.min.js">
</script>
<table cellpadding="0" cellspacing="0" border="0" class="dataTable" class="example">
<thead>
<tr>
<th>Item</th>
<th>Store 1</th>
<th>Store 2</th>
<th>Store 3</th>
<th>Store 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sugar</td>
<td>21</td>
<td>95</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td>Coffee</td>
<td>5</td>
<td>41</td>
<td>5</td>
<td>1</td>
</tr>
<tr>
<td>Banana</td>
<td>123</td>
<td>323</td>
<td>22</td>
<td>233</td>
</tr>
<tr>
<td>Gum</td>
<td>13</td>
<td>213</td>
<td>2</td>
<td>33</td>
</tr>
<tr>
<td>Milk</td>
<td>23</td>
<td>24</td>
<td>44</td>
<td>242</td>
</tr>
</tbody>
</table>
</div>
</body>
JavaScript
var table = $('.example').DataTable({
dom: 'Bfrtip',
buttons: [
{
extend: 'excelHtml5',
exportOptions: {
columns: ':visible'
},
text: 'Export to Excel'
},
],
});
// I get the attribute name from the checkbox and I match it with the id on the row and when the checkbox is unchecked I hide the rows.
$('input.rowsHideSeek').click(function() {
var name = $(this).attr('name');
if ($(this).is(':checked')) {
$('#' + name).show()
} else {
$('#' + name).hide()
}
});
This is what I came up with and it seems to work. It shows and hides rows and, on export, only shows rows not hidden.
here is it is on jsbin http://jsbin.com/qituvu/edit?output
The key part is that it uses the customizeData in the extended excelHtml5.
$(document).ready(function () {
// this just creates a critera to filter on
var faketype = 1;
for (var i = 0; i < dataStore.data1.length; ++i) {
dataStore.data1[i].type = faketype++;
if (faketype == 5) faketype = 1;
}
var aTable = $('#example').DataTable({
"data": dataStore.data1,
paging:false,
"columns": [
{ "data": "name" },
{ "data": "position" },
{ "data": "office", className: "editColumn" },
{ "data": "extn" },
{ "data": "start_date" },
{ "data": "salary" },
{ "data": "type"}
], dom: 'Bfrti',
"createdRow": function( row, data, dataIndex ) {
$(row).addClass('type_' + data.type);
},
buttons: [{text:"Excel",
extend: 'excelHtml5', customizeData: function (exData) {
var rowNodes = aTable.rows().nodes();
var newData = []
for (var i = (exData.body.length - 1) ; i >= 0; i--) {
if ($(rowNodes[i]).css("display") == "none") {
continue;
}
newData[newData.length] = exData.body[i];
}
// the loop reverses order so put it back
exData.body = newData.reverse();
}}]
});
// event handler for hiding and showing rows
$("input[name='hideType']").on("click", function () {
var c = $(this).val();
var isChecked = $(this).prop('checked');
$(aTable.rows('.type_' + c).nodes()).toggle(isChecked);
aTable.rows().invalidate().draw();
});
});
The problem with jQuery hide() / show() is that you will need to tweak any part of dataTables you are using, if you want to fake persistent "hidden" rows.
Here is a few plug-in methods that provide real hide() and restore() on rows in dataTables :
$.fn.dataTableExt.hiddenRows = {};
$.fn.dataTable.Api.register( 'row.hide()', function(selector) {
var row = this.row(selector);
if (row.length == 0) return -1;
var index = row.node()._DT_RowIndex;
$.fn.dataTableExt.hiddenRows[index] = row.node().outerHTML;
row.remove().draw(false);
return index;
});
$.fn.dataTable.Api.register( 'row.restore()', function(index) {
var row = $.fn.dataTableExt.hiddenRows[index];
if (row) {
this.row.add( $(row) ).draw(false);
delete $.fn.dataTableExt.hiddenRows[index];
return true;
}
return false;
});
Now you have table.row.hide() and table.row.restore(). The methods use the dataTables API, and does nothing but maintaining a list of removed rows by their unique indexes. A demo could look like this :
var table = $('#example').DataTable({}) ;
$('#example').on('click', 'tbody tr', function() {
var index = table.row.hide(this);
var $button = $('<button></button>')
.addClass('restore')
.attr('index', index)
.text('show #'+index);
$('body').prepend($button);
})
$('body').on('click', '.restore', function() {
var index = $(this).attr('index');
table.row.restore(index);
$(this).remove();
})
When you click on a row it is hidden (i.e removed); a restore button is generated for each hidden row. If you click on the button the corresponding row is restored.
Demo -> http://jsfiddle.net/s183ek2q/

How to put an html element in dojo dgrid table header

I want to place a hyperlink in the <th> of dojo dgrid table, but it is not possible when I tried it declarative
<thead>
<tr>
<th data-dgrid-column="{ field:'AVAILABLE_BALANCE',resizable:true}">Available
Balanceclick
</th>
</tr>
</thead>
it displays like
Available Balance click
How to do it
You can use the column renderHeaderCell do achieve this.
using HTML to grid way
<thead>
<tr>
<th data-dgrid-column="{ field:'AVAILABLE_BALANCE',resizable:true,
renderHeaderCell:customRenderHeaderCell}">
</th>
</tr>
</thead>
JavaScript:
function customRenderHeaderCell(node){
var div = document.createElement("div");
div.innerHTML = "Available Balance<a href='#'>click</a>";
return div;
}
using programmatic way
require([ 'dgrid/Grid' ], function (Grid) {
var columns = {
first: {
label: "First Name"
},
last: {
label: "Last Name"
},
balance: {
field: 'AVAILABLE_BALANCE',
resizable: true,
renderHeaderCell: function(node){
var div = document.createElement("div");
div.innerHTML = "Available Balance<a href='#'>click</a>";
return div;
}
}
};
var grid = new Grid({ columns: columns }, 'grid');
grid.renderArray(arrayOfData);
});

How can we change width of search fields in DataTables

Can I change the width of search text fields in dataTables ?
I am writing following code right now but it is not working.
$('#example').dataTable()
.columnFilter({ sPlaceHolder: "head:before",
aoColumns: [ { type: "text",width:"10px" },
{ type: "date-range" },
{ type: "date-range" }
]
});
And if my dataTables is dynamically generated like as gven below:
$('#example').dataTable({
"aaData": aDataSet,
"aoColumns": [
{ "sTitle": "#","sWidth": "10px" },
{ "sTitle": "ID" },
{ "sTitle": "Staff Name" },
{ "sTitle": "Rig Days" },
{ "sTitle": "Manager"},
{ "sTitle": "Grade"},
{ "sTitle": "Tools"},
{ "sTitle": "Vacations"},
{ "sTitle": "Presently On"},
]
});
}
How to add Search field in this dynamically created DataTable to search by each column?
None of the above solution worked for me; then I got this:
$(document).ready(function () {
$('.dataTables_filter input[type="search"]').css(
{'width':'350px','display':'inline-block'}
);
});
And it worked perfectly!
If you want to place a placeholder too inside the search box use this ..
$('.dataTables_filter input[type="search"]').
attr('placeholder','Search in this blog ....').
css({'width':'350px','display':'inline-block'});
And this will work for sure.
To change the search box width, all I had to do was go into my .css file and enter the following:
.dataTables_filter input { width: 300px }
it's worked for me
<script>
var datatable = $('#table').DataTable({
...<datatables properties>,
initComplete: function () {
$('.dataTables_filter input[type="search"]').css({ 'width': '350px', 'display': 'inline-block' });
}
</script>
The only thing worked for me is this css.
$(document).ready(function(){
$('#datatable-buttons_filter').css({"position":"relative","left":"-100px"});
});
try to use css to change the width
example
.text_filter{
width:45%;
min-width:200px;
}
I applied this solution in my environment (Laravel 5.2, yajra/Laravel-DataTables 6.0, Bootstrap 3.x):
My table:
<table id="my-table" class="table table-striped table-hover" style="font-size: 80%">
<thead>
<tr>
<th class="input-filter" style="text-align:center;width: 5%">ID</th>
...
</tr>
</thead>
<tbody></tbody>
<tfoot>
<tr>
<th style="text-align:center;width: 5%">ID</th>
...
</tr>
</tfoot>
My script:
<script type="text/javascript">
var dt = $('#my-table').DataTable({
stateSave: true,
responsive: true,
processing: true,
serverSide: true,
order: [[ 0, "desc" ]],
lengthMenu: [[5, 10, -1], [5, 10, "All"]],
ajax: {
url: '...',
},
columns: [
{data: 'id', name: 'id',orderable:true,searchable:true},
...
],
language: {
url: '....'
},
initComplete: function () {
this.api().columns('.input-filter').every(function () {
var column = this;
var input = document.createElement("input");
// start - this is the code inserted by me
$(input).attr( 'style', 'text-align: center;width: 100%');
// end - this is the code inserted by me
$(input).appendTo($(column.footer()).empty())
.on('keyup', function () {
var val = $.fn.dataTable.util.escapeRegex($(this).val());
column.search(val ? val : '', true, true).draw();
});
});
}
});
</script>
here is the repeater
<asp:Repeater ID="rptClients" runat="server">
<HeaderTemplate>
<table id="example" class="display">
<thead>
<tr style="color:#fff;">
<th>Edit</th>
<th>Client Name</th>
<th>Address</th>
<th>City</th>
<th>State</th>
<th>Zip</th>
<th>Phone</th>
<th>Fax</th>
<th>Client Type</th>
<th>Active</th>
</tr>
<tr id="filterRow">
<td>Edit</td>
<td>Client Name</td>
<td>Address</td>
<td>City</td>
<td>State</td>
<td>Zip</td>
<td>Phone</td>
<td>Fax</td>
<td>Client Type</td>
<td>Active</td>
</tr>
</thead>
<tfoot style="display:none;">
<tr>
<td> </td>
</tr>
</tfoot>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><div class="padBtm-05 padTop-10"><asp:Button runat="server" ID="btnEdit" Text="Edit" /></div></td>
<td>
<%# Container.DataItem("ClientName")%>
</td>
<td>
<%# Container.DataItem("ClientAddress")%>
</td>
<td>
<%# Container.DataItem("ClientCity")%>
</td>
<td>
<%# Container.DataItem("State")%>
</td>
<td>
<%# Container.DataItem("ClientZip")%>
</td>
<td>
<%# Container.DataItem("ClientPhone")%>
</td>
<td>
<%# Container.DataItem("ClientFax")%>
</td>
<td>
<%# Container.DataItem("ClientType")%>
</td>
<td>
<%# Container.DataItem("Active")%>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
There are filters on all columns. Here I actually hide the edit column filter since it doesn't need one. If i don't render a filter for this column my filtering is off 1 column. In the javascript i target my table row which will end up being my title placeholder. Based on the placeholder name you can run an if statement that allows you to target the input element and set the width of the item. I have found setting the width of the filter sets the column width on the table.
// apply the input styling
$('#example thead td').each(function (i) {
var title = $('#example thead th').eq($(this).index()).text();
if (title == "Edit") {
var serach = '<input type="text" style="display:none;" placeholder="' + title + '" />';
} else if (title == "Client Name") {
var serach = '<input type="text" style="width:370px;" placeholder="' + title + '" />';
} else if (title == "Zip") {
var serach = '<input type="text" style="width:50px;" placeholder="' + title + '" />';
} else {
var serach = '<input type="text" placeholder="' + title + '" />';
}
$(this).html('');
$(serach).appendTo(this).keyup(function () { table.fnFilter($(this).val(), i) })
});
// 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();
}
});
});
I have used the below code while using dataTables
JS
$('#du_ft_table').dataTable( { <br/>
"bProcessing": true,<br/>
"bServerSide": true,<br/>
scrollX: true,<br/>
"sAjaxSource": "../server_processing_man.php?sourceC=du_ft&rights=1&mandatory=1&retailer_id=2725",
"aoColumns": [
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
{ "mData": function(obj) {
return '<a class="btn btn-xs btn-primary" href="EBSNL_NW='+obj[0]+'" alt="Edit" title="Edit"><i class="fa fa-pencil-square-o"></i></a>';
}}
]
} );
$('.dataTables_scrollFootInner tfoot th').each( function () {<br/>
var title = $(this).text();<br/>
if(title != '') $(this).html( '<input type="text" placeholder="Search '+title+'" />' );<br/>
});
var duft_table = $('#du_ft_table').DataTable();
// Apply the search
duft_table.columns().every( function () {<br/>
var that = this;<br/>
$( 'input', this.footer() ).on( 'keyup change', function () {<br/>
if ( that.search() !== this.value ) {<br/>
that.search(this.value).draw();<br/>
}<br/>
} );
});
Nativ javascript solution.
$(document).ready(function() {
$('#yourTableId').DataTable();
var addressTableFilter = document.getElementById('addressTable_filter');
addressTableFilter.firstChild.getElementsByTagName('input')[0].style.width = "400px";
addressTableFilter.firstChild.getElementsByTagName('input')[0].setAttribute('placeholder', 'Search');
addressTableFilter.firstChild.removeChild(document.getElementById('addressTable_filter').firstChild.firstChild);
});
Dont forget to wrap everything inside document ready(if u using it)otherwise other lines may kick in before datatable is initiated and you will get error.
This will also remove search label and add it as placeholder inside input box.