I'm trying to create a form that passes data via get to the controller but the URL looks allways like this:
http://example.com/test?_token=VinwWFxKIhKvMqrrEBN5xwXhrmYQjLnOWV8s7dht¶m1=horse¶m2=cat¶m3=dog
But I want something like this:
http://example.com/test/param1=horse/param2=cat/param3=dog
or
http://example.com/test/horse/cat/dog
Route:
Route::get('test/{param1}/{param2}/{param3}', ['as' => 'test', 'uses' => 'MainController#test']);
HTML:
<form action="{{ route('test') }}" method="get">
{{ csrf_field() }}
<div class="col-md-3">
<div class="form-group">
<label for="animal1">animal1</label>
<br>
<input type="text" name="animal1" class="form-control">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="animal2">animal2</label>
<input type="text" name="animal2" class="form-control">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="animal3>animal3</label>
<input type="text" name="animal3" class="form-control">
</div>
</div>
<div class="col-md-12">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
The problem is that the test route is reloaded every 10 seconds. Therefore, the form values must be in the URL so that I can process them correctly in the controller.
I've found this question here but that wasn't so helpful
How To Pass GET Parameters To Laravel From With GET Method ?
Thanks for your help!
To do this, you'll need to switch off CSRF token check, which is a bad idea. Or you could use JS to build the query which is not a good idea too.
The best way to handle this is to use POST instead of GET:
<form action="{{ route('test') }}" method="post">
And then change the route to:
Route::post('test', ['as' => 'test', 'uses' => 'MainController#test']);
You can do this via javascript.
You don't need to use form like this.you can just get input values by id(getElementById) and on a button click, format them as you expect (test/{param1}/{param2}/{param3}) and redirect page to that.
Related
I have a blog post that I want to edit in its own view, yet when I put the edits to change, I get a 419 page.
This is my edit view to edit the blog in question specified by its id :
<div id="body" style="color:#333">
<h1 style="color:#333">Update blog</h1>
<form method="POST" action="{{route('blogSingle',$blog->id)}}">
#method('put')
#csrf
<div class="field">
<label for="title" class="label" style='font-size:1.2rem'>Title</label>
<div class="control">
<input type="text" class="input" name="title" id="title" placeholder="Blog Title" value="{{$blog->title}}">
</div>
</div>
<div class="field">
<label for="body" class="label" style='font-size:1.2rem'>Body</label>
<div class="control">
<textarea type="text" class="textarea" name="body" id="body" placeholder="Blog Description">{{$blog->body}}</textarea>
</div>
</div>
<div class="field is-grouped">
<div class="control">
<button type="submit" class="btn btn-secondary">Submit</button>
</div>
</div>
</form>
</div>
I've also a view for every single blog, and in it, I click on a button to redirect to a blog edit view like so :
<div id="body">
{{-- Add a variable blog post here --}}
<h1><span>blog single post</span> <span>Edit Blog</span></h1>
<div>
<img src="images/grew-a-mustache.jpg" alt="Mustache">
<div class="article">
<h2 class="lead">{{$blog->title}}</h2>
<p class="lead">
{{$blog->body}}
</p>
</div>
</div>
</div>
My routes involved are as the following :
Route::get('blog-single/{blog}',[BlogController::class,'show'])->name('blogSingle');
Route::get('blog-single/{blog}/edit', [BlogController::class, 'edit'])->name('blog-edit');
Route::put('blog-single/{blog}',[BlogController::class, 'update']);
Why am I still getting a 419 page expired? I even inspected the page before send and I see my token clearly right here :
A 419 is only thrown when the VerifyCsrfToken middleware fails to validate your token. Having #csrf is not a guarantee that your token won't fail. Reasons your token might fail:
Your session has a different token; check the result of session()->token() and see if it matches with the token in the #csrf field. If it does not, try session()->flush() and re-authenticate if you have to.
You have another form input with _token as name after the #csrf which overwrites the CSRF
You have middleware manipulating the token
You have messed with the vendor file, and so the tokensMatch function isn't functioning as it should (If you think you have done this, you can delete your vendor folder, then run composer clearcache and composer install)
I would like to add, you're not routing to your update method:
<form method="POST" action="{{route('blogSingle',$blog->id)}}">
is calling the show method:
Route::get('blog-single/{blog}', [BlogController::class,'show'])->name('blogSingle');
This does work, since you're specifying the method and the URL is the same, but this is not good practice. It'd be better if you explicitly call the update route (which you haven't even given a name yet). It's also better practice to use the placeholder names instead of letting the route fill the placeholders in order:
Route::put('blog-single/{blog}',[BlogController::class, 'update'])->name('blog-update');
<form method="POST" action="{{route('blog-update', ['blog' => $blog])}}">
You can also use compact to quickly bind the blog to the placeholder.
I have installed the latest laravel. I Have made this simple form. I want to create post but when I submit it goes to localhost/post which is the wrong URL . The actual URL is http://localhost/laravel_practice/'
Form
<form method="post" action="/post">
<div class="form-group">
<label>Title</label>
<input type="text" name="title" class="form-control" placeholder="Enter Title Here">
</div>
<div class="form-group">
<label>Body</label>
<textarea name="body" class="form-control" placeholder="Enter the body"></textarea>
</div>
<div class="form-group">
<input type="submit" name="sumit" class="btn btn-primary" value="Publish">
</div>
My Routes
Route::get('/' ,'PostController#index');
Route::get('/posts/create', 'PostController#create');
Route::post('/post','PostController#store');
Your short fix is to use action="/laravel_practice/post" or action="/laravel_practice/public/post" depending on what url you want to go.
However, it is a bad practice. You should use route name. To do that give any name to the route like below,
Route::post('/post','PostController#store')->name('post.store');
Then in view you should use,
<form method="post" action="{{ route('post.store') }}">
To read more about named route you can go through this document.
How do I make custom method to get form data? I want this method same with Laravel update method with parameters request and id. I try this but get error.
In controller
public function updatePassword(Request $request, int $id) {
dd($request->all());
}
In route
Route::post('staffs/{id}/upassword', 'Admin\StaffController#updatePassword')->name('admin.staffs.upassword');
In blade file
<form method="post" accept-charset="utf-8" action="{{ action('Admin\StaffController#updatePassword', ['id' => $staff_id]) }}">
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label class="control-label" for="password">New Password</label>
<input class="form-control" name="password" type="password">
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label class="control-label" for="password_confirmation">Confirm New Password</label>
<input class="form-control" name="password_confirmation" type="password">
</div>
</div>
</div>
<input class="btn btn-primary" type="submit">
</form>
I am using Laravel 5.4.
here are some stuff to fix:
First in the tag you can set the action to :
action="route('admin.staffs.upassword', $staff_id)" since it's
easier to write and since you already gave the route a name, so why
not using it ;)
Second add {{csrf_field() }} right before your form closing tag
</form>
what error are you getting? the error is probably because you are not using {{csrf_field()}} after the form declaration, it is needed so that laravel can validate the request. if you want to get the data from the form you can use:
$request->get('inputname');
I'm trying to setup phpunit tests for a project with Laravel 5.1.40 (LTS), php 5.6.28, and phpunit 4.8.27. I'm sorry if this issue has been solved before, but I couldn't find anything.
public function testAdminLogin()
{
$this->visit('/auth/login')
->type('email#address.com', 'email')
->type('1234567890', 'password')
->press('Login');
}
There seem to be an issue with press('STRING') with both <button> and <input> as submit buttons. Below is the error message I receive.
1) ExampleTest::testAdminLogin
A request to [http://localhost/auth/login] failed. Received status code [500].
C:\xampp\htdocs\project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\InteractsWithPages.php:165
C:\xampp\htdocs\project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\InteractsWithPages.php:63
C:\xampp\htdocs\project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\InteractsWithPages.php:85
C:\xampp\htdocs\project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\InteractsWithPages.php:684
C:\xampp\htdocs\project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\InteractsWithPages.php:671
C:\xampp\htdocs\project\tests\ExampleTest.php:52
C:\xampp\php\pear\PHPUnit\TextUI\Command.php:176
C:\xampp\php\pear\PHPUnit\TextUI\Command.php:129
However, when I change the <button> tag to an <a> tag, add an id to it, and replace the press(STRING) function with the click(ID) function, the test passes. I could change the <button> to an <a>, but that would only a temporary fix, and future cases might not allow the tag change.
Below is the HTML form with the <button> tag.
<form action="/auth/login" method="POST" class="form-horizontal">
<div class="form-group">
<label for="email" class="col-sm-4 control-label">E-Mail</label>
<div class="col-sm-6">
<input type="email" name="email" class="form-control" value="{{ old('email') }}" autocomplete="off">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-4 control-label">Password</label>
<div class="col-sm-6">
<input type="password" name="password" class="form-control" autocomplete="off">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-6">
<button type="submit" class="btn btn-default btn-login">Login</button>
</div>
</div>
</form>
You said you define auth routes manually. In this case you should have POST route for sending login form:
Route::post('auth/login', ....
It works in a href because it sends GET request for which you have route. Form sends POST request by default.
I have seen this post, however I don't believe it is relevant to my issue because I believe I am correctly passing post data through a post route.
Here is the relevant route code:
Route::get('/pass', 'PageController#pass');
Route::post('/pass/{request}',['uses' => 'PageController#passController']);
I would like to have one controller method for the 'pass' page, but to isolate the issue I have separated them.
Here are the relevant methods in PageController.php:
public function pass(){
return view('pass')->with(array(
'title'=>'Create A Pass'
));
}
public function passRequest($request){
$data['request'] = $request;
$validator = Validator::make($request->all(), [
'studentID' => 'required|max:255',
'teacherID' => 'required|max:255',
'destination' => 'required|max:255',
]);
if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}
$pass = new Pass;
$pass->student = DB::table('users')->where('studentID', $request->studentID)->first()->id;
$pass->teacher = DB::table('users')->where('teacherID', $request->teacherID)->first()->id;
$pass->destination = $request->destination;
$pass->save();
return view('home')->with(array(
'title'=>'Home',
'success'=>'null'
));
}
I used the method stated here in order to pass data to the controller. If this is bad practice/obsolete I'm open to any suggestions.
This is the form in the 'pass' page responsible for sending the post data
<form action="{{ url('pass') }}" method="POST" class="form-horizontal">
{!! csrf_field() !!}
<fieldset>
<!-- Text input-->
<div class="container">
<div class="form-group">
<label class="col-md-4 control-label" for="studentID">Student ID</label>
<div class="col-md-3">
<input id="studentID" name="studentID" type="text" class="form-control input-md">
</div>
</div>
</div>
<!-- Text input-->
<div class="container">
<div class="form-group">
<label class="col-md-4 control-label" for="teacherID">Teacher ID</label>
<div class="col-md-3">
<input id="teacherID" name="teacherID" type="text" class="form-control input-md">
</div>
</div>
</div>
<!-- Text input-->
<div class="container">
<div class="form-group">
<label class="col-md-4 control-label" for="destination">Destination</label>
<div class="col-md-3">
<input id="destination" name="destination" type="text" class="form-control input-md">
</div>
</div>
</div>
<div class="container">
<div class="form-group">
<div class="col-sm-offset-4 col-sm-6">
<button type="submit" class="btn btn-default">
<i class="fa fa-check"></i> Create Pass
</button>
</div>
</div>
</div>
</fieldset>
</form>
On submission of this form I get the MethodNotAllowedHttpException Exception.
If a stack trace of the error would be helpful, please let me know. If there are any suggestions on style, I'm open to that as well.
This form tag will generate a POST request to the URL /pass:
<form action="{{ url('pass') }}" method="POST" class="form-horizontal">
Your routes file does not allow that. It only allows GET requests to that url, but POST requests to /pass/{request}.
Not sure if its just a copy/paste mistake, but your POST route is set up to call PageController#passController method, but the method you shared from your controller is named passRequest. Those will need to match also.
In addition to what Jeff Lambert pointed out, you should not put the {request} variable in the route.
You should remove that and have laravel inject the Request object for you.
Import the Request class if you haven't already at the top of the class.
use Illuminate\Http\Request;
And your function should look like the following...
public function passRequest(Request $request)
{
...
}
If you have additional parameters to pass through the URL, then you may add them to the route, and add the arguments to the method after Request $request. Laravel will figure out what to do with it.
try this one...
Route::post('/pass/post','PageController#passController')->name('post_insert');
in your html form change to ...
<form action="{{ route('post_insert') }}" method="POST" class="form-horizontal">
change it also ...
public function passRequest(Illuminate\Http\Request $request){
....