I am currently learning Laravel and finding it really useful and interesting.
At the moment I am making a simple online application form.
What are the biggest advantages to doing things using the Laravel syntax like:
{{ Form::open(array('url' => 'foo/bar')) }}
As opposed to simply:
<form action="foo/bar">
Or:
echo Form::text('username');
Instead of:
<input type="text" name="username" />
The Laravel way must be better, I just wish to know why exactly?
Using built-in HTML helpers have many benefits:
Using Form::open you add CSRF protection input hidden (by default)
Using form elements (inputs/textarea etc.) and withInput method for Redirection allows you to easily fill in the form with the same data with almost no coding
If you use Redirect::route('form'->withInput(); and have input
text {{Form::text('username')}} it will automatically set input's value the old data - you don't need to code it yourself checking it
Also if you want to match fields with labels its much easier:
{{ Form::label('username', 'Enter username') }}
{{ Form::text('username') }}
it will generate the following code:
<label for="username">Enter username</label>
<input name="username" type="text" id="username">
so as you see id will be created automatically
Probably there are some more. However the main disadvantage is that you need to learn and it's not portable in case you want to move your site to other Framework but each solution has pros and cons.
There are so many advantages of using Laravel's Form component but one useful advantage is that, when you just use this:
{{ Form::open(array('url' => 'foo/bar')) }}
{{ Form::close() }}
It automatically appends a hidden _token field which is useful for CSRF protection. otherwise you have to manually create the _token field using echo Form::token() or other way maybe. Also, when you use RESTful routes then Laravel's Form component appends the corresponding hidden _method field as well. Following note is taken from Laravel website:
Note: Since HTML forms only support POST and GET, PUT and DELETE
methods will be spoofed by automatically adding a _method hidden field
to your form.
There are also other advantages like Form Model Binding, generating form elements (specially select) easily and many more. Read more about Form on documentation.
BTW, the Redirect::back()->withInput() doesn't deppend only on use of Form component, if you use something like this, for example:
<input type='text' name='username' value='<?php echo Input::old('username') ?>' />
This will still work, the field will be repopulated on redirect back with inputs.
Related
I'm learning Laravel. The current stable version is, as far as I'm aware, 5.8. I'm following tutorials and really liking the framework, but it gets a bit troublesome when these tutorials get to the point where they introduce how forms are incorporated. All of those tutorials use LaravelCollective forms, which is no longer working as of 5.8 and it is an abandoned project so I'd prefer not to use it anyway.
But this leaves me confused as to what the best practices are for using forms with Laravel. I've had some goes at creating forms, but... most of it is just HTML with hardly any Laravel "in there", if that makes sense. The only Laravel bit here is the form action, where it points to the store function in the TodosController. See below, for a file called create.blade.php.
#extends('layouts.app')
#section('content')
<h1>Create Todo</h1>
<form action="{{action('TodosController#store')}}" method="post">
#csrf
<div class="form-group">
<label for="text">Text</label>
<input type="text" name="text" class="form-control" placeholder="Enter title"/>
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea class="form-control" name="body" id="body" rows="10" placeholder="Enter details"></textarea>
</div>
<div class="form-group">
<label for="due">Due date</label>
<input type="text" name="due" class="form-control" placeholder="Enter due date"/>
</div>
<input type="submit" value="Submit" class="btn btn-primary">
</form>
#endsection
This works fine, but I just feel like I'm not utilising blade properly here at all. Any pointers would be greatly appreciated.
Actually, you're using more laravel there than just the form action. The #csrf stands for Cross-site request forgery and it's the laravel way to protect you against that, as said in the docs:
Laravel automatically generates a CSRF "token" for each active user session managed by the application. This token is used to verify that the authenticated user is the one actually making the requests to the application.
Anytime you define a HTML form in your application, you should include a hidden CSRF token field in the form so that the CSRF protection middleware can validate the request. You may use the #csrf Blade directive to generate the token field:
When you have a PUT, PATCH OR DELETE form you should use the blade directive #method to inform wich action laravel should use:
HTML forms do not support PUT, PATCH or DELETE actions. So, when defining PUT, PATCH or DELETE routes that are called from an HTML form, you will need to add a hidden _method field to the form. The value sent with the _method field will be used as the HTTP request method:
You can achieve that, simply using:
<form action="/foo/bar" method="POST">
#method('PUT')
#csrf
</form>
Besides that, i think you're using laravel/blade just fine. Make sure you read the docs for more info.
Good luck!
What you have is a good point to start from, however another good place to take a look at is the boilerplate registration form (this is not from the official Laravel project page because the boilerplates are optionally introduced and are not in the official repo by default).
There are a few improvements you can do based on this:
<div class="form-group">
<label for="text">{{__('Text')}}</label>
<input type="text" name="text" class="form-control{{ $errors->has('text') ? ' is-invalid' : '' }}" value="{{ old('text') }}"placeholder="Enter title"/>
</div>
The extras:
__('Text') will automatically translate Text based on the selected locale and available language assets.
{{ $errors->has('text') ? ' is-invalid' : '' }} will "decorate" the field with the bootstrap-4 error style if serverside validation failed (and therefore passed the $errors variable to the view)
{{ old('text') }} will pre-fill the input with the value that was previously filled in case the form failed validation and the user was redirected back to the same page.
This will help improve the user experience, however keep in mind these are all server-side tools (because Laravel is a server-side framework) so it's probably a better user experience to also add client-side checks and validation.
I'm currently trying out http://altorouter.com/ and it's working well for me so far, except for this one issue I'm having
My route is set up like this:
$router->map( 'PATCH', '/admin/pages', 'pageController#update');
If I use the following jquery, the route works perfectly:
$.ajax({
type: "PATCH",
url: "/admin/pages",
data: {page_items:page_items, page_name: 'test_page'},
success: function(returned_data)
{
console.log(returned_data);
}
});
However, no matter what I put in my HTML I can't get a regular form to submit in a way it accepts as PATCH:
<form action="/admin/pages" method="post">
<input type="hidden" name="form_function" value="edit_theme">
<input type="hidden" name="_METHOD" value="PATCH">
<button type="submit">Save Page</button>
</button>
I've tried "_METHOD", "_method", "method" etc. None of them work.
I've also tried
method="PATCH"
but that only causes it to do a GET.
When I echo the $_SERVER['REQUEST_METHOD'] on the target page I get "PATCH" for the ajax, but just "POST" for the form. Hope someone can help.
In short, you cannot.
As you'll see in the W3 Spec
The only valid methods for HTML based forms are "GET" and "POST".
However you can work around this if you wish, on the server side instead. Theres a great article about how Laravel does it here: Theres no Put/Patch Delete Methods
A quick snippet of code from that article:
<form method="POST" action="" accept-charset="UTF-8">
<input name="_method" type="hidden" value="PUT">
</form>
<form method="POST" action="" accept-charset="UTF-8">
<input name="_method" type="hidden" value="PUT">
</form>
If you are not using Laravel and want to build a form manually, you cannot use PUT/PATCH – there’s just no such methods supported by forms in browsers – it’s only GET and POST. So how does Laravel make it work with {{ Form::create([‘method’ => ‘PUT’]) }}?
Actually, under the hood the generated HTML looks like this:
That’s right, Laravel constructs a hidden field with name _method and
then checks it upon form submittion, routing it to the correct
Controller method.
So if for any reason you would need to build the FORM tag yourself,
don’t put (same applied to patch and delete) – it
just won’t work. Instead add hidden fields, if necessary.
So back to your issue, Altorouter. It appears their documentation is rather lacing the best guide I can find for you is here https://recalll.co/app/?q=rest%20-%20PHP%20detecting%20request%20type%20(GET%2C%20POST%2C%20PUT%20or%20DELETE)%20-%20Stack%20Overflow it might be worth your while finding a better router, as Alto doesn't seem to have been updated in around 3 years.
Managed to find a working solution after digging around in the code. Altorouter's match method actually accepts a method parameter, which doesn't seem to be documented anywhere.
Where I used to have
$match = $router->match();
I now have:
if(isset($_POST['_method']))
{
$match = $router->match(null, $_POST['_method']);
}
else
{
$match = $router->match();
}
As I am new to laravel framework, I have a query, I am using <form> tag in blade template so that I can delete the data from table.
I am using this the below code of form tag to delete the data
<form action="{{ route('admin.states.update',$data->state_id) }}" id="form_sample_2" class="form-horizontal" novalidate="novalidate" method="PUT">
Here I have used method as PUT, but browser is automatically considering it as GET request, I found some questions on stackoverflow where many of them said PUT & DELETE is not detected by browser.
So using Laravel Facade Form , this problem is solved
{!! Form::open(array('route'=>['admin.states.update',$data->state_id],'role'=>'form','method'=>'PUT')) !!}
The above code work as intended but my query is I don't want to use Formfacade in Laravel , I want to use first type of HTML code for form opening.
Is there any other method by which I can use PUT method in HTML Form Tag without using any Form FAcade in Laravel.
set form method to post and add a hidden input as following
<input type="hidden" name="_method" value="put">
and also make sure to add
<input type="hidden" name="_token" value="{{ csrf_token() }}">
If your ValidateCSRF middleware is enabled.
I just got into Symfony2 as an ASP.NET programmer. I have this very simple form that I want to put in. Since it only contains a label and an input, I figured I didn't want to make a separate form class for it. But as soon as I tried to preform that, I ran into some trouble:
<form action="{{ path('search', [{'src':'bla'}]) }}" method="get">
<label for="src"></label>
<input type="text" name="src" id="src" class="form-control search-input" placeholder="Type a group or song name: ie. Metallica, Fly me to the moon etc.">
</form>
How do I set the path to mydomain.com/search/{src}, I'm trying to at least build a path for now, so I'm using 'bla' as some placeholder valye. Right now from the code above, I receive the following error upon loading the page that contains the form:
An exception has been thrown during the rendering of a template ("Some mandatory parameters are missing ("src") to generate a URL for route "search".") in :home:index.html.twig
Some methods I also tried:
path('search', 'bla') <-- and --> path('search', 'bla', [])
brings error:
An exception has been thrown during the rendering of a template ("Warning: array_replace(): Argument #3 is not an array") in :home:index.html.twig
path('search', ['src':'bla'])
and some more (probably) nonsense that didn't get me close to the result.
Is this even doable, or do I have to do it the 'normal' way with {{ form_start() }} and form classes?
Don't try, just read documentation, it's more effective and faster :)
http://symfony.com/doc/current/book/templating.html#book-templating-pages
{{ path('search', {'src':'bla'}) }}
In Laravel 5, I notice that whenever I have a form in which I wrote in plain HTML, instead of using the Form::open, it is required to have a hidden input field for the token.
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>" />
And for a form that updates a record, it is required to have <input name="_method" type="hidden" value="PATCH">
Is it correct that I should always have these fields when writing forms using plain HTML? Is there other ways of doing this if I were still to write it in plain HTML?
Yes that's correct. For PATCH (and basically all non GET or POST verbs) there's no other way than using the _method.
This is described in the route chapter of the documentation: Method Spoofing
However you could disable CSRF protection. I'm not saying you should do that but if you wanted to, you can disable it by removing Illuminate\Foundation\Http\Middleware\VerifyCsrfToken from the middleware array in app/Http/Kernel.php
This is in the documentation as well: CSRF Protection