Not sure if this is answering your question but its pretty easy to determine if the current displayed page has a selected row. Use the selector-modifier of {selected: true, page:'current'} with the row() API. For example: http://live.datatables.net/nohobafu/1/edit
There is a selected row on page 3. Click the button to get the selected row count on the current page.
Hi @kthorngren
Nice sample.
First thanks a lot for helping...
In fact I just want to disallow single select button action if the selected row is not in the current recordset (filtered) and displayed.
Sometime, after a row is selected a filter is applied and then the selected row is not yet in the filtered result, but is always selected and buttons clickable...
So I'd like to know if the selected row (record) is included in filtering result data and if yes then draw the page where it is contained...
Regarding your sample I do a test, find the page, display it but after what page displayed after filtering is the first again... I think I do a mistake but don't know what nor where...
I set a table.on( 'search.dt', fct ); as this :
initComplete:
function () {
if (savedSelected) { // used to restore some contextual states
this.api().rows(savedSelected).select();
this.api().state.save();
}
this.api().columns(<?php echo $FilterColumnList; ?>).every( function () {
// show column filter listbox
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 ) {
(d!=null) ? select.append( '<option value="'+d+'">'+d+'</option>' ):'';
});
});
// TRY TO DISPLAY PAGE CONTAINING SELECTED ROW
var p2go=0;
var fct= function () {
var bInSelection=false;
var curSelection = table.rows( { selected: true } );
if ( curSelection.any() ) {
// on verifie si la selection fait partie du recordset resultant
var pc=table.page('last').page() + 1;
table.page( 0 ).draw( 'page' );
if ((curSelection.count() === 1) && (table.row( {selected: true, page:'current'} ).count() !== 1 )) {
table.off('search.dt'); // disallow event
for (p=0; p < pc; p++){
table.page( p ).draw( false );
if (table.row( {selected: true, page:'current'} ).count() === 1 ) {
p2go = p;
bInSelection = true;
break;
}
}
if (! bInSelection) table.row( {selected: true} ).deselect();
table.on( 'search.dt', fct ); // reload .on event
} else {
for(i=0;i<curSelection.count();i++){
table.rows(curSelection[i]).deselect();
}
}
}
if (!bInSelection) {
localStorage.setItem( '<?php echo $TblName.'_'.GetUserID()?>', null );
}
table.page( p2go ).draw( 'page' );
};
table.on( 'search.dt', fct ); // load .on event
}
hi @kevin
I do install row().show()...
The fact is this event is called when filter is changed. So I need to .off(search.dt) before (else turning everytime).
after going to correct record or page (in my old code I was going to the neede page if exist), I do set .on(search.dt, fct) and in finally go everytime to first page.
Thanks for help but I do not understant what's matter and go back to less pretty system unselecting rows when filter change.
Tks
Are you using server side processing (serverSide: true)?
I don't understand why you are going page by page through the Datatable nor why you get the TypeError: table.row(...).show is not a function error. Maybe you can post a link to your page or a test case so we can take a look at what you are doing.
EDIT: I understand why you are going page by page. My comment is that there are better ways where you don't need to page through the table.
@kthorngren
My first answer about row().show() was... after your answer I did install it...
After what, no more error .show() is not a fucntion.
The problem persist what everytime I go back to first page after the correct page has been selected, using page search or .row().show() method
Hi @kthorngren
Last question about row().show()...
I had a look to this function (of course more efficient than scanning pages to go to correct page) but I do not understant what's matter if no row is valid
If selected row is not in the current dataset (a filter exclude it from current criteria selection) what do return row().show() ? null ? ???
You have both the row().show() code along with your original code with your original code executing second. So the end result is going to be whatever your original code is doing. My suggestion is to simplify the function and just use row().show() and eliminate the paging you are doing and eliminate the code toggling the search events. Something like this:
var fct= function () {
if ( table.row( { selected: true } ).count() > 0 ) {
table.row( {selected: true} ).show().draw(false);
}
)};
not more... did you try the link I post ? Go to last page with no filtering set, then select a appartement row, go to page 1 and then apply filter type appartement.... the selected record page is not displayed ...
I simplified your config down to what we are discussing. I grabbed your data from the XHR response in the developer tools and use data to feed the data to Datatables.
The problem with using draw() is it performs a search. That is why you are trying to use .off() and .on(). Using that with the row().show().draw() causes an additional search event which I think occurs directly after you turn the event back on. Maybe using setTimeout with a small value would work to delay the .on() setting.
In the example I use a flag, columnSearched to determine if the column search took place. The example uses the draw event instead of the search event to check for selected rows. The flag is only set to true in the column search event. Otherwise it is set false. This eliminates the infinite loop that happens when using row().show().draw() after a search.
@allan or @colin might be able to provide a better solution.
EDIT: I added some console.log statements so you can see what is happening with the flag.
goto p6 with no column filtering, select #B303, goto p1, filetr appartement... record does not appears
...
Goto p5, select B202 (no filter), then goto p1, filter appartement... p5 is shown but selected is on p4...
...
the page # calculation in .show().draw(false) is correct (in second case 4) but need to substract 1 from the math.floor, because P1 index is 0, not ?
I did (and run correctly)
$.fn.dataTable.Api.register('row().show()', function() {
var page_info = this.table().page.info();
// Get row index
var new_row_index = this.index();
// Row position
var row_position = this.table().rows()[0].indexOf( new_row_index );
// Already on right page ?
if( row_position >= page_info.start && row_position < page_info.end ) {
// Return row object
return this;
}
// Find page number
var page_to_display = Math.floor( row_position / this.table().page.len() );
// Go to that page
this.table().page( --page_to_display );
// Return row object
return this;
});
Thanks for these shared knowledge ..
Last question about this point : How to know If the selected row is in (or not) the resulting data after filtering ?
Edit... sorry but does not run...
I use real case, up to 26 pages.
Select a row studio in page 23, goto page 1, set filter to studio, page to display is set to 20 but should be 2... (last page afeter filter applied)
There is a bug in the rows().show() plugin that, as you mention, it does not consider the filtered table. I used the selector-modifier of {search: 'applied'} to achieve what I think is the correct result. var row_position = this.table().rows( {search: 'applied' })[0].indexOf( new_row_index );
Yep, there's a bug there. Your fix works on the happy path, but it generates an error if the requested row isn't visible. I've raised it internally (DD-1279 for my reference) and we'll report back here when there's an update. Shouldn't be too long.
Answers
Not sure if this is answering your question but its pretty easy to determine if the current displayed page has a selected row. Use the
selector-modifier
of{selected: true, page:'current'}
with therow()
API. For example:http://live.datatables.net/nohobafu/1/edit
There is a selected row on page 3. Click the button to get the selected row count on the current page.
Kevin
Hi @kthorngren
Nice sample.
First thanks a lot for helping...
In fact I just want to disallow single select button action if the selected row is not in the current recordset (filtered) and displayed.
Sometime, after a row is selected a filter is applied and then the selected row is not yet in the filtered result, but is always selected and buttons clickable...
So I'd like to know if the selected row (record) is included in filtering result data and if yes then draw the page where it is contained...
Regarding your sample I do a test, find the page, display it but after what page displayed after filtering is the first again... I think I do a mistake but don't know what nor where...
I set a table.on( 'search.dt', fct ); as this :
I didn't dig to far into your code but if you want to jump to the page with a selected row you can use the row().show() plugin. I updated my example to demonstrate:
http://live.datatables.net/humusiqa/1/edit
Kevin
hi @kthorngren
I see your sample is running good and mine not but I do not understand why.
Thanks
Did you install the row().show() plugin?
Kevin
yet no...
hi @kevin
I do install row().show()...
The fact is this event is called when filter is changed. So I need to .off(search.dt) before (else turning everytime).
after going to correct record or page (in my old code I was going to the neede page if exist), I do set .on(search.dt, fct) and in finally go everytime to first page.
Thanks for help but I do not understant what's matter and go back to less pretty system unselecting rows when filter change.
Tks
Are you using server side processing (serverSide: true)?
I don't understand why you are going page by page through the Datatable nor why you get the
TypeError: table.row(...).show is not a function
error. Maybe you can post a link to your page or a test case so we can take a look at what you are doing.EDIT: I understand why you are going page by page. My comment is that there are better ways where you don't need to page through the table.
Kevin
Are you using the Select extension? I can generate the same error if I remove the select.js from the example:
http://live.datatables.net/litiqasu/1/edit
Kevin
Yes select is (was) linked.
What kind of link to page do you mean? I will construct a tast case and send link asap.
Tks
@kthorngren
or can I give you a log / pass in private mode to acces to current application ?
@kthorngren
My first answer about row().show() was... after your answer I did install it...
After what, no more error .show() is not a fucntion.
The problem persist what everytime I go back to first page after the correct page has been selected, using page search or .row().show() method
Hi @kthorngren
Last question about row().show()...
I had a look to this function (of course more efficient than scanning pages to go to correct page) but I do not understant what's matter if no row is valid
If selected row is not in the current dataset (a filter exclude it from current criteria selection) what do return row().show() ? null ? ???
Are you saying that you need to do something like this?
Kevin
Yes something like that, but dont know il selected is displayable.
I create a small test here : http://2g.appinfo.fr/form/donneesTest.php
for example,
go to page 5
select a row type appartement
goto page 1
set filter to appartement in column type
the selected row does not appears.
code line 240...
( table.row( { selected: true } ).count() > 0 ) should be true but row is not in data pages because filtered...
You have both the
row().show()
code along with your original code with your original code executing second. So the end result is going to be whatever your original code is doing. My suggestion is to simplify the function and just userow().show()
and eliminate the paging you are doing and eliminate the code toggling the search events. Something like this:See if just this code works.
Kevin
Not better...
I just add .off and .on else stack overflow...
Is it working for you now?
Kevin
not more... did you try the link I post ? Go to last page with no filtering set, then select a appartement row, go to page 1 and then apply filter type appartement.... the selected record page is not displayed ...
I did better than that. I built a test case I can work with.
http://live.datatables.net/sijixiho/1/edit
I simplified your config down to what we are discussing. I grabbed your data from the XHR response in the developer tools and use
data
to feed the data to Datatables.The problem with using
draw()
is it performs a search. That is why you are trying to use.off()
and.on()
. Using that with therow().show().draw()
causes an additional search event which I think occurs directly after you turn the event back on. Maybe usingsetTimeout
with a small value would work to delay the.on()
setting.In the example I use a flag,
columnSearched
to determine if the column search took place. The example uses thedraw
event instead of the search event to check for selected rows. The flag is only set totrue
in the column search event. Otherwise it is setfalse
. This eliminates the infinite loop that happens when usingrow().show().draw()
after a search.@allan or @colin might be able to provide a better solution.
EDIT: I added some console.log statements so you can see what is happening with the flag.
Kevin
Another option would be to use
one()
fordraw()
where you setcolumnSearched
totrue
, but I'd say what you've got is good!I keep forgetting about using
You mean like this:
one()
http://live.datatables.net/sijixiho/2/edit
That is a much better and cleaner option.
Kevin
Yep, that's the fella!
It's certainly a handy method.
Hi @kthorngren @colin @allan
Thanks for answers...
Test case have a problem...
goto p6 with no column filtering, select #B303, goto p1, filetr appartement... record does not appears
...
Goto p5, select B202 (no filter), then goto p1, filter appartement... p5 is shown but selected is on p4...
...
the page # calculation in .show().draw(false) is correct (in second case 4) but need to substract 1 from the math.floor, because P1 index is 0, not ?
I did (and run correctly)
Thanks for these shared knowledge ..
Last question about this point : How to know If the selected row is in (or not) the resulting data after filtering ?
Edit... sorry but does not run...
I use real case, up to 26 pages.
Select a row studio in page 23, goto page 1, set filter to studio, page to display is set to 20 but should be 2... (last page afeter filter applied)
No filter set

pages : 23 this.index() : 223
Filter set

pages : 2 this.index() : 223
A can see, this.index does not use the filter expression...
Good find! I updated my test case here:
http://live.datatables.net/sijixiho/5/edit
There is a bug in the rows().show() plugin that, as you mention, it does not consider the filtered table. I used the
selector-modifier
of{search: 'applied'}
to achieve what I think is the correct result.var row_position = this.table().rows( {search: 'applied' })[0].indexOf( new_row_index );
Let me know what you think.
Kevin
@colin if you guys feel this is a bug in the
row().show()
plugin can you update it?Kevin
Yep, there's a bug there. Your fix works on the happy path, but it generates an error if the requested row isn't visible. I've raised it internally (DD-1279 for my reference) and we'll report back here when there's an update. Shouldn't be too long.
Cheers,
Colin