I want to search with a specific criteria.
For example we have:
Column1: Name, Column2: Age
I want to search only age > 30. If I want to search age = 30, I use table.column(1).search('30')
.
But, how I can search with that criteria?
I want to search with a specific criteria.
For example we have:
Column1: Name, Column2: Age
I want to search only age > 30. If I want to search age = 30, I use table.column(1).search('30')
.
But, how I can search with that criteria?
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
Hi,
I have a table which has expandable rows (like seen here: https://datatables.net/examples/api/row_details.html )
and in addition I can select rows using the Select functionality. (https://datatables.net/extensions/select/)
Is it possible to bind the plus (+) key so that when I click on it when selecting a row, the child-row will appear?
(very much like the standard expandable rows in Windows)
Thanks,
Avihai.
i want chow color for just some row like that pleas help
I am using Bootstrap. When I use the DOM Positioning say "flipt" all the controls appear in separate lines because everything is inside an individual div even though I didn't mention any "<" or ">".
I have downloaded the individual css/js-Files for dt and its extensions and am inserting the appropriate links into my HTML - but when inspecting the source of my page I now noticed a case where the Excel's button code referenced the .swf-file from cdn.datatables.net instead of site and I wonder why that is. I have verified by going through the download-process again (no package, only using Button-Extension with all sub-options selected and Download-method=Download) - the file buttins.flash.min.js still refers to cdn, yet my download contains a folder "swf" with exactly that file! (sry, the page is still on localhost, so no sample or debugger, but I think the case does not require it)
Source of Excel-button on my page:
<button class="dt-button buttons-excel buttons-flash" tabindex="0" aria-controls="sample"><span>Excel</span><div style="position: absolute; left: 0px; top: 0px; width: 62px; height: 39px; z-index: 99;"><embed id="ZeroClipboard_TableToolsMovie_1" src="//cdn.datatables.net/buttons/1.5.1/swf/flashExport.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboard_TableToolsMovie_1" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=62&height=39" wmode="transparent" align="middle" width="62" height="39"></div></button>
Hello all,
I have a working report using DataTables but as soon as a piece of data comes through with an EM dash I get the "Invalid JSON Repsonse" alert.
Response from server:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: CFID=26523; Path=/; Secure
Set-Cookie: CFTOKEN=97593167; Path=/; Secure
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 15 Jan 2018 14:42:29 GMT
Highligted character is causing the error:
Actual text (I'm guessing the character will get stripped but I'll try anyway):
ONeal
I'm not exactly sure what I can do to solve this, any ideas? Let me know if you need more information.
Thanks!
Hi
after update from DataTables Editor v1.5.x to 1.7.0 have
a problem z-index form add... now is backgound and list in foreground!
css:
'jquery.dataTables.min.css, 'buttons.dataTables.min.css', 'select.dataTables.min.css', 'editor.dataTables.min.css'
I trying to figure out how handle date formats using DataTable Editor, with inline datepicker.
I am using a SSP script to retrieve and update my database.
The field I need is stored in the DB as YYYMMDD format (text).
So I need to achieve the following...
This would also apply to the DataTable Editor form field as well.
SSP
<?php
// DataTables PHP library
require( $_SERVER['DOCUMENT_ROOT']."/DataTables_Editor/php/DataTables.php" );
// Alias Editor classes so they are easy to use
use
DataTables\Editor,
DataTables\Editor\Field,
DataTables\Editor\Format,
DataTables\Editor\Mjoin,
DataTables\Editor\Options,
DataTables\Editor\Upload,
DataTables\Editor\Validate;
// Build our Editor instance and process the data coming from _POST
Editor::inst( $db, 'NWxxxx.PAYxxxx', 'HREMxx')
->debug(true)
->fields(
Field::inst('HRLxx'),
Field::inst('HRLOxx'
Field::inst('HRNOxx'),
Field::inst('HRNAMxx'),
Field::inst('HREFDTxx') // SALARY EFFECTIVE DATE - Formatted YYYMMDD
)
->process( $_POST )
->json();
JS
<script type="text/javascript" src="/js/jquery-current.min.js"></script>
<script type="text/javascript" src="/jquery-ui-1.12.0/jquery-ui.min.js"></script>
<script type="text/javascript" src="/js/jquery.dataTables.min.js"></script>
<!-- <script type="text/javascript" src="/js/dataTables.fixedHeader.min.js"></script> -->
<script type="text/javascript" src="/js/dataTables.fixedColumns.min.js"></script>
<script type="text/javascript" src="/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" src="/js/dataTables.select.min.js"></script>
<script type="text/javascript" src="/DataTables_Editor/js/dataTables.editor.min.js"></script>
<script type="text/javascript" src="/js/dataTables.rowGroup.min.js"></script>
<script type="text/javascript" src="/DataTables_Editor/js/editor.display.js"></script>
<script type="text/javascript">
var editor; //global for the submit and return data rendering
var table; // global for the data table
//****************************************************************************
//** $(document).ready(function()
//****************************************************************************
$(document).ready(function() {
editor = new $.fn.dataTable.Editor( {
ajax: "ssp_script.php",
table: "#approvalTable",
fields: [
{label: "Employee Name",
name: "HRNAMxx",
type: "display",
},
{label: "Employee Number",
name: "HRNOxx",
},
{label: "Effective Date",
name: "HREFDTxx", // SALARY EFFECTIVE DATE - Formatted mm/dd/yyyy
},
]
} );
// Activate an inline edit on click of a table cell
$('#approvalTable').on( 'click', 'tbody td:not(:first-child):not(\'.live\')', function (e) {
editor.inline( this, {
onBlur: 'submit'
} );
} );
table = $('#approvalTable').DataTable( {
lengthMenu: [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
},
scrollX: true,
dom: "Bfrtip",
ajax: "ssp_HourlySalaryIncreaseApproval.php",
type: 'POST',
order: [[2, 'asc']],
columns: [
{
data: null,
defaultContent: '',
className: 'select-checkbox',
orderable: false
},
{ data: "HRLxx"},
{ data: "HRLOxx"},
{ data: "HRNOxx" },
{ data: "HRNAMxx" },
{ data: "HREFDTxx" }, // SALARY EFFECTIVE DATE - Formatted mm/dd/yyyy
],
select: {
style: 'os',
selector: 'td:first-child'
},
buttons: [
// { extend: "create", editor: editor },
{ extend: "edit", editor: editor },
// { extend: "remove", editor: editor }
]
} );
});//END $(document).ready(function()
</script>
I need to reset fields values based on a value changed in another inline field . I tried using the following script, however when the table is loaded the first time, the code is executed and wipes out the values in said fields. I just need to perform this operation when a user changes the HRWPER. So let's say, if the percent field changed from 2.0 to 3.0, I need to reset other fields.
I am sure there is a better way to do this so all suggestions are welcomed.
$( editor.field( 'HRWPER' ).input() ).on( 'change', function () {
//**Reset Plant Manager Approval function
editor.field( 'HRWMGR' ).val( 0);
editor.field( 'HRWMNA' ).val( '');
} );
I am using the datatables with ajax, pagination and buttons.
The table shows only the results of the page, until then everything normal and right.
I would like to know if I can click on the button to print(view, export), remove the page and make a new query on the server. In this way the printing will have all the results available.
Is it possible to do that?
Hi
I wonder if you could help me get Autocomplete to work. I have set up a basic test but still am struggling and would probably benefit from a basic example.
I am using JQueryUI/BS4/DataTables and have several different tables on a single page, 2 with editors. I want to use AutoComplete for the 'diagnosis' field. The relevant code is:
var diagnosisEditor = new $.fn.dataTable.Editor( {
ajax: {
url: 'common/ajax/diagnoses.php?id={id}',
type: 'POST'
},
table: '#diagnoses',
fields: [
{
"label": "patient_id:",
"name": "diagnoses.patient_id",
"type": "hidden",
"def": "{id}"
},
{
"label": "Date:",
"name": "diagnoses.diagnosis_date",
"type": "datetime",
"format": "DD-MM-YYYY"
},
{
"label": "Diagnosis:",
"name": "diagnosis_list.diagnosis",
"type": "autoComplete",
"opts": {
"source": [
"john", "fred", "james", "malcolm", "dave", "alex", "ruby"
]
}
},
{
"label": "Notes:",
"name": "diagnoses.notes",
"type": "text"
}
]
} );
The field appears, but AutoComplete does not seem to work. What am I doing wrong?!
Thanks in advance
Ronnie
Cuando intento cargar parrafo con comillas dobles , saltos de linea , comas , puntos y comas en su contenido me aparece error .
DataTables warning: table id=tabEventosCN - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1
Hi, I am using Editor buttons and select extensions . I need to export in Excel all the row and not only the selected ones and I followed the example reported in
https://datatables.net/extensions/buttons/examples/print/select
In both cases, the "Print all" button in the example and our use case, the option
exportOptions: {
modifier: {
selected: null
}
}
is not working and only the table header is exported.
Is the selected: null modifier still valid?
Thanks
Hi,
I am trying to execute some longer processes server-side on a row removal, and am wondering how I can prevent datatables from reloading the page after I submit a delete event. I tried, e.preventDefault() in the success parameter to the overriden ajax for the editor removal option, but that stopped anything from happening.
How would someone stop the page reload on only a single AJAX override event in Editors?
Thanks!
Chris
Most of the topics on passing a new jQuery DataTable to Row.Child().Show() to display a detail table has been closed. At the moment, I am able to display a detail table using Row.Child(row.data()).Show() but I built the HTML table manually and return it to the parent row.
I would like to use jQuery DataTable for my detail table so that it will automatically populate the data using the Row.data() as data source. How do you accomplish this?
Thank you.
I'm getting a weird 404 error when populating select2 ajax url with function, outside of this error the function seems to work fine and select2 box is getting populated based on updated urls when the _mvp.commodity_category variable is updated.
Editor field init:
{
label: "Commodity:",
name: "connections.commodity_name",
type: "select2",
"opts": {
delay: 250,
inputclass: 'input-large',
placeholder: "Select a commodity.",
dropdownAutoWidth: true,
dropdownCssClass: "bigdrop",
ajax: {
url: function () {
if(_mvp.commodity_category!=null)
{
return "rest/views/commodity_ids/?category=" + _mvp.commodity_category;
}
return "";
},
dataType: "json",
data: select2_ajax_data,
processResults: connections_commodity_processResults,
cache: true
},
templateSelection: connections_commodity_templateSelection,
escapeMarkup: function (m) { return m; }
}
},
But when i open editor modal I get this weird 404 that returns the entire function as string.
http://devhost/dev/function%20()%20%7B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(_mvp.commodity_category!=null)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22rest/views/commodity_ids/?category=%22%20+%20_mvp.commodity_category;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20}%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22%22;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20}
404 (Not Found)
Hello. I hope this is an easy one but it is driving me nuts.
I have a table getting data from a URL to MySql.
This works fine and has a dropdown for number of records per page.
All I want to do is add some export buttons.
When I add buttons they do not show up and I lose the dropdown.
When I remove the URL parameters the buttons show up and work.
An help please?
<script type="text/javascript" language="javascript" >
$(document).ready(function() {
var table = $('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax":{
url :"employee-grid-data.php", // json datasource
type: "post", // method , by default get
error: function(){ // error handling
$(".example-error").html("");
$("#example").append('<tbody class="example-error"><tr><th colspan="3">No data found in the server</th></tr></tbody>');
$("#example_processing").css("display","none");
}
},
"lengthChange": false,
"buttons": [ 'copy', 'excel', 'pdf', 'colvis' ]
} );
table.buttons().container()
.insertAfter( '#example' );
} );
</script>
Hi,
How can I programmatically select a row after inserting a new one ? (its has be inserted with an ajax call to the DB)
Thanks