I'm using Datatables plugin in one school project. But I can not make it work server side version. In the client side version I have some crud botons to manage the data. But I can not achieve to put that buttons in the sever side version. I try to use it with mRender wich aloud me create HTML objects. But I want to put some data array value inside this string. But I can't make it. Can someone help me with this one please.
This es what I try.
<script type="text/javascript">
$(document).ready(function () {
$('#mita').DataTable({
"columns": [
{"data": "llave"},
{"mRender": function ( data, type, full ) {
return 'Download';}},// Problem Here !!!
{"data": "llave"},
{"data": "titulo"},
{"data": "titulo"},
{"data": "fecha_inicio"},
{"data": "fecha_fin"},
{"data": "fecha_fin"},
{"data": "fecha_fin"},
{"data": "fecha_fin"}
],
"processing": true,
"serverSide": true,
"order": [[ 0, "desc" ]],
"ajax": {
url: 'demo2.php',
type: 'POST'
}
});
});
</script>
This fix maybe help you , try this :
<script type="text/javascript">
$(document).ready(function () {
$('#mita').DataTable({
"columns": [
{"data": "llave",
"render": function ( data, type, full, meta ) {
return 'Download';
}
},
{"data": "llave"},
{"data": "titulo"},
{"data": "titulo"},
{"data": "fecha_inicio"},
{"data": "fecha_fin"},
{"data": "fecha_fin"},
{"data": "fecha_fin"},
{"data": "fecha_fin"}
],
"processing": true,
"serverSide": true,
"order": [[ 0, "desc" ]],
"ajax": {
url: 'demo2.php',
type: 'POST'
}
});
});
Related
hey guys i have a problem with Datatable plugin
the problem is that i can't select the checkbox in the action column to convert it into bootstrap-toggle
it was working before but when i use the serverside of datatable and declare the checkbox in the controller nothing works (Sorry for my english )
please help!!
this is the controller code
return DataTables::of($participant)
->addColumn('action',function($participant){
$route = route('admin.participant.presence',$participant);
return '<form action="'.$route.'" method="PATCH">
<input type="hidden" name="presence" value="0">
<input type="checkbox" class="participation" onchange="this.form.submit()" '.isChecked($participant).' name="presence" value="1">
</form>';
})->make(true);
and here's the js code in the view and I think the problem comes from here
<script>
$(document).ready( function(){
var id = {{request()->route('id')}};
$('#table').DataTable({
"processing": true,
"serverSide": true,
"ajax": "/admin/evenment/event/participant/ajaxdatatable/"+id,
"columns":[
{"data": "adherent_id"},
{"data": "nom_participant"},
{"data": "prenom_participant"},
{"data": "fonction"},
{"data": "action"},
]
});
$('.participation').bootstrapToggle({
on: 'Oui',
off: 'Non',
onstyle: 'success',
offstyle: 'danger',
width: '70'
});
});
</script>
When using serverSide, the resulting table is displayed after the full page load. Therefore the bootstrap elements have already been generated when datatable displays the results.
You can solve this by calling a function which takes care of displaying bootstrap elements in the "complete" ajax handler. (here the $.extend applies to a datatable options object)
$.extend(true, options, {
"ajax": {
"url": self.data('url'),
"data": function ( d ) {
d.action = "drawDatatable"
},
"type": "POST",
"complete": function() {
prepareDisplayElements("#"+self.attr("id"));
}
}
});
So in your case this could be something simple like this:
$(document).ready( function(){
var id = {{request()->route('id')}};
$('#table').DataTable({
"processing": true,
"serverSide": true,
"ajax": {
"url": "/admin/evenment/event/participant/ajaxdatatable/"+id,
"complete": function() {
$('.participation').bootstrapToggle({
on: 'Oui',
off: 'Non',
onstyle: 'success',
offstyle: 'danger',
width: '70'
});
}
},
"columns":[
{"data": "adherent_id"},
{"data": "nom_participant"},
{"data": "prenom_participant"},
{"data": "fonction"},
{"data": "action"},
]
});
});
I built a bridge between socket and websocket with webtcp. Then i was able to display the data on browser, however it is not updating in real time unless i refresh the whole page. It needs to be updated constantly showing all the data. This is how i get the data, parse it and update it.
socket.on('data', function (data) {
var arr = data.split("|").slice(1);
var dataSet = {};
arr.map((o, i) => {
if ((i + 1) % 2 != 0) dataSet[o] = arr[i + 1];
});
console.log(dataSet);
$(document).ready(function () {
$("#example").DataTable({
retrieve: true,
deferRender: true,
searching: false,
paging: false,
"data": [dataSet],
"columns": [
{"data": "power"},
{"data": "mode"},
{"data": "execution"},
{"data": "Xact"},
{"data": "Yact"},
{"data": "Zact"},
{"data": "Xcom"},
{"data": "Ycom"},
{"data": "Zcom"},
{"data": "path_feedrate"},
{"data": "line"},
{"data": "Block"},
{"data": "program"}
],
});
});
});
This is my html:
<table id="example" class="display" width="100%">
<thead>
<tr>
<th>Power</th>
<th>Mode</th>
<th>Execution</th>
<th>Xact</th>
<th>Yact</th>
<th>Zact</th>
<th>Xcom</th>
<th>Ycom</th>
<th>Zcom</th>
<th>path_feedrate</th>
<th>line</th>
<th>Block</th>
<th>program</th>
</tr>
</thead>
</table>
This is how my data looks on console and on browser, it gets updated on console as waterjet machine is working but not on browser:
This is how looks raw data from socket:
2018-08-14T22:17:00.0631|Xcom|0.00|Ycom|0.00|path_feedrate|0.00
2018-08-14T22:17:00.0683|line|389286|Block|389286
2018-08-14T22:17:00.0709|Xact|402.79|Yact|33.84|Xcom|38.71|Ycom|24.19|path_feedrate|45.65
2018-08-14T22:17:00.0735|Xcom|0.00|Ycom|0.00|path_feedrate|0.00
2018-08-14T22:17:00.0787|line|389288|Block|389288
2018-08-14T22:17:00.0840|Xact|402.78|Xcom|19.36|path_feedrate|19.36
2018-08-14T22:17:00.0866|Xcom|0.00|path_feedrate|0.00|line|389290|Block|389290
2018-08-14T22:17:00.0944|Xact|402.75|Yact|33.83|Xcom|58.07|Ycom|24.19|path_feedrate|62.91
2018-08-14T22:17:00.0970|Xcom|0.00|Ycom|0.00|path_feedrate|0.00|line|389292|Block|389292
and so on....
You are right to wait for the document to load at first, but after that the code you use to populate the table isn't running again until the document is loaded again (refresh).
Put the code that populates the table in a function and have it check the document.readyState property, to only run once the DOM is loaded:
function fillDataTable(dataSet){
if(document.readyState === "complete") {
$("#example").DataTable({
retrieve: true,
deferRender: true,
searching: false,
paging: false,
"data": [dataSet],
"columns": [
{"data": "power"},
{"data": "mode"},
{"data": "execution"},
{"data": "Xact"},
{"data": "Yact"},
{"data": "Zact"},
{"data": "Xcom"},
{"data": "Ycom"},
{"data": "Zcom"},
{"data": "path_feedrate"},
{"data": "line"},
{"data": "Block"},
{"data": "program"}
],
});
}
}
And then call it in the socket.on method:
socket.on('data', function(data) {
const arr = data.split("|").slice(1);
let dataSet = {};
arr.map((o, i) => {
if ((i + 1) % 2 != 0) dataSet[o] = arr[i + 1];
});
console.log(dataSet)
fillDataTable(dataSet)
});
The answer is easier than I thought and it is better without using any external libraries and tables.
<div class="cell">
<div class="row">
<div class="cell">
<div class="info">
<div>POWER:</div>
<div>MODE:</div>
<div>EXECUTION:</div>
<div>BLOCK:</div>
<div>LINE:</div>
<div>FEEDRATE:</div>
<div>PROGRAM:</div>
</div>
</div>
<div class="cell">
<div class="live-data">
<div id="power"></div>
<div id="mode"></div>
<div id="execution"></div>
<div id="block"></div>
<div id="line"></div>
<div id="feedrate"></div>
<div id="program"></div>
</div>
</div>
</div>
</div>
and this is my js:
if (dataSet.power) document.getElementById("power").innerHTML = dataSet.power;
if (dataSet.mode) document.getElementById("mode").innerHTML = dataSet.mode;
if (dataSet.execution) document.getElementById("execution").innerHTML = dataSet.execution;
if (dataSet.block) document.getElementById("block").innerHTML = dataSet.block;
if (dataSet.line) document.getElementById("line").innerHTML = dataSet.line;
if (dataSet.path_feedrate) document.getElementById("feedrate").innerHTML = dataSet.path_feedrate;
if (dataSet.program) document.getElementById("program").innerHTML = dataSet.program;
if (dataSet.Xact) document.getElementById("xact").innerHTML = dataSet.Xact;
if (dataSet.Yact) document.getElementById("yact").innerHTML = dataSet.Yact;
if (dataSet.Zact) document.getElementById("zact").innerHTML = dataSet.Zact;
if (dataSet.Xcom) document.getElementById("xcom").innerHTML = dataSet.Xcom;
if (dataSet.Ycom) document.getElementById("ycom").innerHTML = dataSet.Ycom;
if (dataSet.Zcom) document.getElementById("zcom").innerHTML = dataSet.Zcom;
That's it, and it works great.
I need to edit the columns section of this code for change the content of tr and td for table generated by json response. For example, I need to insert a hyperlink on EFICAZ_TAB_RESULTADO column for use click event.
I don't know how to do this task and I need help!
$(document).ready(function(){
// Setup datatables
$.fn.dataTableExt.oApi.fnPagingInfo = function(oSettings){
return {
"iStart": oSettings._iDisplayStart,
"iEnd": oSettings.fnDisplayEnd(),
"iLength": oSettings._iDisplayLength,
"iTotal": oSettings.fnRecordsTotal(),
"iFilteredTotal": oSettings.fnRecordsDisplay(),
"iPage": Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength),
"iTotalPages": Math.ceil(oSettings.fnRecordsDisplay() / oSettings._iDisplayLength)
};
};
var table = $("#mytable").dataTable({
initComplete: function() {
var api = this.api();
$('#mytable_filter input').off('.DT').on('input.DT', function(){
api.search(this.value).draw();
});
},
oLanguage: {
sProcessing: "carregando ..."
},
processing: true,
serverSide: true,
searching: false,
ajax: {
"type": "POST",
"url": "/tab/getJsonAllOcorrenciasTabForMonth"
},
pageLength: 100,
columns: [
{"data": "EFICAZ_TAB_ID"},
{"data": "ID"},
{"data": "PERIODICIDADE"},
{"data": "EFICAZ_TAB_MES_ANO"},
{"data": "EFICAZ_TAB_ITEM_ID"},
{"data": "EFICAZ_TAB_META"}, // if EFICAZ_TAB_META é diferente de EFICAZ_TAB_RESULTADO
{"data": "EFICAZ_TAB_RESULTADO"}
],
order: [
[1, 'asc']
],
rowCallback: function(row, data, iDisplayIndex) {
var info = this.fnPagingInfo();
var page = info.iPage;
var length = info.iLength;
$('td:eq(0)', row).html();
}
}); // end setup datatables
// addClass para formatar estilo bootstrap ...
$("#mytable_length select").addClass("form-control")
});
I suggest utilizing the rowCallback. This allows you to modify the rows as they are being drawn to the table. You just have to select the cell within the respective row to modify it. I suggest adding a class to the column:
Add a Column Class
columns: [
...
{
"data": "EFICAZ_TAB_RESULTADO",
"className": "hyperlinkClass"
}
...
]
Modify that cell each time a new row is drawn
rowCallback: function(row, data, iDisplayIndex) {
$(row).find(".hyperlinkClass").html('HYPERLINK TEXT');
}
You can achieve that by using columnDefs property, e.g. add a click event on EFICAZ_TAB_RESULTADO column:
columnDefs: [{
"targets": [6],//index of EFICAZ_TAB_RESULTADO
"createdCell": (td, cellData, rowData, row, col) => {
$(td).css({
'color': '#007bff',
'cursor': 'pointer'
});
$(td).attr('title', 'Click Me');
$(td).click(e => {
alert(cellData) //call the function here
})
}
}
]
Fiddle for your reference.
I've initiated a datatable plugin as following:
var table= $("#mytable").DataTable({
ajax: "list.json",
columns: [
{"data": "name"},
{"data": "location"},
{"data": "date"}
],
searchCols: [
{"search": "John"},
null,
null
]
});
The example above also does a pre search on the first column. Now, when the plugin is initiated I want to interact with some of its rows:
fnInitComplete: function() {
$(this).find("tr").click( ... );
}
Everything works good, UNTIL I try to interact with a row that's been searched on the table render {"search": "John"} and that was searched again after (e.g. I changed the search query to "Richard" and tried to click on one of that rows). Any ideas?
You need to use delegated event handlers because jQuery DataTables manipulates DOM on each table draw.
For example:
var table= $("#mytable").DataTable({
ajax: "list.json",
columns: [
{"data": "name"},
{"data": "location"},
{"data": "date"}
],
searchCols: [
{"search": "John"},
null,
null
]
});
$("#mytable").on("click", "tr", function(){
// Handle click event
});
I'm trying load json data on table using datatables
The return of json from php is like this:
data = {
"CLIENTES": {
"0": {
"ID": "1",
"NOME": 'GABRIEL'
},
"1": {
"ID": "2",
"NOME": 'RODRIGUES'
}
}
}
In the documentation columns data they say that I need to follow this structure:
table.DataTable({
"ajax": url,
columns: [
{"data": "CLIENTES.ID"},
{"data": "CLIENTES.NOME"}
]
});
But dont work, and we know that the right acess to de data index is this way:
{"data": "CLIENTES['0'].ID"},
{"data": "CLIENTES['1'].ID"},
But need's to be dynamically, how can I do this?
You should create new data for datatable without CLIENTES .... map is an option.
$(document).ready(function() {
data = {
"CLIENTES": {
"0": {
"ID": "1",
"NOME": 'GABRIEL'
},
"1": {
"ID": "2",
"NOME": 'RODRIGUES'
}
}
};
var newData = $.map(data.CLIENTES, function(el) { return el });
$('#example').DataTable({
data: newData,
columns: [
{"data": "ID"},
{"data": "NOME"}
]
});
});
example: https://jsfiddle.net/cmedina/7kfmyw6x/5/
If you remove the 'CLIENTES' outer array and only return an array of the results in your PHP, you will be able to refer to the values like this:
table.DataTable({
"ajax": url,
columns: [
{"data": "ID"},
{"data": "NOME"}
]
});
you can do things to an object dynamically by using for var in
var myArray = [] //an empty array
for(var i in data){
myData.push({"data": "CLIENTES[i].ID"})
myData.push({"data": "CLIENTES[i].NOME"})
}
then later you can do this
table.DataTable({
"ajax": url,
columns: myArray
});
but I suspect the way you write {"data": "CLIENTES[i].ID"} is wrong, though i havent used datatables before.
maybe something like this is more correct? it's how you usually get to object properties
for(var i in data){
myData.push({"data": data.CLIENTES[i].ID})
myData.push({"data": data.CLIENTES[i].NOME})
}