jQuery DataTable exact match - javascript

I have this jQuery datatable in place:
var $dataTable = $('#example1').DataTable({
"ajax": serviceUrl,
"iDisplayLength": 25,
"order": [[ 2, "asc" ]],
"scrollY": 600,
"scrollX": true,
"bDestroy": true
});
I also have this CHANGE event happening when the user selects an option in a dropdown:
$('#serviceload').on('change',function()
{
$dataTable.columns(1).search( this.value ).draw();
});
I need to be able to alter the CHANGE event so that it searches the DataTable for the exact match in the dropdown.
For example, the v has 2 services called SERV and SERV_ONE. In the dropdown, both SERV and SERV_ONE are available for the user to choose, but if the user chooses SERV, the datatable filters for SERV and also displays the records for SERV_ONE. But when SERV_ONE is chosen, the DataTable only displays the records for SERV_ONE.

See this example for proper use of drop-down filters.
$('#serviceload').on('change keyup', function(){
var val = $.fn.dataTable.util.escapeRegex($(this).val());
$dataTable
.columns(1)
.search( val ? '^' + val + '$' : '', true, false )
.draw();
});

Related

DataTables - Sorting not working after content update

I'm using DataTables (version 1.10.18) and I'm updating rows and its content via jQuery.
My table is initalized with this code:
$(".summary").append(tableContent);
var otable = $('.summary').DataTable({
initComplete: function () {
this.api().columns([0, 1, 2, 3]).every(function () {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo($(column.footer()).empty())
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
});
},
"pageLength": records_per_page,
"language": {
"url": "//cdn.datatables.net/plug-ins/1.10.16/i18n/Italian.json"
},
"order": [[0, 'desc']],
"ordering": true,
"scrollX": true,
"scrollY":"50vh",
"searching":false,
"info":false,
"paging": false
});
Then I've an input field that searches in a SharePoint list (via Rest API). So I make an AJAX call, I get the response from SharePoint web service and I prepare HTML code with new data (some data returned from web services needs to be modified). Finally I update the table content using this code:
var otable = $('.summary).DataTable();
otable.clear().draw();
$(".dataTables_scrollBody>.summary").append(newContent);
otable.rows().invalidate().draw();
newContent is something like:
newContent = "<tbody><tr><td>content</td><td>content</td></tr></tbody>";
Content is updating correctly and sorting arrows are visible in the table header, they are also changing their own active status (desc or asc) but content is not sorted.
I've tried a lot of solutions found online but no one is working for me. In the content update section I'm also adding rows using .append() method.
Is there a way to fix this?
i would suggest, instead of appending the row, you should use the https://datatables.net/reference/api/row.add() add method which is exposed by datatable api. This will automatically apply all the initial settings to new added row.

JS Datatables - filtering table from combo box in header

I have the following datatable which uses the js datatable plugin from https://datatables.net/
The datatable is set using the following JS:
$(document).ready(function () {
$('#tracerTable').DataTable({
"bInfo": false,
"order": [[2, "desc"]], //order by date created
"aoColumnDefs": [
{ aTargets: [3], "bSortable": false },
{ aTargets: [4], "bSortable": false },
{ aTargets: [5], "bSortable": false }
]
});
}
Question:
Is it possible to update the JS to allow me to filter on the 'Type' column using a dropdown with tickbox options within in the table header (just like the filter option in excel - see image below). I would want this for selecting Water and Oil Tracers, but not showing Gas tracers.
If this is not possible within the datatable plugin, can anyone suggest a plugin which would provide this functionality?
Make use of the bootstrap-select plugin, append it to the header of your DataTables by targeting the desired column (in your case 1), get the checked values, join it with | (the or operand) then use search API.
var table = $('#example').DataTable({
initComplete: function() {
this.api().columns([1]).every(function() {
var column = this;
var select = $('<select class="selectpicker" data-show-content="false" data-none-selected-text="Position" multiple><option value="" >Show All</option></select>')
.appendTo($(column.header()).empty())//use $(column.footer() to append it to the table footer instead
.on('changed.bs.select', function(e) {
var val = $(this).val();
var fVal = val.join("|")
column
.search(fVal, true, false)
.draw();
}); //select
column.data().unique().sort().each(function(d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
}); //column.data
}); //this.api
} //initComplete
});
Fiddle for more details, I suggest moving the filter function on the footer as clicking the dropdown button on the table header will sort the table.

DataTables - Getting the database ID of the current row via click event

I am trying to get the database ID of the current row while clicking a button.
I have seen a few examples relating to this aspect and have tried many but it seems that they mostly relate to the legacy table tools extension whereas I am making use of the Editor.
Using the idSrc option from the Editor manual I recieve a server side response in JSON that contains the databases id/primary key value:
{
"data":[
{
"id":"1",
"name":"Test Name",
}
],
"options":[],
"files":[]
}
Now I am trying to get that value by clicking a button that is attached to row via the API function: row().id()
Within the example for this function it provides a clear example of how the rows id value (now the database id?) can be obtained:
var table = $('#myTable').DataTable();
$('#myTable').on( 'click', 'tr', function () {
var id = table.row( this ).id();
alert( 'Clicked row id '+id );
});
So I have implemented this as follows:
var editor;
$(document).ready(function() {
editor = new $.fn.dataTable.Editor( {
ajax: "/names.php",
table: "#example",
idSrc: "id",
fields: [ {
label: "Name:",
name: "name"
} ]
});
var table = $('#example').DataTable( {
dom: "Bfrtip",
ajax: "/names.php",
columns: [
{ data: "name" }
]
});
$('#example').on( 'click', 'tr', function () {
var id = table.row( this ).id();
alert( 'Clicked row id ' + id );
});
});
The problem here though is that when I click on the row (tr) it prompts as follows: Clicked row id undefined
Why am I getting back an undefined value when it should be sending back the row id?
When instances your DataTable, you must indicate the id field rowId, which should be indicated as the name of your columns
var table = $('#example').DataTable( {
dom: "Bfrtip",
ajax: "/names.php",
columns: [
{ data : "id" },//id is the name of your data
{ data: "name" }
],
rowId: 'id' //Here assign the id to your table
});
Result: https://jsfiddle.net/cmedina/7kfmyw6x/17/
As #CMedina pointed out, rowId stipulates which value in the JSON data is used as each rows id attribute.
Here is the code used to get the rows ID value which is prefixed with row_:
$('#example').on( 'click', 'tr', function () {
// Get the rows id value
var id = table.row( this ).id();
// Filter for only numbers
id = id.replace(/\D/g, '');
// Transform to numeric value
id = parseInt(id, 10);
// So instead of returning the actual id which is row_1
// We get back just the primary key which is 1
alert( 'Clicked row id '+id );
});

In JQGrid, How can I dynamically get the column header label when validating a filtertoolbar field?

I have a jqGrid with the filtertoolbar option enabled. For a column or columns in the grid, I want to validate the column in some fashion, e.g., if an input field exceeds a certain length, display an alert.
When I display an alert, I want to display the column header label in colNames to a user, not the colmodel name for that input field, as that will be clearer to the user. I have a jsfiddle example with a simple example for the "Client Name" field. "Client Name" is hard-coded in the alert message. Ideally, I don't want to hard-code the label as it could change, e.g., "Client Name" could be changed to "Customer Name". I don't want to go back into the function to change it each time. Changing it in one place is trivial, but I may have a grid with several columns and associated functions involving the filter toolbar fields, and changing the labels across everywhere is inefficient.
I have searched the jqGrid documentation but have not found a function to do this. I know that the column labels are enclosed in divs named as jqgh_{grid name}_{column name}, e.g., jqgh_test1_name in the jsfiddle, and I can get the div contents, but I would have to parse out the label from the rest of the content, which seems like more work than is needed. Is there a built-in capability in jqGrid to do this, or will I have to parse the label from the div, or is there another approach that I can take?
Thanks in advance...
<table id="test1"></table>
.ui-widget { font-size: 0.8em }
$("#test1").jqGrid({
datatype: "local",
height: 250,
colNames:['Inv No','Date', 'Client Name', 'Amount','Tax','Total','Notes'],
colModel:[
{name:'id',index:'id', width:60, sorttype:"int"},
{name:'invdate',index:'invdate', width:90, sorttype:"date", formatter: 'date', formatoptions: {newformat: 'm/d/Y', srcformat: 'Y-m-d'}},
{name:'name',index:'name', width:100},
{name:'amount',index:'amount', width:80, align:"right",sorttype:"float"},
{name:'tax',index:'tax', width:80, align:"right",sorttype:"float"},
{name:'total',index:'total', width:80,align:"right",sorttype:"float"},
{name:'note',index:'note', width:150, sortable:false}
],
multiselect: true,
caption: "Manipulating Array Data"
});
$("#test1").jqGrid('filterToolbar', {
autosearch: true,
stringResult: false,
searchOnEnter: true,
defaultSearch: "cn",
});
var maxNameLength = 10;
$("input[id=gs_name]").blur(function () {
if (this.value.length > maxNameLength) {
alert('Client Name is longer than ' + maxNameLength + ' characters.');
}
});
$('#gs_invdate').datepicker({
changeMonth: true,
changeYear: true,
showButtonPanel: true
});
var mydata = [
{id:"1",invdate:"2007-10-01",name:"test",note:"note",amount:"200.00",tax:"10.00",total:"210.00"},
{id:"2",invdate:"2007-10-02",name:"test2",note:"note2",amount:"300.00",tax:"20.00",total:"320.00"},
{id:"3",invdate:"2007-09-01",name:"test3",note:"note3",amount:"400.00",tax:"30.00",total:"430.00"},
{id:"4",invdate:"2007-10-04",name:"test",note:"note",amount:"200.00",tax:"10.00",total:"210.00"},
{id:"5",invdate:"2007-10-05",name:"test2",note:"note2",amount:"300.00",tax:"20.00",total:"320.00"},
{id:"6",invdate:"2007-09-06",name:"test3",note:"note3",amount:"400.00",tax:"30.00",total:"430.00"},
{id:"7",invdate:"2007-10-04",name:"test",note:"note",amount:"200.00",tax:"10.00",total:"210.00"},
{id:"8",invdate:"2007-10-03",name:"test2",note:"note2",amount:"300.00",tax:"20.00",total:"320.00"},
{id:"9",invdate:"2007-09-01",name:"test3",note:"note3",amount:"400.00",tax:"30.00",total:"430.00"}
];
for(var i=0;i<=mydata.length;i++)
$("#test1").jqGrid('addRowData',i+1,mydata[i]);
There are many ways to implement your requirement the modified demo http://jsfiddle.net/OlegKi/ejnrtocw/20/ for example use the following code for example
$("input[id=gs_name]").blur(function () {
var $th = $(this).closest(".ui-search-toolbar>th"),
colIndex = $th[0].cellIndex,
$colHeader = $th.parent().siblings(".ui-jqgrid-labels").children("th").eq(colIndex),
colHeaderText = $colHeader.children("div").text();
if (this.value.length > maxNameLength) {
alert(colHeaderText + ' is longer than ' + maxNameLength + ' characters.');
}
});
where the first two lines are the mostly important. colIndex exists in every <td> and <th> element and gives us the position (0-based) in the patent. So colIndex is the column index So one can use it as the index of colNames parameter to access the column text:
$("input[id=gs_name]").blur(function () {
var $th = $(this).closest(".ui-search-toolbar>th"),
colIndex = $th[0].cellIndex,
p = $("#test1").jqGrid("getGridParam"),
colHeaderText = p.colNames[colIndex];
if (this.value.length > maxNameLength) {
alert(colHeaderText + ' is longer than ' + maxNameLength + ' characters.');
}
});
See the next demo http://jsfiddle.net/OlegKi/ejnrtocw/21/

showing 1 to 10 entries of 100 not showing in jquery datatable

I am facing two problems with the jquery JS.
1 . (I have my default display length in the show '10' entries to be defaulted to 10). So for the first 10 records my logic works fine. When I click on next button and navigate to the remaining paginated records and click on any data row, my logic is not working.
<table>
<c: forEach items="${tdetails}" var="tdetail" varStatus="loop">
<tr>
<td>${loop.index+1}</td>
<td><a tag name="det12" id="delhi" href="#" >${tdetail.empNumber}</a></td>
<td>${tdetail.empName}</td>
<td>${tdetail.empDate}</td>
<td>${tdetail.empStatus}</td>
</tr>
</c:forEach>
</table>
<form id="employeeform" action="./getEmployeeStatusDisplay" method="get">
<input type="hidden" id="empNumber" name="empNumber" value="${tdetail.empNumber}">
</form>
2 . "Showing 1 to 10 of 100 entries" is not getting displayed. I am using the following code.
$(document).ready(function(){
$('#detailstable').dataTable({
"bFilter": false,
"bInfo": false,
"bAutoWidth": false,
"bSortClasses": false,
"displayLength":10,
"oLanguage": {
"sInfo": "Showing START to END of TOTAL entries",
"sZeroRecords": "No data to show" },
"sDom": 'T<"clear">lfrtip'
});
$('td a[name="det12"]').click(function(){
alert("inside JS");
id=$(this).text();
alert(id);
$('#empNumber').val(id);
$.blockUI({
message: $('#spinnerbox'),
css: {
margin:'0px auto'
}
});
$("#spinner").show();
$("#employeeform").submit();
});
});
As you can see, when i click on the first column ${tdetail.empNumber} of the datatable which is href tag, it should invoke the 'det12' JS which results in displaying another form ('employeeform.jsp'). The problem is only for the first 10 datarows this logic is working fine, for the remaining 11 to 100 records this doesnt work.
It doesnt work because the <td> click function is resetted each time a new page is shown in the dataTable, and you only does $('td a[name="det12"]').click(function(){ once (thats why it works with the first page, rows 1-10). One way to solve this is by setting the trigger each time the datatable is redrawn (that is, when the user clicks on another page) the callback function fnDrawCallback can be used for that :
$('#detailstable').dataTable({
"bFilter": false,
"bInfo": false,
"bAutoWidth": false,
"bSortClasses": false,
"displayLength":10,
"oLanguage": {
"sInfo": "Showing START to END of TOTAL entries",
"sZeroRecords": "No data to show"
},
"sDom": 'T<"clear">lfrtip',
fnDrawCallback : function() {
$('td a[name="det12"]').click(function(){
alert("inside JS");
id=$(this).text();
alert(id);
$('#empNumber').val(id); $.blockUI({ message: $('#spinnerbox'), css: { margin:'0px auto' } });
$("#spinner").show();
$("#employeeform").submit();
})
}
});
see demo -> http://jsfiddle.net/hf1zqpoz/ I cannot reproduce your setup entirely, but click through the pages, and click on records with the content "Trident".
It looks like some thread (which may have been previously invoked not destroyed properly) would have been creating these kind of problems. So i tried the following in the script tag of my JSP file. Then it is working fine. Hope this helps someone who is facing similar issue like this.
$('#detailstable').dataTable({
"bFilter": false,
"bInfo": false,
"bAutoWidth": false,
"bSortClasses": false,
"displayLength":10,
});
var bindLinks = function(){
$('td a[name="det12"]').click(function(){
id=$(this).text();
$('#empNumber').val(id);
$("#employeeform").submit();
});
};
$("#detailstable").bind("draw.dt", function(){
bind();
});
});
Great forum. Thanks guys.

Categories

Resources