Laravel Pagination on POST request - laravel

Im using Laravel v7 and i have a question about pagination.
So far im using 2 routes, 1rst to return a view with all rows from database, and 2nd receives an input and returns that view with the rows filtered by that input value.
But im using pagination, and on the 2nd route, when i try to go to 2nd page it gives me an error:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The GET method is not supported for this route. Supported methods: POST.
I've tried to change my form method to GET but i need that the token doesn't appear on the page URL and beside that, when i go to 2nd page, it returns all the rows again.
Thats my code so far:
Routes:
Route::get('concessions', 'ConcessionController#index')->name('concessions.index');
Route::post('concessions/search', 'ConcessionController#search')->name('concessions.search');
Controller
class ConcessionController extends Controller
{
public function index()
{
$concessions = DB::table('concessions')->paginate(12);
return view('admin.concessions.index', compact('concessions'));
}
public function search(Request $request)
{
$name = $request->name;
$concessions = Concession::where('name', 'like', '%' . $name . '%')->paginate(12);
return view('admin.concessions.index', compact('concessions', 'name'));
}
}
Any way to do that?

Laravel pagination only works with get parameters.
You should use GET method for your search page. POST requests aren't meant for the purpose of displaying data. Why? There are many reasons, but to be short I will give you three examples :
1. When you access the first page, you get the data by GET request,
not POST request. So if you want to use POST request, you
need to access the page as POST request by sending data with
POST method.
2. With GET parameters, let's say you are on 5th page - you can
copy the link and paste it to friend and he will be able to view
the same content as you. With POST this is impossible.
3. You can not use back button with POST requests, if you manage to
get pagination to work.
POST requests are useful when you need to submit data to the server, in order to create new record, for example.
So I suggest you to change your route type to GET.

From my perspective, if you change your route code similar to below code, it will work properly with both methods of GET and POST.
Route::any('concessions/search', 'ConcessionController#search')->name('concessions.search');

Related

Passing data from blade to blade in Laravel

I have a page where you can create your workout plan. Second page contains "pre-saved" workouts and I want them to load by passing parameters from second page to first. If you directly access first page, you create your workout plan from scratch.
// first page = https://prnt.sc/y4q77z
// second page = https://prnt.sc/y4qfem ; where you can check which one you want to pass to first page
// final step looks like this: https://prnt.sc/y4qh2q - but my URL looks like this:
www.example.com/training/plan?sabloni%5B%5D=84&sabloni%5B%5D=85&sabloni%5B%5D=86
this 84,85,86 are IDS
Can I pass params without changing URL ? Like having only /training/plan without anything after ?
public function plan(Request $request){
$workout = false;
if($request->workout){
$workout = $request->workout;
$workout = SablonTrening::find($sabloni); // $workout = array [1,3,4,5,6]
}
return view('trener.dodaj_trening', compact('workout'));
}
If you are getting to the /training/plan page with GET request, you could simply change it to POST. That way the parameters would be hidden in the URL but would be present in the request body. You would need a new post route:
Route::post('/training/plan', 'YourController#plan')->name('training.plan');
And then, in the form where you are selecting these plans, change the method on submit:
<form action="{{route('training.plan')}}">
//Your inputs
</form>
Your method should still work if your inputs stay the same.
Note: Not sure you would still keep the functionalities that you need, since I can't see all the logic you have.
If you have any questions, let me know.
To pass data from on blade to another blade.
At the end of first post before redirect()-route('myroute') add $request->session()->put('data', $mydata);
At the begining of the route 'myroute', just get back your data with $data = $request->old('data');

How to properly forward parameters from a POST result and avoid refresh (re-submit), with Laravel 5?

This is a basic issue, when submitting and performing a post, you normally want to avoid giving the user the chance to re-iterate the submit by refreshing or going back and forth with browser history.
(Backend re-submit, controls and checking is not questioned here. Of course they should be in place for security)
My solution was to have in Laravel web routes defined a post and a get route.
Like:
Route::post('/action', 'ActionController#doAction')->name('do.action');
Route::get('/action', 'ActionController#doActionConfirm')->name('do.action.confirm');
In ActionController something like:
public function doAction(Request $request)
{
....
return redirect()->route('do.action.confirm', [ 'data' =>
base64_encode(json_encode([
'action_id'=> $action_id,
'sent_to'=> $email,
'sent_success'=> $sent_success,
'sent_errors'=> $sent_errors,
]))]);
}
....
public function doActionConfirm(Request $request)
{
return view('confirmation')->with('data',$request->input('data'));
}
Then in my confirmation.blade.php get that $data decoded and displayed.
Is this the correct way to do it with Laravel?
What I don't like here:
is there's a better and more elegant way to forward data from the redirect()
is there a better way to manage get parameters to the GET route just to avoid people understanding and trying to inject unwanted data to the confirmation blade? (even if they will obtain nothing but no-sense views..because the page is doing nothing, it's simply displaying data in HTML blade)

How do I pass data from my controller to a view in Laravel 5.5?

I have a function that I'm trying to pass some data to a view. I can't get the Route to recognize the data, it just keeps saying my variables are undefined. Here's what I'm trying to do:
return redirect('confirm')->with([
'name'=>$name,
'service'=>$service,
'$email_address'=>$email_address
]);
Then in my web.php file, I have:
Route::get ('confirm', function($name,$service,$email_address){
return view('confirm',compact('name','service','email_address'));
})->name('confirm');
Laravel just throws an error "Missing argument 1 for Illuminate\Routing\Router::{closure}()"
I'm at a complete loss, I've tried this a bunch of different ways. If I call the view right from my controller, it works fine, but then URL isn't what I want it to be, so it seems like I have to return the redirect and reference the data in my route definition. Can anyone enlighten me?
If it's ok to show the email in the route then you can correct the problem like this :
Route::get ('confirm/{name}/{service}/{email_address}', function($name,$service,$email_address){
return view('confirm',compact('name','service','email_address'));
})->name('confirm');
And in the controller :
return \Redirect::route('confirm', [
'name'=>$name,
'service'=>$service,
'email_address'=>$email_address
]);
Ps : this is not recommended i just answer you problem but there is a better way to do it, passing just an id for exsample then find the user by id then take his email and other stuff.

Associate relationship afterwards

Version used: Laravel 5.4
We have a post and that post can have several pictures associated with it. We use a controller to store the post and an other one to store the pictures.
We set the relationship in the models like so:
class Post extends Model
{
public function pictures()
{
return $this->hasMany(Picture::class);
}
}
class Picture extends Model
{
public function post()
{
return $this->belongsTo(Post::class);
}
}
When I go to the form to create a new post, I can add pictures to that post before I actually store the post. Which means that when I store a picture I still don't have a post id to associated it to.
My questions is:
Using only php, is there a clean way to associate the pictures to the post before or afterwards ?
The solution I am currently using is that when I go to the form to create a new post, a blank new post is created before hand and I pass the id on the url. It has to be a better way to do it.
You can try this
First create the form when user access the create post page (as you are already doing).
Suppose this is your function which is showing the create post view
public function showCreatePost()
{
$post = Post::create(['field_name' => '', // put your attributes]);
// pass other data as well if you want.
return view('your_create_view',compact('postId',$postId));
}
change your route of imageupload which will have postid . for example
Route::post('post/image/{postId}','SomeController#somefunction');
create one route for editing the post and use it for editing the post which will have post id.
Route::post('post/edit/{postId}','SomeController#someOtherfunction');
Now use these two routes as form action and you can edit the post and upload the image. route example below
Showing the id in url is not a good idea. so by this way you can try and let me know if you face any problem.

Returning a variable from a filter. Laravel 4

I am new to Laravel and I am trying to set up some basic routing logic. I have a route that will process a certain URL pattern. These URLs will usually be an ajax request (returning data for a popup window). However, search engines and users with javascript disabled will follow a normal link, so I want the data to be returned on a separate page. To do this, I need to determine if the request is ajax. I understand I can do this using:
if(Request::ajax()){
//
}
My plan was to do this as part of a 'before' filter attached to the route. If my thinking is correct, I would need to return a boolean ajax=true/false back from the filter. Maybe this is a very simple question, but I can't find anywhere that explains how you actually return a value like this from a filter? Everything I can find seems to assume that the default outcome of any filter logic must be a redirect.
Thanks
EDIT: I've come to the conclusion that I am simply not using the filtering method in the way it was intended, and simply placing the handler in my controller method. But I would still like to know if it is possible to return data from a filter.
In a controller:
if(Request::ajax()){
return Response::json(['message' => 'Hi. Your request was ajax!', 'status' => 1]);
}
The simple solution I found for that is to use Session::flash which populates data for the next request only and you can easily get the result anywhere. So for example :
Route::filter('something', function() {
if(false) {
View:make('error); // or whenever you want
} else {
return Session:flash('result_var', $my_result_var);
}
});

Resources