Call to a member function getQuery() on array - laravel

Trying to do with datatables in laravel:
Error: Call to a member function getQuery() on array in laravel datatables
Here is Laravel Code:
Controller:
public function get_all_course_requests() {
$course_request = new CourseRequest();
$request_details = $course_request->get_all_course_requests();
$i = 0;
foreach ($request_details as $request) {
$request_details[$i]->sr_no = $request->id;
$request_details[$i]->l_fname = $request->l_fname;
$request_details[$i]->l_lname = $request->l_lname;
$request_details[$i]->l_mail = $request->l_mail;
$request_details[$i]->name = $request->name;
$request_details[$i]->request_date = $request->request_date;
$request_details[$i]->action = $request->id;
$i++;
}
return Datatables::of($request_details)
->filterColumn('l_fname', 'l_lname', 'name','course_name','request_date')
->make(true);
}
Model:
function get_all_course_requests($status='0') {
// DB::enableQueryLog();
$course_request = new CourseRequestModel;
$my_team_ids = $course_request->get_my_team_learner_ids();
return DB::table('course_request')
->select('login_details.l_fname','login_details.l_lname','login_details.l_mail','course_request.id','multilevel_course.name','course_request.request_date')
->whereIn('login_details.l_id', $my_team_ids)
->where('course_request.status', $status)
->join('login_details', 'login_details.l_id','=', 'course_request.user_id')
->join('multilevel_course', 'multilevel_course.id','=','course_request.course_id')
->whereIn('enrollment_policy',array('2','3') )
->get();
}
Here is JS Code:
$(function() {
$('#course_requests_table').DataTable({
processing: true,
serverSide: true,
ajax: BASE_URL + '/get_course_requests',
order: [],
columns: [
{data: "view", orderable: false,
render: function(data, type, row) {
return '<input type="checkbox" class="case" name="row_ids[]" value="' + data + '">';
}
},
{data: 'l_fname', name: 'l_fname'},
{data: 'l_lname', name: 'l_lname'},
{data: 'l_mail', name: 'l_mail'},
{data: 'name', name: 'name'},
{data: 'request_date', name: 'request_date'},
{data: 'action', orderable: false,
render: function(data, type, row) {
return '<a style="cursor:pointer" OnClick="delete_mail(' + data + ')"><i class="fa fa-trash"></i></a>';
}
}
]
});
});
Whats going wrong with code? and what to be done to solve this?

Solved:
Solution: converted array to Collection using collect()
$request_details = $course_request->get_all_course_requests();
$request_details= collect($request_details);
$i = 0;
foreach......

Related

Displaying json data on datatables with laravel resources

I have some data i have stored in my table and i have cast to array and accessing it in my resource like this
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
class JobRequests extends JsonResource
{
public $preserveKeys = true;
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
$data = DB::select('select order_data from orders where id=9');
return [
'email' => json_decode($data[0]->order_data)->personal_data->email,
'telephone_number' => json_decode($data[0]->order_data)->personal_data->telephone_number,
'car_registration' => json_decode($data[0]->order_data)->personal_data->car_registration,
'postal_code' => json_decode($data[0]->order_data)->personal_data->postal_address
/**
'commission' => function(){
$final_price = 700;
return (int)$final_price;
}
*/
];
}
}
My data looks like this
{
"personal_data": {
"email": "info#info.com",
"telephone_number": "0999",
"postal_address": "LON",
"car_registration": "GB BHG"
},
"inperson_diagnostic": {
"diagnostic_inspection": "67.30",
"car_wont_start_inspection": "67.30",
"plugin_diagnostic_inspection": "67.30"
},
"tyres": {
"front_wheels": 1,
"rear_wheels": 1,
"wheel_width": 45,
"wheel_profile": 1,
"wheel_rim": 1,
"speed_rating": "w",
"final_price": 90
},
"servicing_and_mot": {
"mot_with_collection_delivery": 75,
"major_service": 304.52,
"full_service": 203.45,
"interim_service": "149.70",
"vehicle_health_check": 50
},
"inspection_services": {
"premium_prepurchase_inspection": 146.38,
"standard_prepurchase_inspection": 104,
"basic_prepurchase_inspection": 86.44
},
"repairs": {
"ABS wheel speed sensor replacement": 964,
"ABS pump replacement": 712,
"Brake pedal switch replacement": 568,
"Air conditioning regas (R1234yf Gas ONLY)": 469
}
}
This is the function i am trying to fetch data with
//Fetch Job Requests
public function jrData(Request $request)
{
//$data = DB::select('select order_data from orders where id=9');
$jobRequest = new JobRequests($request);
$object_json = $jobRequest->toJson();
$object_array = (array)$object_json;
return Datatables::of($object_array)
->addIndexColumn()
->addColumn('action', function($row){
$btn = 'View';
return $btn;
})
->rawColumns(['action'])
->make(true);
}
and this is my blade page
<script>
$(function() {
$('#users-table').DataTable({
processing: true,
serverSide: true,
ajax: '{!! url('jrData') !!}',
columns: [
{ data: 'id', name: 'id' },
{ data: 'email', name: 'email' },
{ data: 'telephone_number', name: 'telephone_number' },
{ data: 'car_registration', name: 'car_registration' },
{ data: 'postal_code', name: 'postal_code' },
{data: 'action', name: 'action', orderable: false, searchable: false}
]
});
});
</script>
This is the data returned by my jrData
{"draw":0,"recordsTotal":1,"recordsFiltered":1,"data":[{"0":"{\"email\":\"info#info.com\",\"telephone_number\":\"0900\",\"car_registration\":\"KGB BHG\",\"postal_code\":\"00200\"}","action":"<a href=\"view_job_request\/\" class=\"edit btn btn-info btn-sm m-2\">View<\/a>","DT_RowIndex":1}],"input":[]}
I get this error on my blade file
DataTables warning: table id=users-table - Requested unknown parameter
'id' for row 0. For more information about this error, please see
http://datatables.net/tn/4
How can i display the data in the datatables?
Ok here is an example:
You have
$data = DB::select('select order_data from orders where id=9');
This really isn't going to give you the data you need.
Try doing this:
$data = YourModel::where('id',$id)->first();
$id is a dynamic id so you can run this to grab anything instead of being static. I'm guessing you are doing a post to get the data, so if you send that through it would be $request->id so you just set it to $id = $request->id; now you're fully dynamic in your eloquent.

Relationship with multiple foreign key in same table in datatable with Laravel, Eloquent

I'm using Laravel 8, Eloquent and Datatables for few days now. I actually find how i can display a datatable with one of my table with datatable and Eloquent.
My problem now is that I need to display the name in a column (that you can find in the "appellations" table) instead of his foreign key.
screenshot of the actual result of my datatables
This is a screenshot of what I have actually, and my aim is to display the "abrege" that you can find in the "appellations" table in the 2 column I show you in red ("App CVI" and "App engage"), instead of they foreign key.
My code actually is :
My "SousParcelle" Model:
class SousParcelle extends Model
{
use HasFactory;
protected $table = 'sous_parcelles';
protected $fillable = ['id',
'parcelle_id',
'cepage_id',
'appellation_cvi_id',
'dist_entre_rang',
'dist_sur_rang',
'densite_theorique',
'superficie',
'annee_plantation',
'modification_par',
'modification_le',
'validee',
'affectation_appellation_id',
'affectation_superficie'];
public function appellation(){
return $this->belongsTo(Appellation::class, 'affectation_appellation_id', 'id');
}
}
My "Appellation" Model :
class Appellation extends Model
{
use HasFactory;
protected $table = 'appellations';
protected $fillable = ['id', 'libelle', 'abrege', 'siqo_id'];
public function sousparcelles(){
return $this->hasMany(Appellation::class, 'affectation_appellation_id', 'id');
}
}
My "SousParcellesController" Datatable Controller :
class SousParcellesController
{
public function index()
{
return view('welcome');
}
public function getSousParcelles(Request $request)
{
if ($request->ajax()) {
$query = SousParcelle::with(['appellation' => function($query){
$query->select('abrege');
}]);
return DataTables::of($query)
->addIndexColumn()
->addColumn('App engagee', function(SousParcelle $sousparcelles){
return $sousparcelles->appellations()->abrege;
})
->make(true);
}
}
}
The script of my view "welcome.blade.php" :
<table id="sousparcelles" class="table table-bordered yajra-datatable">
<thead>
<tr>
<th>Référence Cadastrale</th>
<th>Commune</th>
<th>Plantation</th>
<th>Cepage</th>
<th>App CVI</th>
<th>Sup CVI</th>
<th>App engagee</th>
<th>Sup engagee</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script type="text/javascript">
function load_table(appellation_id) {
if ($.fn.dataTable.isDataTable('.yajra-datatable')) {
$('.yajra-datatable').DataTable().destroy();
}
var table = $('.yajra-datatable').DataTable({
processing: true,
serverSide: true,
searching: true,
ajax: "{{ route('sousparcelles.liste') }}",
columns: [
{data: 'dist_entre_rang', name: 'dist_entre_rang'},
{data: 'parcelle_id', name: 'parcelle_id'},
{data: 'annee_plantation', name: 'annee_plantation'},
{data: 'cepage_id', name: 'cepage_id'},
{data: 'appellation_cvi_id', name: 'appellation_cvi_id', type: 'selection'},
{data: 'superficie', name: 'superficie'},
{data: 'affectation_appellation_id', name: 'appellations.abrege'},
{data: 'affectation_superficie', name: 'affectation_superficie'},
]
});
}
$(function () {
load_table(5);
});
function change_appellation() {
load_table(6);
}
</script>
Could someone enlighten me about this relationship communication please ?
UPDATE ! I found the solution ! I decided to change the whole request and now it work well. Here is my solution :
The changed part un my controller (with more 'join' to other tables and a 'where' to only have the entries of connected account):
public function getSousParcelles(Request $request)
{
if ($request->ajax()) {
$id = Auth::id();
$userData = DB::table('sous_parcelles')
->join('appellations as affectation', 'affectation.id', '=', 'sous_parcelles.affectation_appellation_id')
->join('appellations as engagee', 'engagee.id', '=', 'sous_parcelles.appellation_cvi_id')
->join('parcelles', 'parcelles.id', '=', 'sous_parcelles.parcelle_id')
->join('users', 'users.id', '=', 'parcelles.user_id')
->select('sous_parcelles.*', 'affectation.abrege as affectationlib', 'engagee.abrege as engageelib', 'parcelles.campagne as parcellescamp')->where('user_id', '=', $id);
return Datatables::of($userData)->filter(function ($query) use ($request) {
})->make(true);
}
And here is my new JS script :
var table = $('.yajra-datatable').DataTable({
processing: true,
serverSide: true,
searching: false,
ajax: "{{ route('sousparcelles.liste') }}",
columns: [
{data: 'parcellescamp', name: 'parcelles.campagne'},
{data: 'parcelle_id', name: 'sous_parcelles.parcelle_id'},
{data: 'annee_plantation', name: 'sous_parcelles.annee_plantation'},
{data: 'cepage_id', name: 'sous_parcelles.cepage_id'},
{data: 'affectationlib', name: 'affectation.abrege'},
{data: 'superficie', name: 'sous_parcelles.superficie'},
{data: 'engageelib', name: 'engagee.abrege'},
{data: 'affectation_superficie', name: 'sous_parcelles.affectation_superficie'},
]
});
All other files do not change for this problem.
I hope it will be useful for someone.

Why is the link getting doubled sometimes when I use yajra-datatable for laravel?

Most of the time when I select a user in the users list, the link would go "localhost:8000/user/1" but sometimes is goes "localhost:8000/user/user/1". I can't remove the user in the link data = '<a href="user/' + data + '>' + data + '</a>'; because most of the time it shows the user page correctly.
This is the code under the UserController
public function getUsers(Request $request) {
if ( $request->ajax() ) {
...
return Datatables::of($data)
->addColumn('id', function($row) {
return $row['id'];
})
->addColumn('name', function($row) {
return $row['name'];
->rawColumns(['id', 'name'])
->make(true);
}
}
This is the script for users index.blade.php
<script type="text/javascript">
$(function () {
var table = $('.yajra-datatable').DataTable({
processing: true,
serverSide: true,
ajax: "{{ url('users/list') }}",
columns: [
{
data: 'id',
name: 'id',
"render": function(data, type, row, meta) {
if(type === 'display'){
data = '<a href="user/' + data + '>' + data + '</a>';
}
return data;
}
},
{data: 'name', name: 'name'},
],
});
});
</script>
just add slash in the front of url
data = '<a href="/user/' + data + '>' + data + '</a>';
I think the thing causing the problem could be the href attribute because if you are on the "/user" page the href value "user/1" will add to that so it will give that result like "/user/user/1".
You should make an absolute value for that. Using this approach that could be accomplished. Try to make a complete URL to the user read page, like this:
$(function () {
var users_url = "{{config('app.url'}}/user/"; // <-- This should be the absolute URL to user page
var table = $('.yajra-datatable').DataTable({
processing: true,
serverSide: true,
ajax: "{{ url('users/list') }}",
columns: [
{
data: 'id',
name: 'id',
"render": function(data, type, row, meta) {
if(type === 'display'){
data = '' + data + '';
}
return data;
}
},
{data: 'name', name: 'name'},
],
});
});

How to display data with yajra datatable many to many relationship in laravel?

I am using Yajra datatable. I want to display data and filter data with the president name
I have 3 tables
1- Planes = id, title, description.
2- presidents = id, P_name.
3- Plane_president = plane_id , president_id
Plane Model:
public function president()
{
return $this->belongsToMany(President::class);
}
President Model:
public function planes()
{
return $this->belongsToMany(Plane::class);
}
My Controller :
public function index(Request $request)
{
if ($request->ajax()) {
$query = Plane::with('presidents')->selectRaw('distinct planes.*');
return $this->dataTable
->eloquent($query)
->addColumn('P_name', function (Plane $plane) {
return $plane->presidents->map(function($president) {
return str_limit($president->P_name);
})->implode('<br>');
})
->make(true);
}
return view('planes.index');
}
js code:
<script type="text/javascript">
$('#search').DataTable({
processing: true,
serverSide: true,
ajax: '{{ route("plane.index") }}',
columns: [
{data: 'id', name: 'id'},
{data: 'main_point', name: 'main_point'},
{data: 'presidents[, ].P_name', name: 'president'},
]
});
</script>
I have this error
message "Undefined property: App\\Http\\Controllers\\PlaneController::$dataTable"
How to solve this error?
use DataTables:: to make datatable and you were missing ->rawColumns(['p_name']) i added that
if ($request->ajax()) {
$plane = Plane::with('presidents')->selectRaw('distinct planes.*')->get();
return \DataTables::of($plane)
->addColumn('p_name', function ($plane) {
return implode(', ', $plane->presidents->pluck('P_name')->toArray());
})
->rawColumns(['p_name'])
->make(true);
}
in javascript
<script type="text/javascript">
$('#search').DataTable({
processing: true,
serverSide: true,
ajax: '{{ route("plane.index") }}',
columns: [
{data: 'id', name: 'id'},
{data: 'main_point', name: 'main_point'},
{data: 'p_name', name: 'p_name'}, // manipulate data of this column in server side here just echo like this
]
});
</script>
You need to pass it as below.
return datatables()->eloquent($query);
Please check the document. and for display president name I would suggest.
implode(', ', $plane->presidents->pluck('P_name')->toArray())

Laravel Yajra Datatables searchable not working on desire column

I have datatables column as such:
var showMasterUserTable = function () {
masterIcon = $('#master_user_table').DataTable({
processing: true,
serverSide: true,
responsive: true,
ajax: {
url: ROOT + 'master-voucher-bit-x/data',
},
columns: [
{
data: 'DT_RowIndex',
name: 'DT_RowIndex',
searchable: false,
orderable: false
},
{
data: 'voucher_code',
name: 'voucher_code',
},
{
data: 'status',
name: 'status',
},
{
data: 'track',
name: 'track',
},
{
data: 'user_use',
name: 'user_use',
orderable: true
},
{
data: 'progress',
name: 'progress',
},
{
data: 'quiz_score',
name: 'quiz_score',
},
{
data: 'urlQr',
name: 'urlQr',
}
]
});
};
As long as i know from the yajra and datatables docs that searchable and orderable is default to be true when it remains unwritten, i have encounter the issue where searchable only search for voucher_code column no matter if i set all the searchable to true. I want to search for user_use column instead. If i set all the searchable to false, the table data cannot be loaded. How should i overcome it? Here's my controller code:
{
$model = VoucherBitX::select('voucher_bit_x.*', 'users.email')
->join('users', 'voucher_bit_x.user_id', '=', 'users.id')
->orderBy("voucher_bit_x.redeem_at","DESC");
return DataTables::of($model)
->addColumn('status', function ($data) {
if($data->status > 0)
$status = '<div><span class="badge badge-success"> Available </span></div>';
else
$status = '<div><span class="badge badge-danger"> Not Available </span></div>';
return $status;
})
->addColumn('urlQr', function ($data) {
$user = UserApp::find($data->user_id);
$a = "";
if(!empty($user) && isset($user->ref_id)){
$quiz = QuizScore::where("track_id",$data->track_id)->where("user_id",$data->user_id)->first();
if($quiz && $quiz->status){
$track = Track::find($data->track_id);
$urlQr = 'https://xxx.id/api/certificate/'.base64_encode(json_encode(["user_id"=>$user->id,"slug"=>$track->slug,"track_id"=>$track->id]));
$a = 'Download Certificate';
}
}
return $a;
})
->addColumn('quiz_score', function ($data) {
$score = 0;
$quiz = QuizScore::where("track_id",$data->track_id)->where("user_id",$data->user_id)->first();
if($quiz){
$score = $quiz->score;
}
return $score;
})
->addColumn('progress', function ($data) {
$progress = 0;
$solve = Track::userProgress($data->user_id,$data->track_id);
if(!empty($solve)){
$progress = $solve;
}
return $progress."%";
})
->addColumn('user_use', function ($data) {
$user = UserApp::find($data->user_id);
if(!empty($user))
return $user->name." (".$user->email.")";
return '-';
})
->addColumn('track', function ($data) {
$track = Track::find($data->track_id);
return isset($track->title)?$track->title:"";
})->rawColumns(['quiz_score','status','user_use','track','urlQr'])
->addIndexColumn()->make(true);
}
*Edit:
I have realized that datatables returned a response that included used query like this:
New question: just where the hell that query json field configuration? On my eloquent query above there is no such thing as where and like query. Haven't found that things both in yajra and datatables documentation. What i want is to modify the where field to users.email instead voucher_bit_x.voucher_code
use columns.searchable
Using this parameter, you can define if DataTables should include this column in the filterable data in the table. You may want to use this option to disable search on generated columns such as 'Edit' and 'Delete' buttons for example.
$('#example').dataTable( {
"columnDefs":
[
{ "searchable": false, "targets": 0 }
]
});
This will disable the search of multiple columns as specified n the target. If you want multiple columns then try using
{ "searchable": false, "targets": [0,1,2] }
Where targets 0 1 and 2 are number of columns starting index from 0

Resources