Laravel : use parameter that taken from url for dynamic table name - php

In controller, I want to use dynamic table name that taken from url and then show data using package chumper/datatable.
When I browse mysite.com/unit/rentin/send I have an AJAX error because the used table name is send_{unit} whereas my registered table name is send_rentin.
Here is my code:
routes.php
Route::resource('unit.send', 'SendController');
SendController.php
class SendController extends \BaseController {
public function index($unit)
{
$table = new Send; // Send is my model
$table->setTable('send_' .$unit);
if (Datatable::shouldHandle())
{
return Datatable::collection($table::all())
->showColumns('admin_no')
->addColumn('admin_date', function ($model) {
return date('d M Y', strtotime($model->admin_date));
})
->make();
}
return View::make('send.index')->withUnit($unit);
}
}
}
What do I miss?

After some hour try, I found a mistake at my views.
Wrong
{{ Datatable::table()
->addColumn('no', 'date')
->setUrl(route('unit.send.index'))
->render('datatable.uikit') }}
Right
{{ Datatable::table()
->addColumn('no', 'date')
->setUrl(route('unit.send.index', ['unit'=>$unit]))
->render('datatable.uikit') }}

Related

Call to undefined function App\Transaksi()

i have a problem with my coding, i want to count user on my database but it's appear to be like this
Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR)
Call to undefined function App\Transaksi()**
Here's my index.php
<div class="col-lg-4 col-xs-6">
<!-- small box -->
<div class="small-box bg-aqua">
<div class="inner">
<h3>{{ $list->transaksi }}</h3>
<p>Transaksi</p>
</div>
and my controller.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class BackController extends Controller
{
public function list()
{
$transaksi = \App\Transaksi::get();
$transaksi = \App\Transaksi('id')->count();
return view('/admin', compact('list'));
}
}
and my routes
Route::group(['prefix'=>'user','middleware' => ['auth', 'role:member']],
function (){
Route::get('/mybook','FrontController#mybook');
});
Route::group(['prefix'=>'admin','middleware' => ['auth', 'role:admin']], function(){
Route::get('/',function() {
return view('admin.index');
});
Route::get('/','BackController#list');
Route::get('logout','UserController#logout');
Thanks.
Sorry For the late reply main bug in your list function is
public function list()
{
$transaksi = \App\Transaksi::get();
$transaksi = \App\Transaksi('id')->count();
return view('/admin', compact('list'));
}
You are Using the Same varible name to
Retrive all the records $transaksi = \App\Transaksi::get(); and
also for the Counting all the records $transaksi = \App\Transaksi('id')->count();
and also you are not passing it to the balde viewer
instead You are passing the function name list
return view('/admin', compact('list'));
Solution To you problem
First you need not to write \App\Transaksi in every where
Just Go to the top of the controller and add this line
use App\Transaksi;
Then Your function
There are several ways to count the record
Method 1:
public function list()
{
$transaksi= Transaksi::latest()->paginate(10);
return view('transaksi.index', compact('transaksi'));
}
here view('transaksi.index') refers to
Projectname/resources/views/transaksi/index.blade.php
Then in your index.blade.php to get the count just use the code
<h3 class="modal-title">{{ $transaksi->total() }} {{ str_plural('Transaksi', $transaksi->count()) }} </h3>
Method 2:
public function list()
{
$transaksi = Transaksi::latest()->get();
$recordCount = Transaksi::count();
return view('transaksi.index', compact('transaksi','recordCount'));
}
Then in your blade file
<h3>{{ $recordCount }}</h3>
Hope it helps
Your controller isn't doing much right now. The view needs to be a valid blade template file, e.g. admin.index, not /admin. You then need to pass a variable into the view, not the function name.
public function list()
{
$transaksi = \App\Transaksi::all();
$numTransaksi = $transaksi->count();
return view('admin.index', compact('numTransaksi'));
}
Then in the view you can access the count via {{ $numTransaksi }}.
You also have two routes for / in your web.php. You should get rid of the first one if you want the BackController#list function to call properly.
Is this what you mean?

How to select an id in route pass it into the controller and fetch data against that id and redirect it view again in laravel 5.6

How to pass id from veiw into controller in then into another view again??
First of all this a basic question you should be able to search it anywhere on the internet. any how below is the solution.
web/routes.php:
Route::get('user/{id}','USerController#find')->name('user.get');
Or by passing user object in the route:
Route::get('user/{user}','USerController#find')->name('user.get');
UserController:
the below function accepts user object as a parameter in the route we defined above.
public function find(user $user)
{
return view('user.detail',compact('user'))
}
or
public function find($id)
{
$user = USer::find($id);
return view('user.detail',compact('user'))
}
resources/view/user/detail.blade.php:
{{ $user -> name }}
{{ $user -> email }}
and in order visit the route user.find use the below line:
View Detail
No you can use this code as reference to your project.
first solution is .
change route
Route::get('/show_vedio/{$id}', 'VedioController#show')->name(show_videos);
and use this {{ route('show_vedios', $vedio->id )}} in href
it's not entirely clear what you are trying to do, maybe i will help you:
public function show(int $id): View
{
$video = Video::find($id);
return view('video.show', ['video' => $video]);
}

Laravel Datatables - Multiple tables on one view

I'm using laravel 5.4 and the latest version of yajra/laravel-datatables as a service.
I have it working fine with one datatable on a page. I want to create a dashboard of unrelated tables. Users, products, bookings etc.
I was hoping to have my controller look something like this:
public function index(ProductsDataTable $productDatatable, UsersDataTable $userDatatable)
{
$user = Auth::user();
$products = $user->products;
return view('admin.dashboard', compact('products', 'user', 'productDatatable', 'userDatatable'));
}
and in my blade do
#section('content')
{!! $productDatatable->table() !!}
{!! $userDatatable->table() !!}
#endsection
#push('scripts')
{!! $dataTable->scripts() !!}
#endpush
However this obviously doesn't work. I'm unsure how to proceed.
I tried to create a route for each datatable but wasn't sure how to reference it from my dashboard controller.
I'm sure there's a better way of implementing multiple tables in one view, but this is what I came up with after reviewing this. Comments/improvements would be highly appreciated.
Controller
The controller will render the tables once in the index() method but will fetch data from both the getUsers() method or getProducts() method.
// DashboardController.php
public function index(UsersDataTable $usersDataTable, ProductsDataTable $productsDataTable)
{
return view('dashboard.index', [
'usersDataTable' => $usersDataTable->html(),
'productsDataTable' => $productsDataTable->html()
]);
}
//Gets Users JSON
public function getUsers(UsersDataTable $usersDataTable)
{
return $usersDataTable->render('admin.dashboard');
}
//Gets Products JSON
public function getProducts(ProductsDataTable $productsDataTable)
{
return $productsDataTable->render('admin.dashboard');
}
Routes
Add two extra routes that will be used to fetch Users and Projects data.
// web.php
Route::get('/', 'DashboardController#index')->name('dashboard.index');
Route::get('projects', 'DashboardController#getProjects')->name('dashboard.projects');
Route::get('users', 'DashboardController#getUsers')->name('dashboard.users');
DataTables Service Class
For both the UsersDataTable and ProductsDataTable service classes, include the relevant routes we created above.
// UsersDataTable.php
public function html()
{
return $this->builder()
->minifiedAjax( route('dashboard.users') );
}
View
// dashboard.blade.php
#section('content')
{!! $productsDataTable->table() !!}
{!! $usersDataTable->table() !!}
#endsection
#push('scripts')
{!! $productsDataTable->scripts() !!}
{!! $usersDataTable->scripts() !!}
#endpush
Submitted a question to the creator of the package. This is his response:
Unfortunately, DataTable service class is designed to handle single instance. However, I think we can make a workaround for it by adding additional query param in our request for us to identify which class is being requested to handle the request.
Maybe something like below:
public function index(ProductsDataTable $productDatatable, UsersDataTable $userDatatable)
{
if (request()->has('product') {
return $productDatatable->render('view');
}
if (request()->has('user') {
return $productDatatable->render('view');
}
$user = Auth::user();
$products = $user->products;
return view('admin.dashboard', compact('products', 'user', 'productDatatable', 'userDatatable'));
}
Step 1:
Define a route '/home-page' in web.php/route.php' (depending on the laravel version you are using) that returns the view called 'dt.blade.php'. (we will create this view in step 4)
i.e. Route::get('/home-page', function(){
return view('dt');
});
Step 2:
Suppose you want to display two dataTables in 'dt.blade.php' view. (first datatable shows all the students in a school while other shows all the classes in a school)
To do that, you need to create two Builder instances ('Builder' class belongs to DataTables package) in the '/home-page' route's callback function and pass them to the 'dt.blade.php' view . i.e
Route::get('/home-page', function() {
$student_dt = app(Builder::class)->columns(['id', 'student_name'])->ajax('/show-students-datatable')->setTableId('t1');
$classes_dt = app(Builder::class)->columns(['id', 'class_name'])->ajax('show-classes-datatable')->setTableId('t2');
return view('dt', compact('student_dt', 'classes_dt'));
});
Step 3
Now define two more routes in web.php/route.php file:
Route::get('/show-students-datatable', function () {
return datatables(App\Student::query()->select(['id', 'student_name']))->toJson();
});
Route::get('/show-classes-datatable', function () {
return datatables(App\Class::query()->select(['id', 'class_name'])))->toJson();
});
Step 4
Define the 'db.blade.php' view, this view show both the dataTables that were passed to it in step 1.
#extends('layouts.master')
#section('content')
{{ $student_dt->table() }}
{{ $classes_dt->table() }}
#endsection
#push('scripts')
{{$student_dt->scripts()}}
{{$classes_dt->scripts()}}
#endpush

Submitting like using Ajax within Laravel application

So i've modified some code to add a Like function to a table called sources, this sources have the relation "hasMany" with the table likes.
It doesn't work and I don't get any errors, neither Javascript or PHP errors.
When I like the page it seems like the Ajax don't get called because the page reload to /public/view#, so nothing get submitted to the database.
I don't know how to sort this out.
View:
#foreach($post->sources as $source)
<a>{{$source['link']}}</a>
<div class="interaction" data-sourceid=" {{ $source['id'] }} ">
{{ Auth::user()->likes()->where('source_id', $source['id'])->first() ? Auth::user()->likes()->where('source_id', $source['id'])->first()->like == 1 ? 'You like this source' : 'Like' : 'Like' }} |
{{ Auth::user()->likes()->where('source_id', $source['id'])->first() ? Auth::user()->likes()->where('source_id', $source['id'])->first()->like == -1 ? 'You don\'t like this source' : 'Dislike' : 'Dislike' }}
</div>
<br>
#endforeach
<script>
var token = '{{ csrf_token() }}';
var urlLikeSource = '{{ route('likesource') }}';
</script>
app.js:
$('.like-source').on('click', function(event){
event.preventDefault();
sourceId = event.target.parentNode.dataset['sourceid'];
var isLike = event.target.previousElementSibling == null; //Checks if it's a like or dislike.
$.ajax({
method: 'POST',
url: urlLikeSource,
data: {isLike: isLike, souceId: sourceId, _token: token}
})
.done(function(){
//Change the page when .ajax has been executed.
event.target.innerText = isLike ? event.target.innerText == 'Like' ? 'You like this source' : 'Like' : event.target.innerText == 'Dislike' ? 'You don\'t like this source' : 'Dislike';
//Make sure you can't dislike and like at the same time.
if(isLike){
event.target.nextElementSibling.innerText = 'Dislike';
} else {
event.target.previousElementSibling.innerText = 'Like';
}
});
});
routes:
Route::post('/likesource', [
'uses' => 'SourceController#sourceLikeSource',
'as' => 'likesource'
]);
SourceController.php:
<?php
namespace App\Http\Controllers;
use App\Comment;
use App\Post;
use App\Like;
use App\Source;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class SourceController extends Controller{
public function sourceLikeSource(Request $request)
{
$source_id = $request['sourceId'];
$is_like = $request['isLike'] === 'true'; //Get's passed as string in request, changed to boolean.
$update = false;
//REDO WITH SMARTER SOLUTION
if($is_like == 0){
$is_like = -1;
}
$source = Source::find($source_id);
if(!$source){
return null;
}
$user = Auth::user();
$like = $user->likes()->where('source_id', $source_id)->first(); //First has to be specified
if($like){
$already_like = $like->like;
$update = true;
//Deletes if it already exists.
if($already_like == $is_like){
$like->delete();
return null;
}
} else {
$like = new Like(); //Creates new row for Like in table
}
$like->like = $is_like; //Set's whatever $like->like to whatever $request['isLike'] passed.
$like->user_id = $user->id;
$like->source_id = $source_id;
if($update){
$like->update();
}else{
$like->save();
}
return null;
}
}
Like.php model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Like extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
public function post()
{
return $this->belongsTo('App\Post');
}
public function source()
{
return $this->belongsTo('App\Source');
}
public function comment()
{
return $this->belongsTo('App\Comment');
}
}
Source.php model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Source extends Model
{
public function post()
{
return $this->belongsTo('App\Post');
}
public function likes()
{
return $this->hasMany('App\Like');
}
}
Edit:
Rookie mistake by me, I cleared the browser cache. The browser used an old app.js file. Now the ajax seemed to get called correctly, however there's still no new rows in the likes table.
Edit 2:
I gave the data within the Ajax call sourceId: 1 and isLike: 2. There were still no new rows being created in the table likes.
So the problem seems to be in the routes, controller or any of the models.
Edit 3:
I changed the route to a route I knew works properly, I added a csfr_token exception to make sure the token wasn't screwing anything up. I made sure everything in the models were right and I finally made sure everything in the controller was being called correctly.
I truly can't find any problem.
The only thing I can think about is that the likes table "belongsTo" a lot of tables. I made the post_id, comment_id and source_id nullable when I created the table migration.
Should I use some other relationship in the models?

Having trouble creating a Like system for comments in a Laravel Project

I'm creating a project using Laravel. Users are able to like comments. I want to display a "like" button so a user can like a comment and if the user has already liked the comment I want that button to be "unlike" so a user can unlike the liked comment
In my database I have a likes table:
| id | user_id | comment_id |
My Like Model looks like this:
class Like extends \Eloquent {
protected $fillable = ['user_id', 'comment_id'];
protected $table = 'likes';
public function owner()
{
return $this->belongsTo('Acme\Users\User', 'user_id');
}
}
Comment Model looks like this:
class Comment extends \Eloquent {
protected $fillable = ['user_id', 'post_id', 'body'];
protected $table = 'comments';
public function owner()
{
return $this->belongsTo('Acme\Users\User', 'user_id');
}
public function likes()
{
return $this->hasMany('Acme\Likes\Like');
}
}
User model:
class User extends Eloquent {
public function comments()
{
return $this->hasMany('Acme\Comments\Comment');
}
public function likes()
{
return $this->hasMany('Acme\Likes\Like');
}
}
Likes controller :
class LikesController extends \BaseController {
use CommanderTrait;
/**
* Like a comment
* #return Response
*/
public function commentLike()
{
// using a command bus. Basically making a post to the likes table assigning user_id and comment_id then redirect back
extract(Input::only('user_id', 'comment_id'));
$this->execute(new CommentLikeCommand($user_id, $comment_id));
return Redirect::back();
}
public function unlike()
{
$like = new Like;
$user = Auth::user();
$id = Input::only('comment_id');
$like->where('user_id', $user->id)->where('comment_id', $id)->first()->delete();
return Redirect::back();
}
}
In my view I'm able to get the comments via $comment, and I'm able to get likes via $comment->like have:
#foreach($post->comments as $comment)
<div class="user-comment">
<p class="comment">
{{ $comment->owner->first_name }} {{ $comment->owner->last_name }} {{ $comment->body }}
</p>
<div class="com-details">
<!-- how long ago the comment was posted -->
<div class="com-time-container">
{{ $comment->created_at->diffForHumans() }} ·
</div>
<!-- HERE IS WHERE I WANT THE LIKE AND UNLIKE BUTTONS TO DISPLAY -->
#if ($comment->likes->owner->id === $currentUser->id)
{{ Form::open(['route' => 'like']) }}
{{ Form::hidden('user_id', $currentUser->id) }}
{{ Form::hidden('comment_id', $comment->id) }}
<button type="submit" class="com-like">Like</button>
{{ Form::close() }}
#else
{{ Form::open(['route' => 'unlike']) }}
{{ Form::hidden('user_id', $currentUser->id) }}
{{ Form::hidden('comment_id', $comment->id) }}
<button type="submit" class="com-like">Unlike</button>
{{ Form::close() }}
#endif
<!-- how many users like this comment -->
<span class="likes"> · {{ $comment->likes->count() }}</span>
</div>
</div><!--user-comment end-->
#endforeach
Im trying to set up an if statement to see if the current user has liked the status but im not sure how this is done? If the user has not liked the comment yet I want the "like" button to display. If the user has liked the comment I want the "unlike" button to display. I thought I could say #if($comment->likes->owner->id === $currentUser->id) but I get Undefined property. How would I go about doing this?
$comment->likes is a Collection of Like objects. To access the owner property, you would need to iterate the collection.
However, another option is to use the available methods on the Collection to do what you need:
#if (in_array($currentUser->id, $comment->likes->lists('user_id')))
$comment->likes->lists('user_id') will return an array of all the user_id values in the Collection of Likes for the Comment. in_array() will check if the $currentUser->id is in that array.
I haven't worked much with Laravel, so my syntax and terminology might be a bit off, but it should be the right idea.
Basically, $comment->likes is a list of likes on that comment. You need to iterate through those likes and check if one of them is by the current user. If one of them is by the current user, then show the unlike button. Otherwise, show the like button.
Not sure what that'd look like in Blade, but here's some pseudo-code:
$currentUserLiked = false;
// go through all of the comment's likes
foreach ($comment->likes as $like)
{
// check if this like is by the current user
if ($like->owner->id == $currentUser->id)
{
$currentUserLiked = true;
break;
}
}
if ($currentUserLiked)
{
showUnlikeButton();
}
else
{
showLikeButton();
}

Categories