0

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.

3
  • 2
    You could extract form inputs to blade components and such, but to be fair, that's more work than it is to do it like this with a decent IDE. This looks perfectly fine to me Commented Feb 28, 2019 at 14:52
  • 1
    That's what I was thinking as well. It's at least reassuring that I'm not doing this in some completely unintended way, thank you. Commented Feb 28, 2019 at 14:57
  • Correct me if I'm wrong but won't this not function since it's a string? action="{{action('TodosController@store')}}". shouldn't it be with out the quotations? Commented Apr 12, 2019 at 22:34

2 Answers 2

5

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!

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.