Need help Row details dont work properly
Need help Row details dont work properly
hi
to start sorry if my english is not very good I'm french.
I do not know how to explain that.
I put in my datatable row details ( https://datatables.net/examples/server_side/row_details.html ), but it does not work properly.
in the beginning everything works, on all the lines of my table.
when I change the category (ex: PUBG) it works, I can open row detail for my 3 lines, but when I put back without category (all games), only the first 3 lines work, I can not open row detail for others.
I dont understand why it does not work after.
someone can help me ?
my website : http://ckdn.esy.es/
table page html:
<table id="product_data" class="">
<thead>
<tr>
<th style="width: 28px;" ></th>
<th><i class="far fa-calendar-alt"></i></th>
<th><i class="far fa-user"></i></th>
<th><i class="far fa-gamepad"></i>
<select name="category" id="category" class="form-control">
<option value="">Touts les Jeux</option>
{$envoie} <!-- reçoit la boucle php -->
</select>
</th>
<th>Age</th>
</tr>
</thead>
</table>
script page html
<script type="text/javascript" language="javascript" >
$(document).ready(function (){
load_data();
function load_data(is_category)
{
var dataTable = $('#product_data').DataTable({
"processing":true,
"serverSide":true,
"order":[],
"ajax":{
url:"includes/fetch.php",
type:"POST",
data:{is_category:is_category}
},
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": 1},
{ "data": 2},
{ "data": 3,
"orderable":false,},
{ "data": 4 }
],
"language": {
"processing": "<div id='loader'></div>"
}
});
// affiche plus de détaille annonce
function format ( d ) {
if ( d[5] == '') {
$online = '<div class="steamWidget no-steam">'+
'Statut Steam: <p>Steam Non renseigné</p><br><br>'+
'Description Prochainement</div>';
} else {
if ( d[5] == 'online') {
$online = '<div class="steamWidget online">'+
'Statut Steam:<p>'+d[5]+'</p><br><br>'+
'Description Prochainement</div>';
}
else {
$online = '<div class="steamWidget offline">'+
'Statut Steam:<p>'+d[5]+'</p><br><br>'+
'Description Prochainement</div>';
}
}
return $online;
}
// affiche plus de détaille annonce suite
$(document).on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = dataTable.row( tr );
if ( row.child.isShown() ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
} );
}
// change la catégorie
$(document).on('change', '#category', function(){
var category = $(this).val();
$('#product_data').DataTable().destroy();
if(category != '')
{
load_data(category);
}
else
{
load_data();
}
});
</script>
And my fetch page:
require_once('../includes/config.php');
$connect = new mysqli($CONF['host'], $CONF['user'], $CONF['pass'], $CONF['name']);
if ($connect->connect_errno) {
echo "Failed to connect to MySQL: (" . $connect->connect_errno . ") " . $connect->connect_error;
};
$column = array("","date_add", "username", "category_g_name", "born");
$query = "
SELECT * FROM users U
INNER JOIN users_category UC ON (U.idu = UC.id_users)
INNER JOIN category_games C ON (UC.id_category = C.id)
";
$query .= " WHERE";
$query .= " UC.recherche = 1 AND";
if(isset($_POST["is_category"]))
{
$query .= " id = '".$_POST["is_category"]."' AND ";
}
if(isset($_POST["search"]["value"]))
{
$query .= '(date_add LIKE "%'.$_POST["search"]["value"].'%" ';
$query .= 'OR username LIKE "%'.$_POST["search"]["value"].'%" ';
$query .= 'OR category_g_name LIKE "%'.$_POST["search"]["value"].'%" ';
$query .= 'OR recherche LIKE "%'.$_POST["search"]["value"].'%" ';
$query .= 'OR born LIKE "%'.$_POST["search"]["value"].'%") ';
}
if(isset($_POST["order"]))
{
$query .= 'ORDER BY '.$column[$_POST['order']['0']['column']].' '.$_POST['order']['0']['dir'].' ';
}
else
{
$query .= 'ORDER BY date_add DESC ';
}
$query1 = '';
if($_POST["length"] != 1)
{
$query1 .= 'LIMIT ' . $_POST['start'] . ', ' . $_POST['length'];
}
$number_filter_row = mysqli_num_rows(mysqli_query($connect, $query));
$result = mysqli_query($connect, $query . $query1);
$data = array();
while($row = mysqli_fetch_array($result))
{
if (isset($row["steam"]))
{
$steam = simplexml_load_file("https://steamcommunity.com/profiles/".$row["steam"]."?xml=1", 'SimpleXMLElement', LIBXML_NOCDATA);
$steamstatut = str_replace("<br />", " - ", $steam->onlineState);
} else {
$steamstatut = '';
}
// calcule age user
$ub = explode('-', $row["born"]) ;
$age = date('Y') - $ub[0] ;
if ( date('md') < $ub[1].$ub[2] ) $age-- ;
//calcul nbr de our de l'annonce
$now = new DateTime("now");
$dateBdd = new DateTime($row["date_add"]);
//$date_add = $dateBdd1->diff($now)->format("%d jours, %h heurs and %i minutes");
$date_add = $dateBdd->diff($now);
$jours = $date_add->format("%d jrs");
$heurs = $date_add->format("%h hrs");
$minute = $date_add->format("%i min");
if ($jours == 0 ) {
if ($heurs == 0 ) {
$afficher = $minute;
}
else {
$afficher = $heurs;
}
} else {
$afficher = $jours;
}
$URL = $CONF['url'];
$sub_array = array();
$sub_array[] = '<th></th>';
$sub_array[] = $afficher;
$sub_array[] = $row["username"];
$sub_array[] = $row["category_g_name"];
$sub_array[] = $age. 'ans';
$sub_array[] = $steamstatut;
$data[] = $sub_array;
}
function get_all_data($connect)
{
$query = "SELECT * FROM users_category";
$result = mysqli_query($connect, $query);
return mysqli_num_rows($result);
}
$output = array(
"draw" => intval($_POST["draw"]),
"recordsTotal" => get_all_data($connect),
"recordsFiltered" => $number_filter_row,
"data" => $data
);
echo json_encode($output);
thank a lot
Replies
Hi @laurent09 ,
I just tried this against your site, and child rows were always being opened - for all rows, not just the first three. I did the following steps
Can you give more information please on why you feel it isn't working, and what you expect it should be doing.
Cheers,
Colin
ok I will try to explain. lol
1- I refresh my page only 1 times and just now.
2- I click on the '+' I open all the rows, it's ok everything works all the rows opens.
3- I change the category I put another games.
4- I click on the '+' I open all the rows, it's ok everything works all the rows opens.
5 - I change the category I put the first (" touts les jeux ").
6- I click on the '+' I try to open the first three lines is ok, but the next do not want to display the rows.
I hope you understand me
thanks
Can you be more specific, please. I tried changing the game, but none of the others seem to have any data. If you could say exactly what you press, that would help us to see the same things.
selected the game "PLAYERUNKNOWN'S BATTLEGROUNDS", there are 4 lines, and the rows chill works correctly for the 4 lines.
and after selected in the category games "ALL THE GAMES" in the top of the list games.
there are now all the lines, as in the beginning, but only the first 3 lines work properly when we click on the '+'. the other lines do not work, like on my screen.
I found something else, it's difficult to explain.
1- I refresh my page (ctrl + f5)
2- I click on '+' all the lines work correctly.
3- I select the game 'ARMA 3'.
4- I have 1 result, I click on '+' and I open my row child correctly.
5- I change my game and select 'ALL THE GAMES' in the top
6-I have all my results, I click on '+', and only one row child works.
I can only open 1 row child as when I selected the game 'arma 3'.
7- I refreshed my page (ctrl + f5)
8- I select the game 'PLAYERUNKNOWN'S BATTLEGROUNDS'.
9- I have 4 result, I click on '+' and I open my 4 row child correctly.
10- I change my games and select 'TOUTS LES JEUX' in the top
11- I have all my results, I click on '+', and only 4 row child works.
I can only open 4 row child like when I have selected the PLAYERUNKNOWN'S BATTLEGROUNDS game.
I think maybe the problem is my loaddata ();
je ne sais pas pourquoi.
Hi @laurent09 ,
We worked it out. The problem is because you're destroying the table, but leaving old event handlers lying around that will trigger when the table no longer exists. This was causing these errors in the console:
The solution: instead of using
destroy()
it would be better (in order) to refactor the code to either useajax.reload()
, or,clear()
the table and the reload withrows.add()
, or, useoff()
to remove the event handlers.There's also little point using
serverSide
since your tables are so small - that's only needed when you have thousands of records in a table.Hope that all makes sense,
Cheers,
Colin
really really thank you for your help @colin
a simple $('#product_data').DataTable().ajax.reload(); does not work ?
I am really sorry I beginner.
This should reload your ajax data. Does it not work for you?
Kevin
no it does not work.
when I change the category games I have an error.
my siteweb
http://ckdn.esy.es/
You are getting this error:
Did you read the tech note in the link provided in the error?
Your load_data() function is reinitializing the Datatable each time its called. This is causing the error. In your
ajax
you are passing a data parameter to the server for the desired data.The technote provides a couple options that might work for you.
https://datatables.net/manual/tech-notes/3#retrieve
The first is
retrieve
which should eliminate the error but I'm not sure if the ajax call will use the updated data option. You can try it to see. Along with this option you might need to useclear()
if the table isn't cleared of the previous data.If retrieve doesn't work then you can try the
destroy
option to see if it will work.A better option maybe to use an external ajax call to get the data then use
rows.add()
to add the data to the table. Before that you will need to useclear()
to clear the previous data. Something like this example:http://live.datatables.net/heweruva/6/edit
In all cases above you won't want to use
$('#product_data').DataTable().ajax.reload();
Kevin
yes I read the note.
I already have my table which is destroyed when I change the category at the line 40.
and then he calls my ajax with "load_data ();"
it works well, just as I explained earlier in the comment there is a problem with the child rows.
I am really sorry I am a beginner, I want to understand and learn.
Hi @laurent09 ,
The problem is still the same, it hasn't been fixed, the same error is in the console.
As I said in my last comment, whenever the game is changed, you're creating more and more event handlers like this
You're just adding more and more to the list of event handlers whenever the data is loaded. So by the time you've changed the game twice, that will trigger twice when the '+' is clicked on, and this is causing problems.
The suggestions I made in that last comment will fix it. Hope that helps explain it,
Cheers,
Colin
ok i'm trying to understand i'm sorry but i dont arrive
I saw that every time I send something to my table I have a fetch.php that create it, and when I change games it is not delete it create a second and a third. ..
I am completely lost.
I add " dataTable.ajax.reload(); " when I close the row.child
it works but it's not perfect yet.
Hi @laurent09 ,
Your problem is that you're still calling the event handler multiple times.
Take a look at this very simple example here - the code is very similar to yours. You initialise the data at the start (loadData in your case) and then you create an event handler in that function. But, every time that function is called, you're creating more and more event handlers - see how the count is increasing in my example.
If you look at my message that starts, "We worked it out.", this explains how to avoid the problem and what steps to take.
Cheers,
Colin
yes i saw that my function " load_data(); " create each time a fetch.php
but I dont arrive to replace .destroy(); by .ajax.reload() or .clear() I have errors.
can I reload the function load_data ()?
You don't really need to destroy the table. Indeed, you should only destroy the table if you want to change its structure (e.g. different columns) since there is a fair bit of processing overhead in destroying and then creating a new table.
What I would suggest is that you create the table and add the event handlers only once. Do it with the
ajax.data
option as a function rather than as a static object as you currently have. The advantage of a function is that it will evaluate every time the table's Ajax triggers, so you can reference an external variable:Then to reload the table with different data all you need to do is:
Allan
ok thank you very much, it works I think.
how can I load all the table without category?
I have to do a .ajax.reload (); ?
it's possible to reload my tables?
I tried it with "ajax.reload ();" at the line 91, but it does not work.
What happens with
dataTable.ajax.reload();
?Do you get any errors?
My guess is the the variable `dataTable is local to the load_data function:
You probably should declare it globally, something like this:
And remove
var
from inside the function. If this doesn't help please be more specific of what is not working.Kevin
OK
I tried but it does not change anything.
I have no errors.
when I change the category to " touts les jeux ", it does not work, nothing happens.
I would like to reload the table to display all my data without category, as when I refresh my page the first time.
1 change to "arma 3"
2 change to "touts les jeux"
http://ckdn.esy.es/
Looks like the ajax.reload part of the code is working. The problem is with the request.
When selecting "arma 3" the request has this (from the browser's dev tools):
Category 36.
Next I select "touts les jeux" and the request looks like this - its the next requests as the draw parameter incremented:
But it has category 36, same as the previous. You will need to adjust your Javascript code to provide a category value that will allow you to get all records. And you will need to adjust your server code to handle that particular value the way you want. Again the ajax.reload is working as expected.
Kevin
thank you very much everyone for your help I ended up successful
like this
and in my fetch.php
thanks