dataTables make <tr> clickable to link - datatables

I have a dataTables table at http://communitychessclub.com/test.php
My problem is I need to make an entire table row clickable to a link based on a game#. The table lists games and user should click on a row and the actual game loads.
I am unable to understand the previous solutions to this problem. Can somebody please explain this in simple terms?
I previously did this at http://communitychessclub.com/games.php (but that version is too verbose and does disk writes with php echo)
with
echo "<tr onclick=\"location.href='basic.php?game=$game'\" >";
<script>$(document).ready(function() {
$('#cccr').dataTable( {
"ajax": "cccr.json",
"columnDefs": [
{
"targets": [ 0 ],
"visible": false,
}
],
"columns": [
{ "data": "game" },
{ "data": "date" },
{ "data": "event" },
{ "data": "eco" },
{ "data": "white_rating" },
{ "data": "white" },
{ "data": "black_rating" },
{ "data": "black" }
]
} );
} );</script>
"cccr.json" looks like this and is fine:
{
"data": [
{
"game": "5086",
"date": "09/02/2013",
"event": "135th NYS Ch.",
"eco": "B08",
"white": "Jones, Robert",
"white_rating": "2393",
"black": "Spade, Sam",
"black_rating": "2268"
},
...

You can do it this way:
Use fnRowCallback to add a game-id data-attribute to your datatable rows
...
{ "data": "black" }
],
"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
//var id = aData[0];
var id = aData.game;
$(nRow).attr("data-game-id", id);
return nRow;
}
This will give each row in your table a game id attribute e.g:
<tr class="odd" data-game-id="5086">
Then create a javascript listener for the click event and redirect to the game page passing the game id taken from the tr data-attribute:
$('#cccr tbody').on('click', 'tr', function () {
var id = $(this).data("game-id");
window.location = 'basic.php?game=' + id;
}

Related

Mimic the ( Show All ) link in datatables.net

I have a situation where I want to get the full (data) from the backend as a CSV file. I have already prepared the backend for that, but normally the front-end state => (filters) is not in contact with the backend unless I send a request, so I managed to solve the problem by mimicking the process of showing all data but by a custom button and a GET request ( not an ajax request ). knowing that I am using serverSide: true in datatables.
I prepared the backend to receive a request like ( Show All ) but I want that link to be sent by custom button ( Export All ) not by the show process itself as by the picture down because showing all data is not practical at all.
This is the code for the custom button
{
text: "Export All",
action: function (e, dt, node, config) {
// get the backend file here
},
},
So, How could I send a request like the same request sent by ( Show All ) by a custom button, I prepared the server to respond by the CSV file. but I need a way to get the same link to send a get request ( not by ajax ) by the same link that Show All sends?
If you are using serverSide: true that should mean you have too much data to use the default (serverSide: false) - because the browser/DataTables cannot handle the volume. For this reason I would say you should also not try to use the browser to generate a full export - it's going to be too much data (otherwise, why did you choose to use serverSide: true?).
Instead, use a server-side export utility - not DataTables.
But if you still want to pursuse this approach, you can build a custom button which downloads the entire data set to the DataTables (in your browser) and then exports that complete data to Excel.
Full Disclosure:
The following approach is inspired by the following DataTables forum post:
Customizing the data from export buttons
The following approach requires you to have a separate REST endpoint which delivers the entire data set as a JSON response (by contrast, the standard response should only be one page of data for the actual table data display and pagination.)
How you set up this endpoint is up to you (in Laravel, in your case).
Step 1: Create a custom button:
I tested with Excel, but you can do CSV, if you prefer.
buttons: [
{
extend: 'excelHtml5', // or 'csvHtml5'
text: 'All Data to Excel', // or CSV if you prefer
exportOptions: {
customizeData: function (d) {
var exportBody = getDataToExport();
d.body.length = 0;
d.body.push.apply(d.body, exportBody);
}
}
}
],
Step 2: The export function, used by the above button:
function GetDataToExport() {
var jsonResult = $.ajax({
url: '[your_GET_EVERYTHING_url_goes_here]',
success: function (result) {},
async: false
});
var exportBody = jsonResult.responseJSON.data;
return exportBody.map(function (el) {
return Object.keys(el).map(function (key) {
return el[key]
});
});
}
In the above code, my assumption is that the JSON response has the standard DataTables object structure - so, something like:
{
"data": [
{
"id": "1",
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "$320,800",
"start_date": "2011/04/25",
"office": "Edinburgh",
"extn": "5421"
},
{
"id": "2",
"name": "Garrett Winters",
"position": "Accountant",
"salary": "$170,750",
"start_date": "2011/07/25",
"office": "Tokyo",
"extn": "8422"
},
{
"id": "3",
"name": "Ashton Cox",
"position": "Junior Technical Author",
"salary": "$86,000",
"start_date": "2009/01/12",
"office": "San Francisco",
"extn": "1562"
}
]
}
So, it's an object, containing a data array.
The DataTables customizeData function is what controls writing this complete JSON to the Excel file.
Overall, your DataTables code will look something like this:
$(document).ready(function() {
$('#example').DataTable( {
serverSide: true,
dom: 'Brftip',
buttons: [
{
extend: 'excelHtml5',
text: 'All Data to Excel',
exportOptions: {
customizeData: function (d) {
var exportBody = GetDataToExport();
d.body.length = 0;
d.body.push.apply(d.body, exportBody);
}
}
}
],
ajax: {
url: "[your_SINGLE_PAGE_url_goes_here]"
},
"columns": [
{ "title": "ID", "data": "id" },
{ "title": "Name", "data": "name" },
{ "title": "Position", "data": "position" },
{ "title": "Salary", "data": "salary" },
{ "title": "Start Date", "data": "start_date" },
{ "title": "Office", "data": "office" },
{ "title": "Extn.", "data": "extn" }
]
} );
} );
function GetDataToExport() {
var jsonResult = $.ajax({
url: '[your_GET_EVERYTHING_url_goes_here]',
success: function (result) {},
async: false
});
var exportBody = jsonResult.responseJSON.data;
return exportBody.map(function (el) {
return Object.keys(el).map(function (key) {
return el[key]
});
});
}
Just to repeat my initial warning: This is probably a bad idea, if you really needed to use serverSide: true because of the volume of data you have.
Use a server-side export tool instead - I'm sure Laravel/PHP has good support for generating Excel files.

Error creating protected columns with google sheet create api

I am following the google sheet v4 api doumentation to create google sheet with protected columns (https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/create)
I am able to create sheet without using protectedRange in api, using it always gives error, below are request /response i am getting
"properties": {
"title": "NEW SHEET"
},
"sheets": [
{
"data": [
{
"rowData": [
{
"values": [
{
"userEnteredValue": {
"numberValue": 10
}
},
{
"userEnteredValue": {
"numberValue": 20
}
},
{
"userEnteredValue": {
"numberValue": 30
}
}
]
}
]
}
]
},
{
"protectedRanges": [
{
"description": "Locked columns",
"range": {
"sheetId": 0,
"startColumnIndex": 0,
"endColumnIndex": 2
}
}
]
}
]
}
response
{
"error": {
"code": 400,
"message": "Invalid sheets[1].protectedRanges[0]: No grid with id: 0",
"status": "INVALID_ARGUMENT"
}
}
You want to create new Spreadsheet.
When the new Spreadsheet is created, you want to add the protected ranges.
In your sample, you want to create new Spreadsheet including a sheet which has the protected columns "A" and "B" and values of 10, 20, 30 in the cells "A1:C1".
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Issue and solution:
In your request body, please include the property of protectedRanges to the 1st index of sheets.
Please set the sheet ID at properties.
Modified request body:
{
"properties": {
"title": "NEW SHEET"
},
"sheets": [
{
"data": [
{
"rowData": [
{
"values": [
{
"userEnteredValue": {
"numberValue": 10
}
},
{
"userEnteredValue": {
"numberValue": 20
}
},
{
"userEnteredValue": {
"numberValue": 30
}
}
]
}
]
}
],
"protectedRanges": [
{
"description": "Locked columns",
"range": {
"startColumnIndex": 0,
"endColumnIndex": 2,
"sheetId": 0
}
}
],
"properties": {
"sheetId": 0
}
}
]
}
For example, when "sheetId": 123 is set, the sheet is created as the sheet ID of 123.
You can also test above request body at Try this API.
Reference:
Method: spreadsheets.create
If I misunderstood your question and this was not the direction you want, I apologize.

Datatables with nested array

I've posed a question about Bootstrap Tables but meanwhile I moved to Datatables as I was feeling blocked. My problem, however, is the same.
None of the two can easily handle nested JSON results. For instance if I choose "field: author", it processes the following as "[Object Object], [Object Object]".
"author": [
{
"family": "Obama",
"given": "Barack"
},
{
"family": "Obama",
"given": "Michelle"
}
I can select the results individually, say "field: author[, ].family", which returns a list like "Obama, Obama". But I want an output like "given+family1, given+family2, ..".
You can use custom rendering. DataTables allows you to define custom rendering for each column.
Here is a sample that I worked out. I am doing custom rendering for Author column.
$(document).ready(function() {
var dataSet = [
{ "name": "How to DataTables", "author": [{ "firstname": "jack", lastname: "d" }, { "firstname": "dick", lastname: "j" }] },
{ "name": "How to Custom Render", "author": [{ "firstname": "bill", lastname: "g" }, { "firstname": "scott", lastname: "g" }] }
];
$('#example').DataTable({
data: dataSet,
columns: [
{ title:"Book Name",
data: "name" },
{
title: "Authors",
data: "author",
render: function(data, type, row) {
//return data.length;
var txt = '';
data.forEach(function(item) {
if (txt.length > 0) {
txt += ', '
}
txt += item.firstname + ' ' + item.lastname;
});
return txt;
}
}
]
});
});

Use object instead of array in datatables

When using datatables, I get 'no data available in table' when using an object instead of array:
var data1 =
{
"status": "success",
"districts": {
"1": {
"district_number": "1",
"district_name": "district one"
},
"2": {
"district_number": "2",
"district_name": "district two"
}
},
"time": "1.109s"
};
var table1 = jQuery("#data_table1").DataTable({
"data": data1.districts,
"aoColumns": [
{ "mData": "district_number" },
{ "mData": "district_name" }
]
});
I can get an array to display in a datatable using mData as follows:
var data2 =
{
"status": "success",
"districts": [
{
"district_number": "1",
"district_name": "district one"
},
{
"district_number": "2",
"district_name": "district two"
}
],
"time": "1.109s"
};
var table2 = jQuery("#data_table2").DataTable({
"data": data2.districts,
"aoColumns": [
{ "mData": "district_number" },
{ "mData": "district_name" }
]
});
https://jsfiddle.net/w93gubLv/
Is there a way to get datatables to utilize the object in the original format, or must I convert the object to an array?
You can write your own function to convert one format to another, for example:
function formatData(data){
var result = [];
for(prop in data){
if(data.hasOwnProperty(prop)){
result.push( data[prop] );
}
}
return result;
}
You can then later use it to pass data to jQuery DataTables as shown below.
var table1 = jQuery("#data_table1").DataTable({
"data": formatData(data1.districts),
"aoColumns": [
{ "mData": "district_number" },
{ "mData": "district_name" }
]
});
See updated jsFiddle for code and demonstration.

How DataTables determine columns type

I have a dynamic table enhanced by jQuery DataTables, which display a custom object similar to this example.
JSON:
{
"data": [
{
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "$320,800",
"start_date": {
"display": "SomeString",
"timestamp": 1303686000
},
"office": "Edinburgh",
"extn": "5421"
},
// ... skipped ...
]}
JavaScript:
$(document).ready(function() {
$('#example').DataTable( {
ajax: "data/orthogonal.txt",
columns: [
{ data: "name" },
{ data: "position" },
{ data: "office" },
{ data: "extn" },
{ data: {
_: "start_date.display",
sort: "start_date.timestamp"
} },
{ data: "salary" }
]
} );
} );
The difference is that I dynamically build the columns configuration, because the columns can be in any order, and others columns can be added or removed from the list. For this example (my case is very similar) the problem is that for some reason the timestamp property is ordered as a String instead of being ordered as a number.
I discovered that after setting the column "type" as "number" the ordering works perfectly. I'm presuming that DataTables is auto detecting the column as "String" for some reason (maybe because the display element is a string).
How does DataTables set the type of the columns, when is not explicitly declared?
Edit 1
I made a sample code to show the problem
http://jsfiddle.net/Teles/agrLjd2n/16/
jQuery DataTables has built-in mechanism for type detection. There are multiple predefined functions for various types with fallback to string data type.
It's also possible to use third-party plug-ins or write your own.
There are multiple ways to specify data type, below are just the few.
SOLUTION 1
Use type option.
$(document).ready(function() {
$('#example').DataTable( {
ajax: "data/orthogonal.txt",
columns: [
{ data: "name" },
{ data: "position" },
{ data: "office" },
{ data: "extn" },
{ data: "start_date.display", type: "date" },
{ data: "salary" }
]
} );
} );
SOLUTION 2
Use returned JSON data for type detection, see columns.data for more information.
$(document).ready(function() {
$('#example').DataTable( {
ajax: "data/orthogonal.txt",
columns: [
{ data: "name" },
{ data: "position" },
{ data: "office" },
{ data: "extn" },
{ data: {
_: "start_date.display",
sort: "start_date.timestamp",
type: "start_date.timestamp",
} },
{ data: "salary" }
]
} );
} );
DataTables always check the "type" property of the column "data" to auto detect the type of the column, if no "type" property is specified it will check the default value "_".
So if you want DataTables to auto detect the type of the column checking the type of your "sort" property you should set the "type" property of data to be equals to your "sort" value
Here is a sample code with different approchs to achieve what I was tryng to do. Thanks #Gyrocode.com and #davidkonrad.
var Cell = function(display, value) {
this.display = display;
this.value = value;
}
$(document).ready(function() {
var cells = [
new Cell("120 (10%)", 120),
new Cell("60 (5%)", 60),
new Cell("30 (2.5%)", 30)
];
$('#example').DataTable( {
data: cells,
columns: [
{
title : "Column NOT OK",
data: {
_: "display",
sort: "value"
}
}, {
type : "num",
title : "Column Ok setting column type",
data: {
_: "display",
sort: "value"
}
}, {
title : "Column Ok changing default value",
data: {
_: "value",
display: "display",
filter: "display"
}
}, {
title : "Column Ok setting data type",
data: {
_: "display",
sort: "value",
type: "value"
}
}, {
type : "num",
title : "Column Not OK",
data: "display"
}
]
} );
} );