Can i send a slug through a route? - laravel

In Laravel 5 we can send slugs to urls, something like this:
#foreach($records as $record)
<div class="btn-group-sm">
<a href="{{ url('business/'.$record->id.'/edit') }}" class="btn btn-warning"><i class="fa fa-edit"></i></a >
</div>
#endforeach
Would it be the same as this:
#foreach($records as $record)
<div class="btn-group-sm">
<a href="{{ route('businessEdit', $record->id) }}" class="btn btn-warning"><i class="fa fa-edit"></i></a >
</div>
#endforeach
Here's the route:
Route::get('/business/{id}/edit', [
'as' => 'businessEdit',
'uses' => 'BusinessCtrl#edit'
]);
Edit 1
Using the url way i can send the parameter and the address looks like domain.tld/business/4/edit but when using the route it looks like domain.tld/business?4 and it doesn't work.
Here's the edit func at BusinessCtrl:
public function edit($id)
{
$record = Business::find($id);
return view('Center.business.edit')->with('record', $record);
}

The route helper accepts an array as the second argument, so you will want to do this:
{{ route('businessEdit', [$record->id]) }}

Related

Individual ID's pdf print by Laravel8

I'm studying laravel using this gentleman's awesome code.
https://github.com/savanihd/Laravel-8-CRUD/blob/master/app/Http/Controllers/ProductController.php
I use Laravel Framework 8.48.2
I would like to add PDF pritabile view to each ID's "show" page
I could success PDF export using this simple test page.
public function generate_pdf() {
$pdf = \PDF::loadView('products.generate_pdf');
return $pdf->stream('yokoya_test.pdf');
}
so I had been trying to add PDF export to "show" function .
Here is my current code
Controller
public function each_print(Product $product)
{
$pdf = \PDF::loadView('products.each_print');
return $pdf->stream('each_print.pdf');
}
original index.blade.php code is this
<a class="btn btn-info" href="{{ route('products.show',$product->id) }}">Show</a>
I changed this as below
<a class="btn btn-info" href="{{ route('products.each_print',$product->id) }}">Print</a>
Here is my current WEB.php
Route::get('products/each_print', [ProductController::class, 'each_print']);
Route::resource('products', ProductController::class);
but I got this error
Symfony\Component\Routing\Exception\RouteNotFoundException
Route [products.each_print] not defined.
C:\xampp0827\htdocs\lara\ic0630-simple\vendor\laravel\framework\src\Illuminate\Routing\UrlGenerator.php:427
Could you teach me right code please?
UPDATE
index.blade.php
https://jsfiddle.net/diessses/m72bs54r/1/
each_print.blade.php
https://jsfiddle.net/diessses/8Lg5wot3/
you need define the name to the route like:
Route::get('products/each_print/{product}', [ProductController::class, 'each_print'])->name('products.each_print');
UPDATED
first refactor your code in the index blade table like:
<td>
<a class="btn btn-info" href="{{ route('products.show',$product->id) }}">detail</a>
<a class="btn btn-primary" href="{{ route('products.edit',$product->id) }}">edit</a>
<a class="btn btn-info" href="{{ route('products.each_print',$product->id) }}">Print</a>
<form action="{{ route('products.destroy',$product->id) }}" method="POST">
#csrf
#method('DELETE')
<i class="fas fa-trash-alt"></i>
<button type="submit" class="btn btn-danger">×</button>
</form>
</td>
and in the each_print function pass the product instance to the view like:
public function each_print(Product $product)
{
$pdf = \PDF::loadView('products.each_print', ['product' => $product]);
return $pdf->stream('each_print.pdf');
}

method links does not exist - laravel 5.4

I am using filter by serial number in table,, but when I click the button error like this
" method links does not exist"
this is my controller
public function show(Request $request)
{
$instrument = Instrument::when($request->serial_number, function ($query) use ($request) {
$query->where('serial_number', 'like', "%{$request->serial_number}%");
})->paginate(5);
$instrument->appends($request->only('serial_number'));
return view('settinginstrument.index', compact('settinginstrument'));
}
this is my blade:
<table class="table">
#foreach ($instruments as $instrument)
<tr>
<td>
Serial Number : {{ $instrument->serial_number }}
#if($instrument->customer !== NULL)
<div class="text-muted"><i class="fa fa-hospital-o" aria-hidden="true"></i> {{ $instrument->customer->name }}</div>
#endif
#if($instrument->contractType !== NULL)
<div class="text-muted"><i class="fa fa-compress" aria-hidden="true"></i> {{ $instrument->contractType->name }}</div>
#endif
</td>
<td>
<div class="pull-right">
<a type="button" href="{{ route('instrument.edit', ['instrumentType' => $instrumentType->id, 'instrument' => $instrument->id]) }}"
class="btn btn-success ">
<i class="fa fa-pencil"></i> Edit
</a>
#if($instrument->customer == NULL || $instrument->contractType == NULL)
<a href="{{ route('instrument.destroy', ['instrumentType' => $instrumentType->id, 'instrument' => $instrument->id]) }}"
data-method="delete" data-confirm="" class="btn btn-danger">
<i class="fa fa-trash"></i> <span class="hidden-xs">Delete</span>
</a>
#endif
</div>
</td>
</tr>
#endforeach
</table>
<div class="paginator text-center">{{ $instruments->links() }}</div>
#else
....................................
where wrong with my code?
You are not passing the param to the view:
public function show(Request $request)
{
$instruments = Instrument::when($request->serial_number, function ($query) use ($request) {
$query->where('serial_number', 'like', "%{$request->serial_number}%");
})->paginate(5);
$instrument->appends($request->only('serial_number'));
return view('settinginstrument.index',['instruments' => $instruments);
}
Then on the blade:
{{$instruments->links()}}
When you have zero counts of record and you are trying to access the links() then such issue occurs
Add on condition to check the record exists.
#if($instruments)
<div class="paginator text-center">{{ $instruments->links() }}</div>
#endif
Also in the controller you have one typo error $instruments and $instrument
I recommend that add the condition above the foreach
and on blank result show some message that record not found.
Update
Also pass the $instruments to the balde
$instruments = Instrument::when($request->serial_number, function ($query) use ($request) {
$query->where('serial_number', 'like', "%{$request->serial_number}%");
})->paginate(5);
$instruments->appends($request->only('serial_number'));
return view('settinginstrument.index', compact('instruments'));

Laravel href with POST

I'm trying to pass some data to my controller with an action href. I don't know why, but laravel passes the data with GET method, but instead of GET I need a POST. I don't really understand why laravel does that and coulnd't find an answer. I did that multiple times and my syntax seems to be correct. Can somebody have a look over it?
Blade:
<td>
#foreach($products as $product)
<a href="{{ action('ProductsController#delete', $product->id ) }}">
<span class="glyphicon glyphicon-trash"></span></a>
{{ $product->name }},
#endforeach
</td>
My Route:
Route::post('delete', ['as' => 'delete', 'uses' => 'ProductController#delete']);
In my Controller is just a:
public function delete()
{
return 'hello'; // just testing if it works
}
Error:
MethodNotAllowedHttpException in RouteCollection.php line 219....
I know it's a get method, cause if I'm trying to pass the data to my controller, my URL looks like this:
blabla.../products/delete?10
Is anything wrong with my syntax? I can't really see why it uses the get method.
I also tried a: data-method="post" insite of my <a> tag but this haven't worked either.
Thanks for taking time.
When you make a link with an anchor like <a href=example.com> your method will always be GET. This is like opening a URL in your browser, you make a GET request.
You should use a form to make that POST request to the delete method of the controller. Assuming you have the Illuminate HTML package for HTML and forms, you could do this:
{!! Form::open(['method' => 'DELETE', 'route' => $route]) !!}
{!! Form::submit('delete', ['onclick' => 'return confirm("Are you sure?");']) !!}
{!! Form::close() !!}
EDIT:
With a button tag:
{!! Form::open(['method' => 'DELETE', 'route' => $route]) !!}
<button type="submit"><i class="glyphicon glyphicon-remove"></i>Delete</button>
{!! Form::close() !!}
Here's your problem:
<a href="{{ action('ProductsController#delete', $product->id ) }}">
Anchor tags are always submitted over GET. It's a HTTP built in and is not Laravel specific.
POST is used when a form is submitted that specifies the POST HTTP Verb or the HTTP method is invoked by an AJAX request that specifies POST as the HTTP Verb.
Instead consider a submit type button in a form that submits what you need.
<td>
#foreach($products as $product)
<form method="POST" action="{{ route('delete') }}">
<input type="hidden" name="product_id" value="{{ $product->id }}">
{!! csrf_field() !!}
<button type="submit" class="btn">
<span class="glyphicon glyphicon-trash"></span>
</button>
</form>
{{ $product->name }},
#endforeach
</td>
And then in your controller:
public function delete()
{
// 'Die Dump' all of the input from the form / request
dd( request()->input()->all() );
// 'Die Dump' the specific input from the form
dd( request()->input('product_id') );
}
You will begin to see how GET and POST requests differ in sending of key/value pairs.
For more information:
http://www.tutorialspoint.com/http/http_methods.htm
Best for laravel 7. First define the form with given form id.
#auth
<form id="logout-form" action="{{ route('logout') }}" method="POST"
style="display: none;">
#csrf
</form>
#endauth
Then you can use the anchor tag for logout operation.In background,javascript working.Wherever the logout was fire then action to given form method of post method and logout route was working.
<a class="nav-link dropdown-toggle text-muted waves-effect waves-dark"
href="{{ route('logout') }}" onclick="event.preventDefault();document.getElementById('logout-form').submit();"
id="2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="mdi mdi-logout"></i>
</a>
Most benefit is the form was not loaded unnecesory.If the user was
logged in so far its load otherwise not
Laravel 7
By jQuery:
<form id="form" action="{{route('route_name')}}" method="POST">#csrf</form>
By JS:
<form id="form" action="{{route('route_name')}}" method="POST">#csrf</form>

Printing tasks per task list with Laravel 4 Eloquent

I'm trying to display several task lists in one page with their respective tasks. In my controller I'm using the following:
public function index()
{
$tasks_lists = Task_List::all();
$tasks = Task_List::find(1)->tasks;
return View::make('tasks.index', array(
'tasks' => $tasks,
'tasks_lists' => $tasks_lists
));
}
Using
$tasks = Task_List::find(1)->tasks;
Will return for all tasks lists the tasks appointed to task list 1. So I'm guessing here is my problem, what type of clause should I be using to achieve my goal?
My foreach in my view:
#foreach ($tasks_lists as $task_list)
<h2>{{ $task_list->title }}</h2>
<ul>
#foreach ($tasks as $task)
<li>
{{ Form::open() }}
<input type="checkbox" name="task" value="{{ $task->id }}" />{{ $task->name }}
{{ Form::close() }}
</li>
#endforeach
</ul>
#endforeach
Instead of fetching the tasks for one of the Task_List models (in your case the one with id 1) you should get them for every task_list.
Do this in your view:
#foreach ($tasks_lists as $task_list)
<h2>{{ $task_list->title }}</h2>
<ul>
#foreach ($task_list->tasks as $task)
{{-- etc --}
#endforeach
</ul>
#endforeach
Attention: if you leave it that way it will make a query on the db every time you call ->tasks. You need to use eager loading. This is done by adding with('relationship-name')
$tasks_lists = Task_List::with('tasks')->get();
return View::make('tasks.index', array(
'tasks_lists' => $tasks_lists
));
You don't need to look for the tasks in the controller, so that can be simply removed:
public function index()
{
$tasks_lists = Task_List::all();
$tasks = Task_List::find(1)->tasks;
return View::make('tasks.index', array(
'tasks' => $tasks,
'tasks_lists' => $tasks_lists
));
}
Then, you'll need to get the tasks for each task list in the view, like this:
#foreach ($tasks_lists as $task_list)
<h2>{{ $task_list->title }}</h2>
<ul>
#foreach ($task_list->tasks as $task)
<li>
{{ Form::open() }}
<input type="checkbox" name="task" value="{{ $task->id }}" />{{ $task->name }}
{{ Form::close() }}
</li>
#endforeach
</ul>
#endforeach
And that should be enough. :)

Wildcards in Laravel

With the following code, I'm trying to pass a wildcard to my controller but I'm not sure how I can pass the URL dynamically and I'm not sure how to do this without creating a route for each url, which would take forever. Currently, I'm attempting to do it like so:
<a href="{{ route('purchase-get') }}/$item->name">
Here is the rest of the code
<tbody class="text-center">
#foreach (array_chunk($items->all(), 3) as $item_each)
<tr>
#foreach($item_each as $item)
<td>
<a href="{{ route('purchase-get') }}/$item->name">
{{ HTML::image($item->image_url, 'item-image', array('class' => 'item-image-row')) }}
<h4>{{ $item->item }}</h4>
<span class="text-muted">{{ $item->cost }}</span>
</a>
</td>
#endforeach
</tr>
#endforeach
</tbody>
You can link to a wildcard with named routes:
Route::get('/', array('as' => 'index', function()
{
$slug = 'product-1';
return 'link to product';
}));
Then catch the names route with the wildcard slug:
Route::get('products/{slug}', array('as' => 'products', function($slug)
{
$product = Product::where('slug','=',$slug)->first();
return $product;
}));

Resources