Laravel redirecting problem when submitting form - laravel

I have following routes
Route::get('videos/{video}/edit', 'VideoController#edit');
Route::put('videos/{video}/update2', 'VideoController#update2');
first route loads the following stripped view
<form action='/videos/{{$video->uid}}/update2' method='post'>
<button class='btn btn-default' type='submit'>Update</button>
{{csrf_field()}}
{{method_field('PUT')}}
</form>
from the controller code listed below
class VideoController extends Controller{
public function edit(\App\Models\Video $video){
return view('video.edit',[
'video' => $video,
]);
}
public function update2(VideoUpdateRequest $request,\App\Models\Video $video){
echo "ok";
}
}
according to this code, expected behavior should be to see "ok", instead of that I get HTTP 302 Redirect as shown below in Dev Console.
This is a weird behavior, which is not expected. How to get the expected behavior of displaying "OK" after submitting the form? How to debug this?
SOLVED
Problem was with HTML elements in the form are not having 'name' attributes thus Laravel Form Request Validation redirects back. after adding those missing attributes, form works as expected.

SOLVED
Problem was with HTML elements in the form are not having 'name' attributes thus Laravel Form Request Validation redirects back. after adding those missing attributes, form works as expected.

Related

Laravel 9 - Submitting a form to a route leads to /null and doesn't do anything

I'm using soft deletes and trying to make a function to restore the deleted row. Really everything to do with submitting the form doesn't work, even deleting...
My tags are within a forelse loop, maybe that's the cause??
Route is (this is above my resource route):
Route::post('/post/restore/{id}', [PostController::class, 'restore'])
->name('post.restore');
Controller is:
public function restore($id)
{
dd($id);
}
Form/view is:
<form action="{{route('post.restore', $post->id)}}" method="POST">
#csrf
<button type="submit" class="dropdown-item popup" data-confirm="Would you like to restore?">Restore</button>
</form>
After submitting, it just takes me to:
domainURL/post/null
and gives a 404 error
Any advice?? I also tried it without the {id} at the end of the route, same results
I think you are using the wrong syntax for route function, instead of this:
route('post.restore', $post->id)
you should use it like this:
route('post.restore', ['id' => $post->id])
you can read more here as well.
I figured it out... my "would you like to restore?" javascript function was breaking the form. I was using javascript to popup a confirmation message before submitting and during that process it lost the ID
I got rid of that and it works fine
Thank you!

Correctly redirect to another page with inertia?

I"m trying to redirect on click to another page, for some reason it's not working. This is the code on my vue where the redirect buttons are. I've tried two different ways and neither are working.
<el-row class="import-btn">
<a :href="'/imports/teachers'">
<el-button type="warning">
Importar
</el-button>
</a>
</el-row>
<el-row class="import-btn">
<el-button type="warning" #click="redirectStudents()">
Importar
</el-button>
</el-row>
redirectStudents() {
this.$inertia.visit('/imports/students');
},
I have the web.php routes like this
Route::resource('imports/students', 'ImportStudentController');
Route::resource('imports/teachers', 'ImportTeacherController');
In both the controllers I currently just have the index() filled
public function index()
{
return Inertia::render('Import/Students');
}
public function index()
{
return Inertia::render('Import/Teachers');
}
In the vue files for Teachers and Students I have basic layout and titles for those pages, so they're not empty.
When I click on the <a :href=""> button I get redirected to the link but the page is totally blank and when I click on the other button it opens up like a window inside also blank.
What is the correct way to fix this?
Links
Creating a link in Inertia.js is pretty straight-forward. It has a custom tag as to denote that it's something that falls into the domain of the framework.
<inertia-link href="/">Home</inertia-link>
UPDATE: Since version 0.7.0 of inertia-vue and version 0.5.0 of inertia-vue3 there has been a breaking change with an update to how links work.
For your Vue.js 2 components:
import { Link } from '#inertiajs/inertia-vue'
<Link href="/">Home</Link>
For Vue.js 3 components:
import { Link } from '#inertiajs/inertia-vue3'
<Link href="/">Home</Link>
Under the hood there is a <a> tag, which also means that all attributes passed will be sent to that underlying <a> tag.
Redirect
If all you're really looking for is a simple link-click - and not a redirect per se - then you're fine with the above code.
If you're instead interesting in a redirect - for example after updating a user or the something similar - then simply using the Redirect facade like you would do in any other Laravel application is sufficient.
class UsersController extends Controller
{
public function store()
{
User::create(
Request::validate([
'name' => ['required', 'max:50'],
'email' => ['required', 'max:50', 'email'],
])
);
return Redirect::route('users');
}
}
If you've installed the Inertia.js laravel adapter package, then this redirect will return a 303 status code, which is the same as a 302 status code, except that the request is changed into a GET request.
Hope this helps!

The PUT method is not supported for this route

I cannot submit form information through to store function in laravel controller. The form needs to create a - new - profile for a registered user.
I have even recreated the project, and redone the form - moving back into plain html as I suspect that the laravelCollective functions may be causing it but still the same error.
I have even rearranged the the form attributes as suggested in another post/thread.
I have even recreated the project, and redone the form - moving back into plain html as I suspect that the laravelCollective functions may be causing it but still the same error.
I have even rearranged the the form attributes as suggested in another post/thread.
The Form:
< form method="POST" enctype="multipart/form-data" action="{{ url('users/profile') }}" accept-charset="UTF-8" >
#csrf
...
// input fields here
...
< /form >
The Routes:
Route::resource('users/profile', 'ProfileController');
Route::get('/home', 'HomeController#index')->name('home');
Route::resource('users', 'UserController');
Route::post('users/profile', 'ProfileController#store')->name('profile.store');
The ProfileController#store function:
//some code omitted
public function store(Request $request)
{
$this->validate($request, [
'firstname'=>'required',
'lastname'=>'required',
...
'desc'=>'required'
]);
//handle file upload
if($request->hasFile('cover_image')) {
//Get file name with extension
$fileNameWithExt = $request->file('cover_image')->getClientOriginalName();
//Just file name
$fileName = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
//Just Ext
$ext = $request->file('cover_image')->getClientOriginalExtension();
//FileName to Store
$fileNameToStore = $fileName.'_'.time().'_'.$ext;
//upload image
$path = $request->file('cover_image')->storeAs('public/users/'.auth()->user()->id.'cover_images/'.$request->input('firstname').'_'.$request->input('lastname').'_'.auth()->user()->id.'/',$fileNameToStore);
} else {
$fileNameToStore = 'noimage.jpg';
}
/*
*/
$profile = new Profile;
$profile->firstname = $request->input('firstname');
$profile->lastname = $request->input('lastname');
...
$profile->desc = $request->input('desc');
$profile->save();
return redirect('/users/profile');//->with('success','Profile Created');
}
The famous error:
Symfony \ Component \ HttpKernel \ Exception \
MethodNotAllowedHttpException The PUT method is not supported for this
route. Supported methods: GET, HEAD, POST.
Not sure what is causing the error, help appreciated.
If I understand it correctly this is for store function right? then you don't have to put #method('PUT') inside your form it should POST. The route of store in resource is POST.
this is your code that i deleted the #method('PUT')
< form method="POST" enctype="multipart/form-data" action="{{ url('users/profile') }}" accept-charset="UTF-8" >
#csrf ...
// input fields here ...
< /form >
The Routes: Route::resource('users/profile', 'ProfileController');
Route::get('/home', 'HomeController#index')->name('home');
Route::resource('users', 'UserController'); Route::post('users/profile', 'ProfileController#store')->name('profile.store');
and the PUT method is used for updating. When update in controller you need to pass id in your form that should look like this.
< form method="POST" enctype="multipart/form-data" action="{{ url('users/profile', $data->id) }}" accept-charset="UTF-8" >
#method('PUT')
#csrf ...
// input fields here ...
< /form >
I hope it helps!
you have problem in your routes file simply change your edit route to this route
Route::match(['put', 'patch'], 'the path you want /{id}','controllername#functionname');
you should notice that if you are new to laravel you should pass the id to this route as shown in this part {id} so that your edit function could display the previous data of it and also if you want to submit a the form it should have the put method and the html basic forms doesn't support that so you should find a way to submit it like using laravel collective or maybe put a hidden method in your form
if it doesn't work please give me a call
When using the Laravel resource method on a route, it makes things pretty specific in terms of what it is expecting. If you take a look at the chart on the manual, it is looking for a uri with the updating element id returned as part of the uri. The example looks like: /photos/{photo}. I'm not sure that this is how you've structured your html form.
You said you were using the LaravelCollective to get this working. This usually works fine, and has the massive advantage of easy form-model binding. But it helps to include the named route, which includes 'update' for the update resource. For example:
{!! Form::model($yourModel, array('route' => array('yourRoute.update',
$yourModel->id), 'method'=>'PUT', 'id'=>'Form'))!!}
I have not had an issue with the Collective using this method.

custom validation, method not allowed on error

<form method="post" action="{{action('PLAYERController#update', $ply->reg_no)}}">
{{csrf_field()}}
Getting method not allowed exception on custom validation with false return. Tried mentioning PUT, PATCH and DELETE inside csrf field. Still, does not work.
UPDATE
using post for form method. Using method_field('POST'). not defining get method for the update function. If I go back from the error page back to the form page and press refresh, then the validation message is displayed as it should.
UPDATE 2
Validator::extend('check_sold_amount', function($attribute, $value, $parameters, $validator) {
if(($value%5000)==0)
{
return true;
}
return false;
});
}
UPDATE 3
Controller code
public function update(Request $request, $reg_no)
{
//
$this->validate($request, [
'sold_amount' => 'required|check_sold_amount',
'sold_to_team'=>'required'
]);
$ply = Player::find($reg_no);
$ply->sold_amount = $request->get('sold_amount');
$ply->sold_to_team = $request->get('sold_to_team');
$team_name=$ply->sold_to_team;
$team=Team::find($team_name);
if($ply->category=='indian')
{
$team->indian_players=$team->indian_players+1;
}
else {
$team->foreign_players=$team->foreign_players+1;
}
$team->balance=$team->balance-$ply->sold_amount;
$ply->save();
$team->save();
//return view('player.index');
}
Method not allowed means you do not have a route set up for the request that happened. There are 2 possibilities:
The route for the form submission is not set up
The code you have shown us does not include any method_field(...), so it looks like you are doing a normal POST. So you need a corresponding POST route like:
Route::post('/some/path', 'PLAYERController#update');
The route for the failed validation response is not set up
I'm guessing this is the problem. Say you are on pageX, and you landed here via a POST. You have a post route set up, so that you can land on this page OK. Now from this page, you submit the form you have shown us, but validation fails. When that happens, Laravel does a GET redirect back to pageX. But you have no GET route set up for pageX, so you'll get a Method not allowed.
Along with your POST route for the current page, you need a GET route to handle failed validations.
Also, you say Tried mentioning PUT, PATCH and DELETE inside csrf field - as others pointed out, you should use method_field() to spoof form methods, eg:
<form ...>
{{ csrf_field() }}
{{ method_field('PATCH') }}
Laravel form method spoofing docs
UPDATE
Based on your comments, I think it is actually your initial POST that is failing. Checking your code again, I think your action() syntax is incorrect.
According to the docs, if the method specified in the action() helper takes parameters, they must be specified as an array:
action="{{ action('PLAYERController#update', ['reg_no' => $ply->reg_no]) }}"
If your update route using patch method (example Route::patch('.....');) then add this {{ method_field('PATCH') }} below {{csrf_field()}} in your update form
UPDATE
If you are not using PATCH method for the update route, try this :
Route::patch('player/update/{reg_no}', 'PLAYERController#update')->name('plyupdate');
and then in the form you can do like below :
<form method="POST" action="{{route('plyupdate', $ply->reg_no)}}">
{{csrf_field()}}
{{ method_field('PATCH') }}
//Necessary input fields and the submit button here
</form>
This way always works fine for me. If it still didn't work, maybe there's something wrong in your update method in the controller
UPDATE
Untested, in your update method try this :
public function update(Request $request, $reg_no) {
$input = $request->all();
$ply = Player::find($reg_no);
$validate = Validator::make($input, [
'sold_amount' => 'required|check_sold_amount',
'sold_to_team'=>'required'
]);
if ($validate->fails()) {
return back()->withErrors($validate)->withInput();
}
$ply->sold_amount = $request->get('sold_amount');
$ply->sold_to_team = $request->get('sold_to_team');
$team_name=$ply->sold_to_team;
$team=Team::find($team_name);
if($ply->category=='indian') {
$team->indian_players=$team->indian_players+1;
}
else {
$team->foreign_players=$team->foreign_players+1;
}
$team->balance=$team->balance-$ply->sold_amount;
$ply->save();
$team->save();
return view('player.index');
}
Don't to forget to add use Validator; namespace
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show the profile for the given user.
........................
Did you reference a validation request controller?
Hope this helps :)

ajax method return view code instead redirect on view in laravel

I have many buttons in single form that's why i used ajax to call different method on different button click event. But while I call method using ajax and return view, it send code of view as response, And i need to redirect on that view my method code is as below.
public function store(Request $request)
{
return view('surat.proceed_sell');
}
can i redirect on other view using ajax? Or any other way to call different methods on different button click event then please let me know.
What you could do is return the url where to redirect as a response in your controller as
return url('the path');
and in your ajax success callback you could redirect to the view as
window.location = data;
The url should be defined in your route file where the view is rendered.
You cannot redirect to a view with Ajax because Ajax expects a response. What you should do is redirect to a page instead, using anchors.
First, define your routes
Route::get('surat/proceed', 'SuratController#proceed');
Then use anchor with a button to go that page. It doesn't matter how many buttons you have in the form, as longs as they are not of type submit, they should not submit the form.
<form method="post" action="">
Go to proceed
<button type="submit" class="btn btn-primary">Submit</button>
</form>
If this does not help you, please, update your question with your form code.

Resources