jQuery row.child missing on second page - javascript

I created a table using jQuery. I added a row.child which shall be shown after each parent row. On the first page this works fine. But on the second page it is missing.
function format(d) {
return '' +
'<i style=";color:#9b9b9b; font-size:10px; Padding-left:50px"> Vertragsart - ' + d[4] + ' | Intensität - ' + d[5] + '</i>' +
'';
}
var $j = jQuery.noConflict();
$j('document').ready(function () {
var oTable = $j('#position_list').DataTable({
"order": [[0, "desc"]],
"iDisplayLength": 50,
"oLanguage": {
"sLengthMenu": "Zeige _MENU_ Einträge",
"sSearch": "Suche:",
"sInfo": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
"sInfoEmpty": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
"sInfoFiltered": "(gefiltert aus _MAX_ Datensätzen)",
"oPaginate": {
"sNext": "Nächste",
"sPrevious": "Vorherige"
},
},
});
$j('.parentrow').closest('tr').each(function () {
var row = oTable.row(this);
var data = format(row);
row.child(format(row.data())).show();
});
});

The problem is that you are using jQuery to select the rows, but jQuery only has access to the rows currently on the DOM. As it was said in the comments, only the rows of the current page are in the DOM at any given moment, so those are the only rows your code will manipulate.
To run a jQuery selector through the whole table, Datatables API has the $() method. It accepts a jQuery selector that will be run on all tr elements on the table and their descendant elements, returning a jQuery object like jQuery(selector) does.
So you only need to change your jQuery selector for oTable.$(...):
oTable.$('.parentrow').closest('tr').each(function () {
var row = oTable.row(this);
var data = format(row);
row.child(format(row.data())).show();
});

Use drawCallback option or draw event to call your code every time the table is redrawn.
For example:
$j('#position_list').on('draw.dt', function(){
$j('.parentrow').closest('tr').each(function(){
var row = oTable.row(this);
var data = format(row);
row.child(format(row.data())).show();
});
});

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.

How to search an specific button in a grid using webdriverIO

I'm using an ExtJS grid panel. This grid has more than 20 rows of info and I want to search in each row for an icon that represents active mode, using WebdriverIO as a test driver.
How can I search in each row till the test driver finds the first active icon? (Note: the grid I'm testing is hosted on alegra.com).
Consider the following HTML print-screen:
It's hard to know exactly how to do it without knowing which locator you are using but if you first get a list of the rows and then filter them and grab the first match it should do what you are looking for.
public static get rows() { return browser.elements('#someTableId > table > tbody > tr'); }
public static getFirstMatch() {
return this.rows.value.filter((row: WebdriverIO.Element) =>
browser.elementIdElement(row.ELEMENT, 'someLocator').value)[0];
}
This is how i did it
var icon_type = 'delete';
it('Se elimina una factura', function(){
//rellenamos el array de elementos del grid
var elements = browser.getAttribute('#gridInvoices #gridview-1047-table tbody tr .action-icons img:nth-child(7)','class');
//Busca la primera coincidencia en el array con type
var row_num = elements.indexOf(icon_type);
if(row_num === -1){
throw new Error('No se encontraron botones activos del tipo "Eliminar" en todo el grid' )
}else{
$$('#gridInvoices #gridview-1047-table tbody tr')[row_num].click('.action-icons [title="Eliminar"]');
browser.click('=Sí')
};
});

DataTables - oLanguage.sInfo issue

I have a problem with Datatables oLanguage.sInfo. When there are more than 999 entries, the variable TOTAL is wrong.
The main problem is that there is a string undefined inserted.
Eg, it shows not 1 to 50 of 5,601 entries but 1 bis 50 von 5undefined601
$.extend(
$.fn.dataTable.defaults,
{ "oLanguage": { "sInfo": "START bis END von TOTAL Einträgen", ...
}
});
DataTables 1.10.7
More details: http://debug.datatables.net/iqifax
I found how to fix this:
"oLanguage": {
"sThousands": ".",

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