Responsive table in DataTable - php

My page looks like this:
I want to add scrollX when page is too small so I must add line
scrollX: true
When I add page looks like this:
DataPicker is behind rows and line of column is not in this same line but scrollX work(look picture). When I write in input and ajax load data that line of column works fine but datapicker still not work. How can I repair this?
Code _table.blade.php
<table class="table table-striped table-bordered" id="policies-table" style="width: 100%;">
<thead>
<tr>
<th>Numer polisy</th>
<th>Produkt</th>
<th>Data wystawienia</th>
<th>Wartość</th>
<th>Składka</th>
<th>Wystawiający</th>
<th>Akcje</th>
</tr>
</thead>
</table>
Ajax load:
$('#policies-table').DataTable({
ajax: {url:"url",
type: "POST",
'headers': {'X-CSRF-TOKEN': '{{ csrf_token() }}'}},
processing: true,
serverSide: true,
autoWidth: true,
scrollX: true,
scrollCollapse: true,
jQueryUI: true,
order: [[ 2, "desc" ]],
........
});

Try this $('#policies-table').DataTable({responsive: true} );
Or If you are using bootstrap, you cant try this
<div class='table-responsive'>
<table class='your classes'>
</table>
</div>

Related

DataTables warning: table id=DataTables_Table_0 - Ajax error - Laravel

I'm getting an error when trying to setup a datatables with my laravel project.
DataTables warning: table id=DataTables_Table_0 - Ajax error. For more information about this error, please see http://datatables.net/tn/7
This is my controller.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Transaction;
use DataTables;
use Illuminate\Support\Facades\DB;
class TestTableController extends Controller
{
public function index()
{
return view('testtable');
}
public function getTestTable(Request $request)
{
if ($request->ajax()) {
$data = DB::table('transactions')->get();
return Datatables::of($data)
->addIndexColumn()
->addColumn('action', function($row){
$actionBtn = 'Edit Delete';
return $actionBtn;
})
->rawColumns(['action'])
->make(true);
}
}
}
This my route.
Route::get('testtable', [TestTableController::class, 'index']);
Route::get('testtable/list', [TestTableController::class, 'getTestTable'])->name('testtable.list');
View/blade.
<body>
<div class="container mt-5">
<h2 class="mb-4">Laravel 7|8 Yajra Datatables Example</h2>
<table class="table table-bordered yajra-datatable">
<thead>
<tr>
<th>ID</th>
<th>Amount</th>
<th>Charge</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js">
</script>
<script src="https://cdn.datatables.net/1.10.21/js/dataTables.bootstrap4.min.js">
</script>
<script type="text/javascript">
$(function () {
var table = $('.yajra-datatable').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('testtable.list') }}",
columns: [
{data: 'id', name: 'id'},
{data: 'amount', name: 'amount'},
{data: 'charge', name: 'charge'},
{
data: 'action',
name: 'action',
orderable: true,
searchable: true
},
]
});
});
</script>
This is the error from laravel debugbar.
But the query did have results.
This is the output if I echo the query.
$data = DB::table('transactions')->get();
echo $data;
Anything else I'm missing? The exact same code is working if I tested in a new fresh laravel installation. This is an existing project that I try to implement datatables. I guess there must be something from current project configuration that causing the issue.
Your code in getTestTable function look fine. You got in the debugbar:
No query results for model [App\Frontend] testtable
But the code in getTestTable has nothing related to testtable so I guess route('testtable.list') doesn't get to that function. And the reason may be because you put a route like Route::get('testtable/{id}',... before Route::get('testtable/list', so when you call testtable/list, it will take list as id and go to other function.
If my guess is true, you can fix it by putting testtable/list before testtable/{id} route.
I share full details with Sample Code from my Project, this below Example code is a Manage Role DataTable from my project. please refer step by step & try to understand it.
first of all you need to install Laravel Yajra DataTable using below Composer command
composer require yajra/laravel-datatables-oracle
then after Define Routes in web.php as like my sample code
Route::get('/', [\App\Http\Controllers\Admin\RoleController::class, 'index'])->name('admin.roles.index'); //index all the data view...
Route::post('/', [\App\Http\Controllers\Admin\RoleController::class, 'getIndexUsers'])->name('admin.roles.getIndexRoles'); //Get Users for Laravel Yajra Datatable Index Page record...
then after create view file for it, I share sample from my project
<div class="card-body">
<table id="role_table" class="table table-bordered table-striped w-100">
<thead>
<tr>
<th>No.</th>
<th>Role Name</th>
<th>Role Slug</th>
<th>Action</th>
</tr>
</thead>
<tfoot>
<tr>
<th>No.</th>
<th>Role Name</th>
<th>Role Slug</th>
<th>Action</th>
</tr>
</tfoot>
</table>
</div>
<!-- /.card-body -->
& in Footer Script define Function for Initialize the DataTable like below,
<script type="text/javascript">
var dataTable = $('#role_table').DataTable({
lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]],
processing: true,
serverSide: true,
order: [],
searchDelay: 500,
"scrollX": "auto",
"responsive": true,
// "lengthChange": false,
"autoWidth": true,
ajax: {
url: '{{ route("admin.roles.getIndexRoles")}}',
type: 'post',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: function (data) {
// data.fromValues = $("#filterUserType").serialize();
},
},
columns: [
{data: 'SrNo', //try with data: 'SrNo' OR data: 'id',
render: function (data, type, row, meta) {
// return meta.row + meta.settings._iDisplayStart + 1;
return meta.row + 1;
}, searchable: false, sortable: false
},
{data: 'role_name', name: 'role_name'},
{data: 'role_slug', name: 'role_slug'},
{data: 'action', name: 'action', searchable: false, sortable: false},
],
});
</script>
then after In your Controller load Yajra DataTable Class for use it
use Yajra\DataTables\DataTables; //for Laravel DataTable JS...
Now, create Function for Display View File like this,
public function index()
{
return view('admin.roles.index');
}
Now I crated Function method for Ajax Request for DataTable Initialize
public function getIndexUsers(Request $request)
{
$roles = Role::select('roles.*');
if($request->order ==null){
$roles->orderBy('id', 'desc');
}
$detail_data = $roles;
return Datatables::of($detail_data)
->addColumn('action', function ($data) {
return $this->DataTableAction($data);
})
->rawColumns(['action'])
->make(true);
}
public function DataTableAction($data){
$btn = '<div class="btn-group">';
if($data->id == "1" || $data->id == "2"){
$btn .= '<button type="button" class="btn btn-danger dropdown-toggle ml-2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" disabled>Action
</button>';
}else{
$btn .= '<button type="button" class="btn btn-danger dropdown-toggle ml-2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Action
</button>';
}
$btn .= '<div class="dropdown-menu">';
$btn .= '<a class="dropdown-item" href="'.route('admin.roles.edit',$data->id).'" style="color: black;" onmouseover=\'this.style.background="#dee2e6"\' onmouseout=\'this.style.background="none"\'><i class="far fa-edit text-primary"></i> Edit</a>';
$btn .= '<div class="dropdown-divider"></div>';
$btn .= '<a role_id="'.$data->id.'" class="dropdown-item deleteRole" href="#" style="color: black;" onmouseover=\'this.style.background="#dee2e6"\' onmouseout=\'this.style.background="none"\'><i class="far fa-trash-alt text-danger"></i> Delete</a>';
$btn .= '</div>
</div>';
return $btn;
}
Important Note:- Currently I use Laravel 8 So, It's not necessary to needs to define Yajra Service Provider Class in config/app.php . But if you are getting any error in your different Laravel version then you wil needs to define Yajra Service Provider Class in config/app.php... for define it follow below steps
**
Note that, below step not compulsory, its depends on your Laravel
version
**
config/app.php
.....
'providers' => [
....
Yajra\DataTables\DataTablesServiceProvider::class,
]
'aliases' => [
....
'DataTables' => Yajra\DataTables\Facades\DataTables::class,
]
.....
then Run below Command
php artisan optimize
then if you get any problem, try to Clear Cache using
php artisan cache:clear
Important Note:- If you define Service Provider Class in config/app.php & run optimize command, then May be Laravel will load it in autoload which is automatically called when your code references a class or interface that hasn't been loaded yet, I'm not sure
if everything is ok in the app codes,
you may loosed config for yajra..
so to configure it, you can go to the config folder in the app root directory and then open app.php file from there and add this line to the provider..
Yajra\DataTables\DataTablesServiceProvider::class
the result will be something like this:
'providers' => [
..
..
..
Yajra\DataTables\DataTablesServiceProvider::class,
]
and also add this line to the aliases:
Yajra\DataTables\Facades\DataTables::class
try like this:
'aliases' => [
..
..
..
..
'DataTables' => Yajra\DataTables\Facades\DataTables::class,
]
finally, save the file(config\app.php) like above and then open up cmd or terminal and try to clear the app cached file(that includes the config cache) using the fallowing command:
php artisan optimize

DataTables with AJAX - How to pass in a column hyperlink an external variable

I'm beginner in DataTables or dev in general :)
I use Laravel 5.4 and several DataTables which get their data using ajax calls requests and everything it's working just fine :) .
One of the tables have a column with a hyperlink on it I need to send further in the hyperlink an external variable which is not returned by Ajax response but it's hidden in same form with the table.
So, I have the table definition:
$('#tabelClientiOferta').DataTable({
lengthMenu: [[15, 25, 100, -1], [15,25, 100, "All"]],
processing: true,
serverSide: true,
ajax: 'ajaxClienti',
columns: [
{data:'id',name:'id' , sClass: "hidden", "bSearchable": false },
{data: 'denumire', name: 'denumire',
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
$(nTd).html("<a href='selectieFurnizor?idClient=" + oData.id + "'>" + oData.denumire + "</a>")
}
},
{ data: 'cui', name: 'cui' },
{ data: 'telefon', name: 'telefon', "bSearchable": false},
{ data: 'email', name: 'email', "bSearchable": false },
]
});
Controller function which respond to ajax call:
public function clienti(Request $request)
{
return Datatables::of(DB::table('clienti')->get(['id','denumire','cui','telefon','email']))->make(true);
}
HTML template with table and hidden variable:
#extends ('master')
#section('content')
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="tabelOferte" style ="width: 900px">
<table id = "tabelClientiOferta" class="table table-responsive table-striped table-hover">
<thead >
<tr style="font-weight: bold" >
<td>id</td>
<td>Denumire</td>
<td>CUI</td>
<td>Telefon</td>
<td>Email</td>
</tr>
</thead>
</table>
</div>
<input id = "hiddenId" name="hiddenId" type="text" value = {{$someId}} hidden />
</div>
</div>
</div>
#stop
So I need to pass the hidden variable as the second parameter to the "denumire" column hyperlink, something like:
$(nTd).html("<a href='selectieFurnizor?idClient=" + oData.id + "&hiddenId="+$('#hiddenId') "'>" + oData.denumire + "</a>")
.
Is that possible?
The solution which I use now is to return a view from the controller and include in it a static DataTable (with data already prepared and sent by the controller).
Thank you for your attention
:)
Server-side: use add coloumn from controller
$data = DB::table('clienti')->get(['id','denumire','cui','telefon','email']);
return Datatables::of($data)
->addColumn('clear', function ($data) {
return '<i class="glyphicon glyphicon-trash"></i> Clear';
})
->escapeColumns([])
->make(true);
And add to columns with initial js of datatables
{data: 'clear', name: 'cleat', orderable: false, searchable: false }
or use js based columns render() function, official doc and examples here: https://datatables.net/reference/option/columns.render

Dropdown content not showing when loading dynamic generated buttons

I have a question regarding MaterializeCSS.
I have an html table that has an option button that will display dynamic options generated based on the user.
This all works fine on the first run (when loading the page), yet when I reload the table contents (including the buttons) using AJAX the dropdown content won't show up anymore. Whilst the button click event still gets triggered.
I have tried multiple solutions yet none of these worked for my case.
Table (tbody content generated by foreach loop in php):
<table class="table highlight">
<thead>
<tr>
<th class="center-align">
<input type="checkbox" id="checkAllUsers" class="checkToggle checkAllUsers"
data-target="#boxUsers table tbody [type=checkbox]">
<label for="checkAllUsers"></label>
</th>
<th>Username</th>
<th class="hide-on-small-only">Email</th>
<th style="text-align:center;" class="hide-on-small-only">Allowed</th>
<th style="text-align:center;">Employee</th>
<th>Action</th>
</tr>
</thead>
<tbody class="usertablebody">
<tr>
<td class="center-align">
<input type="checkbox" class="selectedUsers" name="u-1" id="u-1">
<label for="u-1"></label>
</td>
<td>jGeluk</td>
<td class="hide-on-small-only">jonah#example.com</td>
<td style="text-align:center;">Yes</td>
<td style="text-align:center;">No</td>
<!-- ACTION BUTTON HERE -->
<td>
<div class="actions">
<a class="dropdown-button showuseroptions btn-flat waves-effect" uid="1" href="#"
data-activates="showUserOptions">
<i class="large material-icons">more_vert</i>
</a>
</div>
</td>
</tr>
</tbody>
Dropdown content:
<ul id="showUserOptions" class="dropdown-content main-dropdown lighten-2">
<li>Loading...</li>
</ul>
Loading dynamic dropdown content (this runs without any problems on page load):
$("body").on('click', ".showuseroptions", function(event) {
var uid = $(this).attr('uid');
var btn = this;;
toggleLoader();
jQuery.ajax({
type: "POST",
url: base_url + "ajax_admin_controller/fetch_user_options",
dataType: 'text',
data: {uid:uid},
success: function(res) {
if (res)
{
//"ul#showUserOptions"
$("ul#showUserOptions").html(res);
}
toggleLoader();
}
});
});
Refresh table function:
function refreshUserTable()
{
toggleLoader();
jQuery.ajax({
type: "POST",
url: base_url + "ajax_admin_controller/fetch_users_table",
dataType: 'text',
success: function(res) {
if (res)
{
$(".usertablebody").html(res);
toggleLoader();
}
}
});
}
Using
$(this).dropdown();
as stated in the documentation doesn't have any effect.
I hope somebody can help me out.
Thanks,
Jonah
call the dropdown after the ajax is completed and the html is appended
toggleLoader();
$('.showuseroptions').dropdown();
make sure you have a unique id for each dropdown
change
dataType: 'html',

Tablesorter and saving sort

I have a table with some information.
At first time it is generate from php-script and then every n-seconds check database.
Then I've installed tablesorter plugin. It's okay, but now, after getting information from database(if table was sorted by several fields) sort "configuration" resets.
So I've found some information about saveSort plugins, download jquery.tablesorter.widgets.js include it into my project. In plugin's documentation I've found some instruction like how to.
$("table").tablesorter({
widgets: ["saveSort"]
});
But it doesn't fix my problem. After getting results the saved sort resets.
So, here is the code of my script:
$(document).ready(function(){
$("table").tablesorter({
widgets: ["saveSort"]
});
function get_op(){
var dataSend = "to teh mooon";
jQuery.ajax({
type: "POST",
url: "get_url",
dataType:"html",
data:dataSend,
success:function(response){
$("#recent_op tbody").html(response);
$("#recent_op").trigger("update");
},
error:function (xhr, ajaxOptions, thrownError){
$("#recent_operations").html(thrownError);
}
});
}
setInterval(function(){get_op()}, 10000);
});
Here is simple table that I used.
<table class="table table-bordered table-hover table-striped tablesorter" id = "recent_op">
<thead>
<tr>
<th>header # <i class="fa fa-sort"></i></th>
....
</tr>
</thead>
<tbody>
<tr>
<td>Body</td>
....
</tr>
....
<tr>
<td>Body</td>
....
</tr>
</tbody>
</table>
So, no errors, everythings from tutorial, but it doesn't work good. I think I'm use this widget in a wrong way.
The saveSort widget requires:
jQuery v1.4.1+
$.tablesorter.storage utility which is also included in the jquery.tablesorter.widgets.js. I mention this in case the file was modified some how.
A browser that supports localStorage, or cookies (fallback method if localStorage is not supported).
The save sort can be enabled/disabled using the widget option
$(function(){
$("table").tablesorter({
widgets: ["saveSort"],
widgetOptions : {
// if false, the sort will not be saved for next page reload
saveSort : false
}
});
});

Datatables 'No Match Found'

I have a datatable that I'm using in server-side mode to retrieve data via AJAX. On the surface everything appears correct however, when I load the page I get "No Matching Records Found" displayed instead of the data displaying. The peculiar part is that it says it is showing the records "Showing records 1 to 2 of 2 entries".
The table HTML and JS is as follows:
<div class="container">
<script type="text/javascript">
$(document).ready(function() {
$("#freebieslist").dataTable({
"bServerSide": true,
"sAjaxSource": "/config/getadvertisers",
"bPaginate": true,
"bProcessing": true,
"bFilter" : true,
"sPaginationType" : "bootstrap",
"sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>"
});
$.extend( $.fn.dataTableExt.oStdClasses, {
"sWrapper": "dataTables_wrapper form-inline"
} );
});
</script>
<div class="row"><h1 class="pull-left">Advertisers</h1><div class="pull-right" style="margin-top:15px;">Add New Delete</div> </div>
<div class="row">
<div class="span12">
<table id="freebieslist" class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th class="span1"> </th><th>Advertiser</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div> </div>
The JSON being loaded is this:
{
"sEcho": "1",
"iTotalRecords": "2",
"iTotalDisplayRecords": "2",
"aaData": [
[
"2",
"Test2"
],
[
"1",
"Tester"
]
]
}
How to fix this so it actually displays the returned rows?
I solved the issue by using datatables debugger in Chrome. I checked the AJAX result coming back (based on the get paramaters datatables was passing in) and found it was getting a null result set. A quick change in the server side code and things started working properly.

Categories