I am setting up a simple form in laravel:
This is the route file:
Route::get('backoffice/upload', [ 'as' => 'backoffice/upload',
'uses' => 'UploadController#uploadForm']);
Route::post('backoffice/saveimage',[ 'as' => 'backoffice/saveimage',
'uses' => 'UploadController#saveImage']);
This is the controller:
class UploadController extends \BaseController
{
public function uploadForm()
{
return View::make("backoffice.upload.create");
}
public function saveImage()
{
return "Uploading...";
}
}
And this is the View file:
<h1>Upload Image</h1>
{{ Form::open(['action' => 'UploadController#saveImage']) }}
<div class='formfield'>
{{ Form::label('newfilename','New File Name (optional):') }}
{{ Form::input('text','newfilename') }}
{{ $errors->first('newfilename') }}
</div>
<div class='formfield'>
{{ Form::submit($action,['class'=>'button']) }}
{{ Form::btnLink('Cancel',URL::previous(),['class'=>'button']) }}
</div>
{{ Form::close() }}
// Generated HTML
<h1>Upload Image</h1>
<form method="POST" action="http://my.local/backoffice/saveimage" accept-charset="UTF-8"><input name="_token" type="hidden" value="x9g4SW2R7t9kia2B8HRJTm1jbLRl3BB8sPMwvgAM">
<div class='formfield'>
<label for="newfilename">New File Name (optional):</label>
<input name="newfilename" type="text" id="newfilename">
</div>
<div class='formfield'>
<input class="button" type="submit" value="Create">
</div>
</form>
So, if I go to: http://my.local/backoffice/upload I get the form with the HTML above.
However, if I type anything, then click SUBMIT, I return to the form but now have the following URL:
http://my.local/backoffice/upload?pz_session=x9g4SW2R7t9kia2B8HRJTm1jbLRl3BB8sPMwvgAM&_token=x9g4SW2R7t9kia2B8HRJTm1jbLRl3BB8sPMwvgAM&newfilename=ddd
This makes no sense to me. Up until now I have always used route::resource when dealing with forms, and had no problem. I am trying to do a simple form with GET and POST and am having no end of grief. What am I missing?
Furthermore, if I modify routes.php and change it from post to any, then open a browser window and type: http://my.local/backoffice/saveimage then I get the message "Uploading..." so that part is working ok.
Found the solution. In making the backoffice of the system, I had re-used the frontoffice template but removed all the excess. Or so I had thought. However, the front office header template had a form which I had only partially deleted.
So the problem was that there was an opening FORM tag I didn't know about. Consequently, when I clicked on submit to my form, it was actually submitting to this other form.
As the other form had no action it was default to itself.
Of course, had I just validated the HTML this would have shown up straight away. The lesson learned here is to validate my html before submitting questions!
Try this, and be sure to correctly configure your url at app/config/app.php
{{Form::open(['url'=>'backoffice/saveimage'])}}
//code
{{Form::close()}}
Related
In a Laravel context, I've got this messages page, with all the messages belonging to a specific user. Initially all messages are not readed, so I put a button to change the boolean in DB (from 0 to 1) and finally show the message.
I'm doing this:
The view
#if ($message->readed != 0)
<p class="card-text message text-left">{{ $message->message }}</p>
#else
<form method="POST" action="/message/read">
#csrf
#method('PATCH')
<input type="hidden" name="message" value="{{ $message->id }}"/>
<button class="btn btn-info text-white" type="submit">
Leggi
</button>
</form>
#endif
The route in web.php
Route::patch('message/read', 'MusicianController#readMessage');
The function
public function readMessage(Request $request)
{
$message = Message::where('id', $request->id)->first();
$message->readed = 1;
$message->update();
return redirect()->back()->with('message', 'message updated');
}
But it's not working, as soon as I click the button to show the message (and even change the DB value) I've got this error: The PATCH method is not supported for this route. Supported methods: GET, HEAD.
Even if I had specified a patch method in routes and even in the form with #method('PATCH')
Could someone help me understand what's wrong please??
the main answer
your route is:
Route::patch('message/read', 'MusicianController#readMessage');
replace your route with following route that use for all CRUD opration:
Route::resource('message/read', 'MusicianController');
if you use ajax for submit data then replace your type and url with following:
type: "patch",
url: "{{url('message/read')}}",
if you don't use ajax than use following:
<form method="POST" action="{{url('message/read"')}}">
{{csrf_field()}}
{{ method_field('PATCH') }}
</form>
update: after version 5.6 you can use these syntax for above functions in any blade file:
<form method="POST" action="{{url('message/read"')}}">
#csrf
#method('PATCH')
</form>
I'm trying to create a new "Airborne" test in my program and getting a 405 MethodNotAllowed Exception.
Routes
Route::post('/testing/{id}/airbornes/create', [
'uses' => 'AirborneController#create'
]);
Controller
public function create(Request $request, $id)
{
$airborne = new Airborne;
$newairborne = $airborne->newAirborne($request, $id);
return redirect('/testing/' . $id . '/airbornes/' . $newairborne)->with(['id' => $id, 'airborneid' => $newairborne]);
}
View
<form class="sisform" role="form" method="POST" href="{{ URL::to('AirborneController#create', $id) }}">
{{ csrf_field() }}
{!! Form::token(); !!}
<button type="submit" name="submit" value="submit" class="btn btn-success">
<i class="fas fa-plus fa-sm"></i> Create
</button>
</form>
According to my knowledge forms don't have a href attribute. I think you suppose to write Action but wrote href.
Please specify action attribute in the form that you are trying to submit.
<form method="<POST or GET>" action="<to which URL you want to submit the form>">
in your case its
<form method="POST" ></form>
And action attribute is missing. If action attribute is missing or set to ""(Empty String), the form submits to itself (the same URL).
For example, you have defined the route to display the form as
Route::get('/airbornes/show', [
'uses' => 'AirborneController#show'
'as' => 'airborne.show'
]);
and then you submit a form without action attribute. It will submit the form to same route on which it currently is and it will look for post method with the same route but you dont have a same route with a POST method. so you are getting MethodNotAllowed Exception.
Either define the same route with post method or explicitly specify your action attribute of HTML form tag.
Let's say you have a route defined as following to submit the form to
Route::post('/airbornes/create', [
'uses' => 'AirborneController#create'
'as' => 'airborne.create'
]);
So your form tag should be like
<form method="POST" action="{{ route('airborne.create') }}">
//your HTML here
</form>
MethodNotAllowedHttpException signposts that your route isn't available for the HTTP request method specified. Perhaps either because it isn’t defined correctly, or it has a conflict with another similarly named route.
Named Routes
Consider using named routes to allow for the convenient generation of URLs or redirects. They can generally be much easier to maintain.
Route::post('/airborne/create/testing/{id}', [
'as' => 'airborne.create',
'uses' => 'AirborneController#create'
]);
Laravel Collective
Use Laravel Collective's Form:open tag and remove Form::token()
{!! Form::open(['route' => ['airborne.create', $id], 'method' =>'post']) !!}
<button type="submit" name="submit" value="submit" class="btn btn-success">
<i class="fas fa-plus fa-sm"></i> Create
</button>
{!! Form::close() !!}
dd() Helper Function
The dd function dumps the given variables and ends execution of the script. Double-check your Airborne class is returning the object or id you expect.
dd($newairborne)
List available routes
Always make sure your defined routes, views, and actions match up.
php artisan route:list --sort name
First of All
Form don't have href attribute, it has "action"
<form class="sisform" role="form" method="POST" action="{{ URL::to('AirborneController#create', $id) }}">
Secondly
If the above change doesn't work, you can make some changes like:
1. Route
Give your route a name as:
Route::post('/testing/{id}/airbornes/create', [
'uses' => 'AirborneController#create',
'as' => 'airborne.create', // <---------------
]);
2. View
Give route name with route() method in form action rather than URL::to() method:
<form class="sisform" role="form" method="POST" action="{{ route('airborne.create', $id) }}">
I'm trying to update my database using a form on my
edit.blade.php page as shown below. The edit part works correctly as the fields are filled in in the form as expected, however when i try to save, an error message of
Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException
No message
is displayed. I have tried so many ways on how to fix it and I'm not sure where I'm going wrong. Hopefully it's something simple to fix?
edit.blade.php
#extends('layouts.app')
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<form method="post" action="{{ action('PostsController#update', $id) }}">
{{ csrf_field() }}
<input type="hidden" name="_method" value="PATCH" />
<h1>Edit Item</h1>
<div class="form-group">
<label for="item">Item:</label>
<input type="text" id="item" name="item" value="{{$post->item}}" class="form-control" required>
</div>
<div class="form-group">
<label for="weight">Weight (g):</label>
<input type="number" id="weight" value="{{$post->weight}}" name="weight" class="form-control">
</div>
<div class="form-group">
<label for="noofservings">No of Servings:</label>
<input type="number" id="noofservings" value="{{$post->noofservings}}" name="noofservings" class="form-control">
</div>
<div class="form-group">
<label for="calories">Calories (kcal):</label>
<input type="number" id="calories" name="calories" value="{{$post->calories}}" class="form-control">
</div>
<div class="form-group">
<label for="fat">Fat (g):</label>
<input type="number" id="fat" name="fat" value="{{$post->fat}}" class="form-control">
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
</div>
</div>
</div>
#endsection
PostsController.php
<?php
public function update(Request $request, $id)
{
$this->validate('$request', [
'item' => 'required'
]);
$post = Post::find($id);
$post->item = $request->input('item');
$post->weight = $request->input('weight');
$post->noofservings = $request->input('noofservings');
$post->calories = $request->input('calories');
$post->fat = $request->input('fat');
$post->save();
return redirect('/foodlog');
}
web.php
<?php
Route::get('edit/{id}', 'PostsController#edit');
Route::put('/edit', 'PostsController#update');
Post.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $fillable = [
'id',
'user_id',
'item',
'weight',
'noofservings',
'calories',
'fat',
'created_at'
];
}
My website is a food log application and this function is so that they can edit their log.
Any help is greatly appreciated!
Based on Michael Czechowski I edited my answer to make this answer better, The main problem is inside your routes:
Route::put('/edit/{id}', 'PostsController#update');
You have to add the id inside your route parameters either. Your update() function needs two parameters, first the form parameters from the formular and second the $id of the edited log entry.
The second problem is , the form method field is 'patch' and your route method is 'put'.
The difference between 'patch' and 'put' is:
put: gets the data and update the row and makes a new row in the database from the data that you want to update.
patch: just updates the row and it does not make a new row.
so if you want to just update the old row change the route method to patch.
or if you really want to put the data, just change the put method field in your form.
simply by : {{method_field('PUT')}}
Remember, the form's and the route's methods must be same. If the form's method is put, the route method must be put; and vice-versa.
The main problem is inside your routes:
Route::put('/edit/{id}', 'PostsController#update');
You have to add the id inside your route parameters either. Your update() function needs two parameters, first the form parameters from the formular and second the $id of the edited log entry.
The second one is inside your HTML template:
<input type="hidden" name="_method" value="PUT" />
To hit the right route you have to add the corresponding method to your route Route::put('/edit/{id}', 'PostsController#update');.
A possible last problem
<form method="post" action="{{ action('PostsController#update', $post->id) }}">
I am not sure how your template works, but $id is possible not set inside your template. Maybe try to specify the ID depending on your post. Just to make it sure the ID comes from the shown post.
Further suggestions
Best practice is to use the symfony built-in FormBuilder. This would make it easier to target those special requests like PUT, PATCH, OPTIONS, DELETE etc.
I am learning Routing in Laravel 5.4 by viewing a tutorial created by DevDojo. Using the following codes in routes/web.php will emerge the TokenMismatchException error and my code does not work after I press the submit button:
Route::post('test', function () {
return 'Printed by the route responsible for test post action.';
});
Route::get('test', function () {
echo '<form method="post" action="test">';
echo '<input type="submit">';
echo '</form>';
});
I searched this same forum here and also the other places on the net like laravel.io or laracasts.com and everyone is talking about problems that occur when Laravel tries to detect the session of the request that is getting made.
I tried to fix the problem by adding the following lines to the Route::get rules but the issue does not get fixed:
echo '<input type="hidden" name="_method" value="post">';
echo '<input type="hidden" name="_token" value="csrf_field();">';
I hope you help me fix it by telling me how to properly use csrf_field(), csrf_token() or anything else needed here in the route file.
Thank you very much in advance.
csrf_token() just gives you the token.
csrf_field() builds the entire input field for you.
example:
{{ csrf_token() }} // Outputs: SomeRandomString
{{ csrf_field() }} // Outputs: <input type="hidden" name="_token" value="SomeRandomString">
in your question:
use
<input type="hidden" name="_token" value="csrf_token();">;
instead of
<input type="hidden" name="_token" value="csrf_field();">;
on the other hand
you could use
echo csrf_field();
OR
{{ csrf_field() }}
I think you're on the right track with the hidden inputs (if you've got a fresh Laravel install, otherwise make sure checking the token isn't disabled);
I recommend you use the (official) Form Builder for Laravel to handle forms (have a look here).
Afterwards, have a look here:
(1)
{{ Form::open(array('url' => 'profile')) }}
your form stuff goes here
{{ Form::close() }}
(2) Make sure to have this to output the token: echo Form::token(); (before you close the form)
(3) And finally, have a POST Route registered, that checks the token:
Route::post('profile', array('before' => 'csrf', function()
{
//
}));
Alternatively, you can specify form action directly to the function (my personal favorite):
echo Form::open(array('action' => 'Controller#method'))
I want to pass an input value from one blade file to another blade file.
I'm new to PHP Laravel, and I'm getting an error when attempting to use it.
I think my syntax is wrong here. Can somebody help?
channeling.blade:
<select class="form-control " name="fee" id ="fee"></select>
This is the link to the next page, where i want to send the value of "fee":
<input type="hidden" value="fee" name="fee" />
Click to Channel</p>
This is my web.php:
Route::post('pay', [
'as' => 'fee',
'uses' => 'channelController#displayForm'
]);
This my controller class:
public function displayForm()
{
$input = Input::get();
$fee = $input['fee'];
return view('pay', ['fee' => $fee]);
}
Error message:
Undefined variable: fee
(View: C:\xampp\htdocs\lara_test\resources\views\pay.blade.php)
pay.blade:
<h4>Your Channeling Fee Rs:"{{$fee}}"</h4>
You should use form to send post request, since a href will send get. So, remove the link and use form. If you use Laravel Collective, you can do this:
{!! Form::open(['url' => 'pay']) !!}
{!! Form::hidden('fee', 'fee') !!}
{!! Form::submit() !!}
{!! Form::close() !!}
You can value inside a controller or a view with request()->fee.
Or you can do this:
public function displayForm(Request $request)
{
return view('pay', ['fee' => $request->fee]);
}
I think you can try this, You mistaken url('pay ') with blank:
change your code:
Click to Channel</p>
to
Click to Channel</p>
Further your question require more correction so I think you need to review it first.
You can review about how to build a form with laravel 5.3. Hope this helps you.
You have to use form to post data and then you have to submit the form on click event
<form id="form" action="{{ url('pay') }}" method="POST" style="display: none;">
{{ csrf_field() }}
<input type="hidden" value="fee" name="fee" />
</form>
On the click event of <a>
<a href="{{ url('/pay') }}" onclick="event.preventDefault();
document.getElementById('form').submit();">
Logout
</a>
tl;dr: I believe #AlexeyMezenin's answer is the best help, so far.
Your current issues:
If you have decided to use Click to Channel, you should use Route::get(...). Use Route::post(...) for requests submitted by Forms.
There isn't an Input instance created. Input::get() needs a Form request to exist. Thus, the $fee an Undefined variable error message.
The value of <input type="hidden" value="fee" name="fee"/> is always going to be the string "fee". (Unless there's some magical spell casted by some JavaScript code).
The laravel docs suggest that you type-hint the Request class when accessing HTTP requests, so that the incoming request is automatically injected into your controller method. Now you can $request->fee. Awesome, right?
The way forward:
The BasicTaskList Laravel 5.2 tutorial kick-started my Laravel journey.
I changed the code like this and it worked..
echanneling.blade
<input type="hidden" value="fee" name="fee" />
<button type="submit" class="btn btn-submit">Submit</button>
channelController.php
public function about(Request $request)
{
$input = Input::get();
$fee = $input['fee'];
return view('pay')->with('fee',$fee);
}
Web.php
Route::post('/pay', 'channelController#about' );