Using an event for all tables in one page but only on the rows inside the table clicked
Using an event for all tables in one page but only on the rows inside the table clicked
Link to test case:
Debugger code (debug.datatables.net):
Error messages shown:
Description of problem:
Hi,
I have a page with 8 tables including 4 tables like this one :
https://live.datatables.net/xomujosa/10/edit
I'm using this event to show/hide the months when a row of a trimestrer is clicked.
table2.on('click', '.trimestre', function () {
var id = this.id;
var child = '.child.' + id;
$( child ).toggle();
});
It works but all the tables eare targeted.
If I click on the row « Trimestre 1 », this row will be expand for the 4 similar tables.
I don't know how to target only the table where the row is clicked.
Also, I wish I could write only one function for the 4 tables.
I tried using jQuery like that but it doesn't work on the rows created by the rowgrouping extension (subject already talked about in another thread)
$("#table1 tr.trimestre, #table2 tr.trimestre, #table3 tr.trimestre, #table4 tr.trimestre").click(function(){
var id = this.id;
var child = '.child.' + id;
$( child ).toggle();
});
Thanks for your help
Replies
That suggest the selector
child
in$( child ).toggle();
is not unique on the page. Try changing the selector to include the specific table, for example:Its possible. One way is to use a selector like this:
This example shows how to get the clicked table and row data:
https://live.datatables.net/xojeworo/1/edit
For this solution I think you would use a selector like this:
Kevin
I should mention that I applied the
trimestre
class to only Brielle Williamson row in the first table and Ashton Cox row in the second table. I thought this would help highlight the click event works on different tables.Kevin
Hi Kevin,
Thank you for your example.
I've changed it to try to understand everything and replicate what I want to achieve :
- rowgrouping
- hidding by default the rows inside of the groups (the « childs »)
- I have put the class and IDs I'm using on my page to the rows (using data from the example instead of number of trimesters and months)
- then, add jQuery UI toggle on the groups (the « parents », they have the « trimestre » class) to show/hide the « children ». This part is not added yet because I've already broke the page
https://live.datatables.net/xojeworo/15/edit
Your test case is getting this error:
The row being clicked on is not a Datatables row so the result of this:
is
undefined
.You don't need that statement so remove it and the associated console.log statement.
One problem with your test case is you are creating non-unique IDs on the page. I suspect you don't need to assign or use an ID for the RowGroup rows. Just get the row to use as the selector for
.toggle()
. For example:https://live.datatables.net/lonidako/1/edit
Using
$( groupRow, table ).toggle();
causes the RowGroup row to disappear but I suspect its due to not having the code to handle the toggle. But it shows that only the row clicked is affected.Hope this gets you going. If not please update the test case to include your toggle code.
Kevin
Thanks for the debug Kevin
This is another version reflecting what's going on with my website.
The toggle fucntion is working but on every table
Ex : you click on London, the group London will show/hide the rows relatives to the group but for every table
I if can't target the table in the toogle function, I think I should had the table ID to the rows ID.
https://live.datatables.net/yujefubu/1/edit
Your ids are not unique. That actually makes it invalid HTML. I think you need to find a way to make the ids unique - perhaps prefixing or postfixing the host table's id to the group id.
You can get the table's id using
table.table().node().id
.Allan
Your ids are not unique (e.g. you have two
trimestreLondon
elements). That actually makes it invalid HTML. I think you need to find a way to make the ids unique - perhaps prefixing or postfixing the host table's id to the group id.You can get the table's id using
table.table().node().id
.Allan
Another option to eliminate duplicated ids is to use HTML5 data-* attributes instead. In the click event use jQuery closest() to get the table which will be used as part of the
toggle()
selector to limit the elements to find to just that table.I updated three lines in the test case to change from using
id
to using HTML5 data-* attributes:I changed the
toggle()
selector to this:https://live.datatables.net/yujefubu/2/edit
Now only the group for the particular table toggled open/closed.
BTW, Thanks for the simplified test case. Its much easier to help
Kevin
I knew it and tried to do it earlier but failed.
Believe me I'm trying a lot of things before posting but I'm missing a lot of things because I'm beginning with JS and also my english is not so good. When I read the doc, sometimes I don't even understand the examples
The IDs was not the best idea, Kevin's idea is better on the next post but I didn't think of it.
Using Jquery UI toggle() is a clever solution. I don't think you have this issue because I think all your data is on one page but the toggle only works on the page displayed. There are other solutions on the forum that keep track of the collapsed groups using a variable. Something similar will to happen if you need this to work across multiple pages.
You've learned a lot since you first started posting
Kevin
Yes ! That's the perfect idea I wish I had ! I'm never working with HTML5 data.
I can't wait to try it live.
Thanks Kevin
Thanks, I'm trying to be a better « student »
I have questions to undertsand how this is working (for me, it's like a magician is doing something I can't see).
How does DT know what tables target with this code ?
How do you change the « settings » if the tables are not the same ?
How do it get the right data for each table when using orthogonal data ?
I give you some context to help understand my questionning...
On the live page, I have 2 « model » of tables :
- one displaying 10 years of informations (the one using the toggle on the rowgroup)
- another one displaying the latest year informations
Each « model » of DT is used for one company.
There are 4 companys (for now), so there are 8 DT in the page with different datas.
Before you show me
var tables = new DataTable('table', {...})
, this is how I have write my code and trying to not duplicate things.Creating variables with the maximum of things I could re-use for each table.
For example the columns for the table with 10 years of infos :
And then, for each table writing the minimum. The only thing changing for each DT is the « dataset » and the ID of the HTML table.
Can I replicate this kind of working with
var tables = new DataTable('table', {...})
?Sorry for the long post, I hope it's clear...
Thank you. You're right everything is on the same page but I keep the post bookmarked in case I need to use the other solution.
Thanks, I'm blushing a little but taking the compliment for my JS ego
The
'table'
is a jQuery selector that will find alltable
elements on the page. You could make this more targeted by adding a classname to the selector, for example:'table.datatable'
.You can set Default Settings once on the page to apply to all the Datatables. Each Datatable you define any specific configurations either overriding the defaults or adding to them.
You might be able to do something like this:
For that last table use an empty
createdRow
function and setrowGroup.enable
tofalse
to override the default settings and do nothing. Here is a simple example:https://live.datatables.net/pesocoze/1/edit
Kevin
Thanks for the explanations and advices.
I need to update my page now with all of that !
I already have this defaults setting in a JS file loaded on every page.
Will it works combine with the one you suggested to add without conflict (with the word « extend », I imagine it's like a complement to the existing default settings) ?
The existing default settings for all the website pages :
If I want to combine the settings with the case we've seen before (toggle rows), can I write this ?
And after « declare » the DT with their ID and « dataset »?
The tables won't be created a second time ?
If you initialize some tables with
new DataTable('table.myClass', {
then usenew DataTable('#tableau10ans_BCF', {
and#tableau10ans_BCF
was already initialized with the selectortable.myClass
you will get the Cannot reinitialise DataTable error. You can initialize a Datatable only once.Not sure if I answered your question.
Kevin
Mmmm, I think you answered but I need to try it to be sure.
I will come back after and show you the code so it will be more concrete.
Thanks Kevin.
This is the code WORKING (capitals are sometimes needed !) with all your recommandations. That's really nice to have something I can easily read and change.
Very nice!!
Kevin
Thanks again for your help
Yesterday, I went back to another topic concerning the same page about creating series for a chart for each table and try your suggestion : creating the charts on
initComplete
and it works !See your latest posts in this discussion :
https://datatables.net/forums/discussion/79756/create-a-serie-for-a-chart-with-the-values-of-the-row-grouping#latest
But I have a problem (again...), I don't know how to empy the series between each table.
I think I should clear the series somewhere because they are good for the first table, but cumulate on the next tables (see the screens captures below)
This is how I did it
1) Add this global var before the JS datatables
2) Add the series for the chart in the rowgrouping code
3) Add the chart with the series in the code of each table
As you can see below, it's working almost well
For the first table, its OK
For the others, series of the previous tables are « cumulated »
Sorry if I'm putting the code here but it's not easy to replicate all the page in a test case.
The easiest way is to set
seriesChart10years
to an empty array at the beginning ofrowgroup
start render. For example:seriesChart10years
will remain global setting it this way withoutvar
.This assumes that each Datatable is initialized one after the other. Meaning you aren't using jQuery ajax() to fetch the data for each Datatable which would be an asynchronous process initializing each Datatable.
If you are doing something that causes asynchronous loading of the Datatables then we will need to find a different solution.
Kevin
I've changed the code to clear the series inside Rowgroup like you mentionned.
It's strange, now I only see one group (trimestre) in each table.
Another thing change (for good) : that's the good values for each table (no more « cumul » from table to table)
Company 1
Company 2
I don't think the data for the tables is using an asynchronous process.
At the beginning of the page, there is ORDA request to a database (not inside a JS script). The data is collected in an Array. Then, the array is affected to a JS var before the DT code. This is for example the var for the data of the Company 1.
Don't pay attention to the syntax , it's a specificity (this word exist ?) of the 4D app.
In this case, it's returning something like
Sounds like synchronous loading of the Datatables
Sorry you don't want to add
seriesChart10years = [];
inrowGroup.startRender
. Place it before the initialization code of each table, for example:Kevin
EDIT : I've added more fake data to be sure about the series showing.
For company 2, 3 and 4, only one serie is showing. I think it's always the last one.
It seems logic if after adding seriesChart10years = []; in the StartEnder of RowGroup, no ?
Company 2
Did you see my previous comment to move seriesChart10years = [];?
Kevin
I have deleted all these lines in startEnder (rowgroup)
Also deleted at the beginning of the page
And now, it's only before each table
DId I miss something ?
The first chart is OK, the other ones are cumulating series
I meant to only delete
seriesChart10years = [];
fromrowGroup.startRender
. I believe you still need to clear thevar serie1 = {};
variables for each group.Probably doesn't matter in your case but I would put it back so there is a global reference to that variable.
Kevin
Ok, I think everything is in its right place now.
That's all the JS code between
<script>
and</script>
, I have put some « ... » on the parts we don't need here to try to reduce le volume of the post.(if I put this is the livedatatable tools, there is too many errors, it need adaptations)
If I didn't make mistake, I don't understand what's happening.
Could it be using
$(document).ready
?I found it : I put
seriesChart10years = [];
only in theinit- footerCallback
and all the charts are ok now.Thanks again for your help.