Paulund
2017-08-30 #laravel

Create A Contact Form With VueJS And Laravel

In this tutorial we're going to learn how we can create a VueJS component for a contact form and create a Laravel API Endpoint that will send the message from the contact form.

VueJS Contact Component

First we're going to build our VueJS component, this goes into your resources/assets/js/components/ directory. The HTML for the contact form is very simple we just have a name, email, message and a submit button. You'll notice on the form tag we have a submit event to run the submitForm method v-on:submit.prevent="submitForm". The second thing you'll notice is that on each of the form elements we want to collect data on we have a v-model attribute. In the script section of our component we need to define the form element we want to collect data from in the data section of the component.


    data(){
        return{
            name:'',
            email:'',
            message:''
        }
    },

Above we said on the submit of form we call the submitForm method, this will collect the form data and send a post request to the route api/contact using axios which in turn will send an email on the back-end.


    methods: {
        submitForm(){
            let formData = {
                name:this.name,
                email:this.email,
                message:this.message,
            };

            return axios.post('/api/contact', formData).then(data => {
              // Change to notify the user
              console.log('Message sent');
            });
        }
    }

Below is the full contact form component. Name

export default{ data(){ return{ name:'', email:'', message:'' } }, methods: { submitForm(){ let formData = { name:this.name, email:this.email, message:this.message, };

        return axios.post('/api/contact', formData).then(data => {
          // Change to notify the user
          console.log('Message sent');
        });
    }
}

} ## Laravel API

We're going to use the Laravel backend in our application to send the email from the contact form. We need to create a new API endpoint open up the routes/app.php file and add the post endpoint for the contact form.


Route::post('contact', 'ContactController@store');

If you now look at your routes php artisan route:list you'll see this new post route for the contact controller. We can now create the ContactController inside the controllers folder app/Http/Controllers. The contact controller will need a store method and we'll use this to send the email, inside the store method we need to validate the request to make sure we've been sent the required information.


        $data = $this->validate($request, [
            'name' => 'required',
            'email' => 'required|email',
            'message' => 'required',
        ]);

If we know this request is correct then we send the email using a mailable class.


Mail::to( config('mail.from.address') )->send( new ContactEmail($request->only(['name', 'email', 'message'])) );

Then we can return a JSON that the email was sent.


return response()->json( ['sent' => true], Response::HTTP_OK);

Below is the full controller used for the contact. namespace App\Http\Controllers; use App\Mail\ContactEmail; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Support\Facades\Mail; class ContactController extends Controller { public function store( Request $request ) {


        $data = $this->validate($request, [
            'name' => 'required',
            'email' => 'required|email',
            'message' => 'required',
        ]);

Mail::to( config('mail.from.address') )->send( new ContactEmail($request->only(['name', 'email', 'message'])) ); return response()->json( ['sent' => true], Response::HTTP_OK); } } ## Create The Contact Mailable

Mailables are a great way of keeping the functionality for the email in a single place. To generate a new mailable class we can use the make artisan command.


php artisan make:mail ContactEmail

For this class we're going to accept the array of email data in the constructor and add this to a public property so it can be accessed from a mailable view.


<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class ContactEmail extends Mailable
{
    use Queueable, SerializesModels;

    public $contact;

    /**
     * Create a new message instance.
     *
     */
    public function __construct( array $contact )
    {
        $this->contact = $contact;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->markdown('mail.contact');
    }
}

In the resources/views folder is where you can place the markdown for the email.


@component('mail::message')
# Contact Form

<p>From: {{ $contact['name'] }}</p>

<p>Email: {{ $contact['email'] }}</p>

{{ $contact['message'] }}

Thanks,<br>
{{ config('app.name') }}
@endcomponent

If you're trying this on Homestead you should be able to view this email on mailhog by accessing your homestead box on port 8025