I have many columns, the order and quantity its not always the same, and some hidden colums and left joins too. But some of this columns have toggles that send data to specific columns to db thru ajax.
The toggles can be at any position and can be more than one.
Im triyng to add attr to columns to read it and know the cell db and table were send the data.
its posible to add attr to a column and read it? to send data to db with ajax with toggles
Can't search contain underscore (string)
Hi, i use server side using ajax, when i search with underscore keyword (_) it result no record fount.
but i'm run manual query is work fine in mysql with LIKE
and use IgnitedDatatables for codeigniter
Best regard,
Thanks
Sample implementation of serverside processing in C# MVC, EF with paging/sorting/searching
I have seen people asking a few times how to use datatables serverside with MVC and EF with paging sorting and searching etc. I had some code lying around so I thought its time to give back and share a simple implementation.
Unfortunately I don't have time right now to create a sample solution for download so I just hacked out the code and pasted it in here as a guide.
For the dynamic searching (where clause) you will need linqkit for the predicate building.
First map the datatable inbound JSON requests to classes
Start - JSon class sent from Datatables
public class DataTableAjaxPostModel
{
// properties are not capital due to json mapping
public int draw { get; set; }
public int start { get; set; }
public int length { get; set; }
public List<Column> columns { get; set; }
public Search search { get; set; }
public List<Order> order { get; set; }
}
public class Column
{
public string data { get; set; }
public string name { get; set; }
public bool searchable { get; set; }
public bool orderable { get; set; }
public Search search { get; set; }
}
public class Search
{
public string value { get; set; }
public string regex { get; set; }
}
public class Order
{
public int column { get; set; }
public string dir { get; set; }
}
/// End- JSon class sent from Datatables
Next implement your action in a standard controller (note in this example we are not using a Web-API controller)
This method just grabs the data sent from the table and calls YourCustomSearchFunc()
before returning a formatted json obj for Datatables to consume.
public JsonResult CustomServerSideSearchAction(DataTableAjaxPostModel model)
{
// action inside a standard controller
int filteredResultsCount;
int totalResultsCount;
var res = YourCustomSearchFunc(model, out filteredResultsCount, out totalResultsCount);
var result = new List<YourCustomSearchClass>(res.Count);
foreach (var s in res)
{
// simple remapping adding extra info to found dataset
result.Add(new YourCustomSearchClass
{
EmployerId = User.ClaimsUserId(),
Id = s.Id,
Pin = s.Pin,
Firstname = s.Firstname,
Lastname = s.Lastname,
RegistrationStatusId = DoSomethingToGetIt(s.Id),
Address3 = s.Address3,
Address4 = s.Address4
});
};
return Json(new
{
// this is what datatables wants sending back
draw = model.draw,
recordsTotal = totalResultsCount,
recordsFiltered = filteredResultsCount,
data = result
});
}
YourCustomSearchFunc()
is very simple it just sets up the sort column and sort direction before calling the database search functionality. In this example we are only allowing sorting on a single column but you could easily implement multi column sorting.
public IList<YourCustomSearchClass> YourCustomSearchFunc(DataTableAjaxPostModel model, out int filteredResultsCount, out int totalResultsCount)
{
var searchBy = (model.search != null) ? model.search.value : null;
var take = model.length;
var skip = model.start;
string sortBy = "";
bool sortDir = true;
if (model.order != null)
{
// in this example we just default sort on the 1st column
sortBy = model.columns[model.order[0].column].data;
sortDir = model.order[0].dir.ToLower() == "asc";
}
// search the dbase taking into consideration table sorting and paging
var result = GetDataFromDbase(searchBy, take, skip, sortBy, sortDir, out filteredResultsCount, out totalResultsCount);
if (result == null)
{
// empty collection...
return new List<YourCustomSearchClass>();
}
return result;
}
This is the main meat of the functionality. In it we simply select from the dbase but instead of using a fixed where
clause we use a dynamic expression built using the wonderful LinqKit to generate the predicate.
Additionally we use Take and Skip to allow us to page through the data. Notice we use the where clause twice. Once to select the data and pick a page, the second time to count how many items we could have returned.
public List<YourCustomSearchClass> GetDataFromDbase(string searchBy, int take, int skip, string sortBy, bool sortDir, out int filteredResultsCount, out int totalResultsCount)
{
// the example datatable used is not supporting multi column ordering
// so we only need get the column order from the first column passed to us.
var whereClause = BuildDynamicWhereClause(Db, searchBy);
if (String.IsNullOrEmpty(searchBy))
{
// if we have an empty search then just order the results by Id ascending
sortBy = "Id";
sortDir = true;
}
var result = Db.DatabaseTableEntity
.AsExpandable()
.Where(whereClause)
.Select(m => new YourCustomSearchClass
{
Id = m.Id,
Firstname = m.Firstname,
Lastname = m.Lastname,
Address1 = m.Address1,
Address2 = m.Address2,
Address3 = m.Address3,
Address4 = m.Address4,
Phone = m.Phone,
Postcode = m.Postcode,
})
.OrderBy(sortBy, sortDir) // have to give a default order when skipping .. so use the PK
.Skip(skip)
.Take(take)
.ToList();
// now just get the count of items (without the skip and take) - eg how many could be returned with filtering
filteredResultsCount = Db.DatabaseTableEntity.AsExpandable().Where(whereClause).Count();
totalResultsCount = Db.DatabaseTableEntity.Count();
return result;
}
Here is the predicate builder function that just plugs in a where clause dynamically. You will need to install (nugget) in linqkit for this.
In this example I am searching where the searchterm appears in either the firstname or lastname
private Expression<Func<DatabaseTableMappedClass, bool>> BuildDynamicWhereClause(DBEntities entities, string searchValue)
{
// simple method to dynamically plugin a where clause
var predicate = PredicateBuilder.New<DatabaseTableMappedClass>(true); // true -where(true) return all
if (String.IsNullOrWhiteSpace(searchValue) == false)
{
// as we only have 2 cols allow the user type in name 'firstname lastname' then use the list to search the first and last name of dbase
var searchTerms = searchValue.Split(' ').ToList().ConvertAll(x => x.ToLower());
predicate = predicate.Or(s => searchTerms.Any(srch => s.Firstname.ToLower().Contains(srch)));
predicate = predicate.Or(s => searchTerms.Any(srch => s.Lastname.ToLower().Contains(srch)));
}
return predicate;
}
The only left to show is the datatable itself
var table = $('#SearchResultTable').DataTable({
"proccessing": true,
"serverSide": true,
"ajax": {
url: "@Url.Action("CustomServerSideSearchAction", "Home")",
type: 'POST'
},
"language": {
"search": "",
"searchPlaceholder": "Search..."
},
"columns": [
{ "data": "Firstname" },
{ "data": "Lastname" }
]
});
Hope this helps
Datatables export to labels
Hi All,
a customer asks me if it is possible to have his (fitlered) table exported to a pdf file with labels so he can
print it on address self adhesive stickers.
Now, i managed to get all the ID's from the datatable and i wanted to create PDF file on the fly trough an
Ajax call, but that seems not so easy to do. I tried JSPdf also but i didn't succeed in a good solution.
I am working in PHP Codeignter.
Anyone has any tips for me? It's highly appreciated.
Bart
Need Help printing custom labels
Hi guys,
I was able to consume JSON data using ajax to show my table with columns name, address line1, address line2, address line3 and also added buttons to export to excel, pdf and print. Now I needed to print mailing labels in the following format:
name
address line1
address line2
address line3
name
address line1
address line2
address line3
I would like to modify the existing print function to achieve this if possible. Anyone has any idea on how to achieve this or do I have to write my own function? Please help!!
Thanks in advance
Sort by hidden column, filter by display column
I know I need to use this: https://datatables.net/reference/option/columns.render
but there are no examples on there of what the HTML has to look like? My data tables are not generated by JSON, they are created from a regular HTML table. What attributes do I need to include in my table cells?
How to clear a filter upon column visibility button click
Hi,
I've been reading up on these 2 options:
https://datatables.net/extensions/buttons/examples/column_visibility/simple.html
https://datatables.net/extensions/fixedheader/examples/options/columnFiltering.html
I tested these out and look like they will work for my scenario but I have noticed if I filter a column by entering a value and then turn off the visibility of the column the filter is still applied which then means all further filtering you do is reliant on the first filter applied now hidden.
Is there a setting to clear the filter automatically if this occurs? (would seem logical to do so?).
If not I suspect I will be able to do this by somehow applying an ID to each column visibility button which references the filter inputs and clear it that you using a .val('').trigger('change')?
Thanks,
Performance Issue with Datatables having fixed columns
Hi,
We are facing delay up to minutes while loading a datatable. When we analyzed performance using F12 debugger-> Performance option, it was showing that the dom loading was taking 80% of the cpu time.
We are using the fixed column option along with serverside option as our data can be up to 20000 rows. We are displaying 90 columns. We are using datatables-1.10.19, fixedcolumns-3.2.6. Please help.
Thanks,
Arun
line break when exporting to excel
I have my project in this way : https://jsfiddle.net/Eufragio/u342qgoz/1/
My problem is when exporting to excel, that the results bring me this way:
The result that I hope is this:
clear old ajax source data from old table instance
Hi,
Im using angular 6 for developping my application.
i create 3 component with router logic.
That mean that when navigate one component to others. Html is deleted and generated.
So on each component i have each other a table that they get initialize in the function ngOnInit.
Each other have different options and different ajax sources routes.
Each time i navigate to a component the table make a first request to my backend.
But some how when i navigate to another component. he keeps the old ajax source data from the old data initialization and pop some alert error msg with error on colomn x to row x and data x. But the table keeps working. But the alert concern colomn data that i initialize in a old datatable options.
In the ngOnDestroy function i try $('#foo').DataTable().destroy() and $('#foo').DataTable().clear().
I try this method at the end of ngOnInit to see what happend and the table actually get destroy and data clear but like i said somehow when i navigate that spam me an error about a data that dont exist on another table.
Is there a way to add on my router logic to clear complety ajax data?
I hope you guys understand my question, thanks for the help.
*edit: somehow i cant send exemple code maybe to long and cant use playground
Hide the sorting option on all but one column?
I'd like to default sort a column (know how to do this) AND hide the sorting option on my other columns. Is this possible with DataTables? I can't find the option.
Thanks!
How can I export HTML in a cell using [buttons] excel export
I have a column which has a html link in it.
json_encode('<a href="url.com">'.$row['name'] . '</a>')
I want this exported to Excel when the user uses the export button.
I have tested and the HTML is not being included in the cell during export.
If I use stripHtml: false
- it adds the html link as text in the cell
Is this possible? Do I need to do something special?
Email button pdf
I would like to add a button to to the datatable buttons called Email which when clicked would prompt for an email address and then call the pdf creation like the pdf button does and then do an ajax call to the server with the pdf. On the server I would save the pdf and then email it. I know how to do the server side, but need help with creating a custom button, adding a prompt for the email ( I can do the prompt, just need a function call) and then then code to create the pdf and send it via ajax.
I think this could be super useful and have seen several request for things like this, but this implementation to me makes the most sense. I am just way over my head with how datatables works to implement this.
How to show partial content for long text cells? Whole content is displayed if the cell is clicked.
One of my column is for long text content (for product description). In order not to increase the row height in the table, any way to show partial of the text and also show "read more" at the cell? The full content can be expanded if the cell is clicked. or hovered. Thank you.
Use fetch api instead of ajax call in datatable
Hi guys. I understand that you can use ajax to populate the datatable. But can you use fetch?
Because I have this normal table, filled dynamically using fetch api.
Here's the code snippet
$(document).ready(function(){
fillTable();
})
//fetch api (AJAX) to fill table
fillTable = () => {
fetch('http://localhost:3000/home.json')
.then(response => response.json())
.then(data => {
let html = '';
for (i = 0; i < data.length; i++){
html += '<tr>'+
'<td class="tdUsername pv3 w-35 pr3 bb b--black-20">'+ data[i].username + '</td>'+
'<td class="tdPassword pv3 w-35 pr3 bb b--black-20">'+ data[i].password + '</td>'+
'<td class="pv3 w-30 pr3 bb b--black-20">'+
'<div class="btn-group" role="group" aria-label="Basic example">'+
'<a class="editButton f6 grow no-underline ba bw1 ph3 pv2 mb2 dib black pointer" data-toggle="modal">EDIT</a>'+
'<a class="deleteButton f6 grow no-underline ba bw1 ph3 pv2 mb2 dib black pointer" data-toggle="modal">DELETE</a>'+
'</div>'+
'</td>'+
'</tr>'
}
$('#tblBody').html(html);
})
.catch(err => console.log("ERROR!: ", err))
}
Get data into Excel Export
I have tried a few ways to achieve this but DataTables kills me at every turn.
I have data in a child row which are notes - could be one note, could be 20 separate notes.
I want to export with excel when the [button] is clicked.
DataTables says - this can't be done.
So I opted for a workaround:
Generate a unique link and wrap that around a field - When exported, the user can click the link which opens a custom page which lists all the notes - This can't be done...
I'm running out of solutions here - DataTables is cutting me off at every pass...
Are there any solutions bar loading in paragraphs of data into the main table row?
How do i specify the child rows for each row in my table ?
I'm using the datatable example of child rows without the ajax and im having a problem where my child rows all have the same data.
function format ( d ) {
// `d` is the original data object for the row
return '<div class="col-md-8" style="padding-top:20px;">'+
'<table class="table table-bordered">'+
'<tr>'+
'<th>'+
"Product Name"+
'</th>'+
'<th>'+
"Quantity"+
'</th>'+
'</tr>'+
'<tr>'+
'<td>'+
"data here"+
'</td>'+
'<td>'+
"data here"+
'</td>'+
'</tr>'+
'</table>'+
'</div>';
}
$('#manageOrderTable tbody button').on('click', function () {
var tr = $(this).closest('tr');
var row = t.row( tr );
if ( row.child.isShown() ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
} );
This is my table:
<tbody>
@php
$x=0;
@endphp
@foreach ($orders as $order)
<tr>
<td></td>
<td>{{$order->order_date}}</td>
<td>{{$order->client_name}}</td>
<td>{{$order->client_contact}}</td>
<td class="details-control">
<button class="btn btn-info btn-xs">
<b>Items : </b> {{$item_count["$x"]}}
</button>
Item Id: @for ($y = 0; $y < $item_count["$x"]; $y++)
{{$item_list["$y"]->product_id}}
@endfor
{{-- <!-- Split button -->
<div class="btn-group">
<button type="button" class="btn btn btn-info btn-xs"><b>Items : </b> {{$item_count["$x"]}}</button>
<button type="button" class="btn dropdown-toggle btn btn-info btn-xs" data-toggle="collapse" data-target="#extra_info{{$x}}" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
</button>
</div>--}}
{{-- <div id="extra_info{{$x}}" class="collapse">
@for ($y = 0; $y < $item_count["$x"]; $y++)
{{$item_list["$y"]->product_id}}
@endfor
</div> --}}
</td>
@if ($order->payment_status==1)
<td><label class="label label-success">Full Payment</label></td>
@elseif($order->payment_status==2)
<td><label class="label label-info">Advance Payment</label></td>
@else
<td><label class="label label-warning">No Payment</label></td>
@endif
<td>
<!-- Single button -->
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Action <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="{{route('orders.edit',$order->order_id)}}" id="editOrderModalBtn"> <i class="glyphicon glyphicon-edit"></i> Edit</a></li>
<li><a type="button" data-toggle="modal" id="paymentOrderModalBtn" data-target="#paymentOrderModal" data-due="{{$order->due}}" data-id="{{$order->order_id}}"> <i class="glyphicon glyphicon-save"></i> Payment</a></li>
<li><a type="button" onclick="printOrder({{$order->order_id}})"> <i class="glyphicon glyphicon-print"></i> Print </a></li>
<li><a href="{{route('orderDelete',$order->order_id)}}" type="button"> <i class="glyphicon glyphicon-trash"></i> Remove</a></li>
</ul>
</div>
</td>
</tr>
@php
$x++;
@endphp
@endforeach
</tbody>
I want to show the item id of each row in the child table.
error on page for datatable
i am getting this error on a page
DataTables warning: table id=example - Ajax error. For more information about this error, please see http://datatables.net/tn/7
datatable file location in code
Hi,
i am using data table to display record,
my project is hosted in windows server
the site is pointing to windows server.
when i open the website its showing this error
DataTables warning: table id=example - Ajax error. For more information about this error, please see http://datatables.net/tn/7
dynamically fit to contents in server-side
My issue comes from the server-side pagination.
Once new data has been injected by ajax source, I need to draw again the table to get the reading fixed because I don't use multiple line per cell. So new contents may be shorter then previous, or longer and the overflow goes on the background than the following cell. It's fine for me, so I just need to redraw using a button that act like a kind of refresh for the table structure:
{ text: 'Refresh', action: function () { table.columns.adjust().draw(); } }
This is just a kind of workaround and it's working, I'm looking for adding this behaviour to the ajax response got from DataTable and I am not able.
If I handle the fnDrawCallback I got infinite refresh that stucks on my web client page, of course it's not a good solution.
By the way, a problem of the main workaround is with the pagination because the button that act like a refresh for the structure of the table brings me back to the first page. If I'm reading contents from the n-th page and I just need to "refresh" tha table I don't get refreshed my current view, so actually there is no way to "refresh" structure for pages that are not the first.
This is my table definition:
table = $("#" + table_name).DataTable({
"processing": true,
"serverSide": true,
"scrollY": '50vh',
"scrollX": true,
"scrollCollapse": true,
"autoWidth": true,
"columnDefs": [
{ "targets": "all", "defaultContent": "-" },
{ "targets": [4,5,6], "createdCell": function (td, cellData, rowData, row, col) {
if ( cellData == 1 ) {
$(td).addClass('compliant');
} else if ( cellData == 0 ) {
$(td).addClass('noncompliant');
}
} },
{ "targets": 3, "createdCell": function (td, cellData, rowData, row, col) {
if ( cellData == 1 ) {
$(td).parent().addClass('top54');
}
} }
],
"columns": [
{ "data": "foo", "className": 'details-control'},
{ "data": "bar" },
{ "data": "bar" },
{ "data": "RowNum", "orderable": false, "visible": false }
],
"ajax": {
"url": "json/ricerca_bdt_ng.php",
"method": "POST",
"data": function (d) {
d.user = account;
d.pass = password;
d.user_ad = account_ad;
d.pass_ad = password_ad;
d.device = deviceid;
d.host = dbhost;
d.port = dbport;
d.db = dbname;
}
},
"language": {
"lengthMenu": "Display _MENU records per page",
"zeroRecords": "Nothing found - sorry",
//"info": "Showing page PAGE of PAGES",
"infoEmpty": "No records available",
//"infoFiltered": "(filtered from MAX total records)",
"processing": "
",
"searchPlaceholder": "Global"
},
// Enable datatables.mark.js highlighting
"mark": true,
//"select": true,
"select": {
style: 'os',
items: 'cell'
},
"dom": "<'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix ui-corner-bl ui-corner-br'Blf>rt<'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix ui-corner-bl ui-corner-br'ip><'clear'>",
"buttons": [
{ extend: 'excelHtml5', title: exportfile },
{ extend: 'selectedSingle',
text: 'Copia cella',
action: function ( e, dt, node, config ) {
var sdata = table.cell('.selected').data();
copyToClipboard(sdata);
}
},
{ text: 'Refresh', action: function () { table.columns.adjust().draw(); } }
]
/*"fnDrawCallback": function( oSettings ) {
console.log( 'DataTables has redrawn the table' );
table.ajax.reload();
}*/
});
// fix input placeholder width
table.columns.adjust().draw();
//table.ajax.reload();
This is part of the css I'm using with the table:
/* fix table scrolling out his div /
table{
margin: 0 auto;
width: 100%;
clear: both;
border-collapse: collapse;
table-layout: fixed;
/word-wrap: break-word;*/
min-width: 100%;
}
th, td { white-space: nowrap; overflow: hidden; }
/th, td { white-space: normal; }/
/* dimensionamento tabella /
/ th { word-break: normal; }
td { word-break: break-all; } */
td.accapo { word-break: normal; }
div.dataTables_wrapper {
width: 95%;
margin: 0 auto;
}
div.dataTables_wrapper div.dataTables_processing {
top: 5%;
}
div.row_details {
width: 950px;
padding: 20px;
}
/* Floating column for labels: 25% width */
.col-25 {
float: left;
width: 25%;
margin-top: 6px;
}
/* Floating column for inputs: 75% width */
.col-75 {
float: left;
width: 75%;
margin-top: 6px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
I'm sorry I am not able to make a working example, I will make treasure of every advice you give me.