Jonjie Jonjie - 2 years ago 139
Ajax Question

How to use On input using VueJs and Laravel 5

I followed along this tutorial and it worked perfectly fine. But what I want is to not use

submit
button to check or perform the validation, what I want is while I'm typing, it is now validating the form. Please see my code below, or visit the link that I mentioned above.

Code:


routes


<?php

Route::get('/', function () {
return view('welcome');
});

Route::get('/article/create', 'ArticleController@showArticleCreationForm');
Route::post('/article', 'ArticleController@publish');





ArticleController

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;

class ArticleController extends Controller
{
public function showArticleCreationForm(){
return view('article.create');
}

public function publish(Request $request){
$this->validate($request, [
'title' => 'required|min:3',
'body' => 'required|min:10'
]);
if ($request->ajax()) return;

return 'publish';
}
}






create.blade.php


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Create Article</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha256-7s5uDGW3AHqw6xtJmNNtr+OBRJUlgkNJEo78P4b0yRw= sha512-nNo+yCHEyn0smMxSswnf/OnX6/KwJuZTlNZBjauKhTK0c+zT+q5JOCx0UFhXQ6rJR9jg6Es8gPuD2uZcYDLqSw==" crossorigin="anonymous">
<style>
.body {
height: 200px !important;
}

.error {
color: darkred;
margin-top: 5px;
display: block;
}
</style>
</head>
<body id="app">
<form @submit.prevent="submitForm" class="col-md-4 col-md-offset-4" action="{{ URL::to('/') }}/article" method="post">
<h1>Create New Article</h1>
<hr>

{!! csrf_field() !!}

<div class="form-group">
<input class="form-control title" type="text" name="title" placeholder="Title" v-model="formInputs.title">
<span v-if="formErrors['title']" class="error">@{{ formErrors['title'] }}</span>
</div>

<div class="form-group">
<textarea class="form-control body" name="body" placeholder="Content" v-model="formInputs.body"></textarea>
<span v-if="formErrors['body']" class="error">@{{ formErrors['body'] }}</span>
</div>

<button class="btn btn-primary" type="submit">Publish</button>
</form>


<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.14/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.6.1/vue-resource.min.js"></script>
<script>
new Vue({
el: '#app',

data: {
formInputs: {},
formErrors: {}
},

methods: {
submitForm: function(e){
var form = e.target;
var action = form.action;
var csrfToken = form.querySelector('input[name="_token"]').value;

this.$http.post(action, this.formInputs, {
headers: {
'X-CSRF-TOKEN': csrfToken
}
})
.then(function() {
form.submit();
})
.catch(function (data, status, request) {
var errors = data.data;
this.formErrors = errors;
});
}
}
});
</script>
</body>
</html>

Answer Source

If you want to validate while typing you should add an @keyup (or v-on:keyup) event listener on your inputs and validate when it's triggered e.g:

<input class="form-control title" type="text" name="title" placeholder="Title" v-model="formInputs.title" v-on:keyup="validate">

And your event listener:

 methods: {
      validate: function (e) {
            //e.target would have the target input which is being changed 

            _.debounce(function () {
                    var input = e.target;
                    var form = input.form;
                    var action = form.action; 
                    var csrfToken = form.querySelector('input[name="_token"]').value;

                    this.$http.post(action, this.formInputs, {
                    headers: {
                        'X-CSRF-TOKEN': csrfToken
                    }
                 })
                .then(function() {
                      // Don't submit
                 })
                .catch(function (data, status, request) {
                    var errors = data.data;
                    this.formErrors = errors;
                });

            }.bind(this), 500); 
      }

This example uses _.debounce which is a lodash function but you can easily write something similar yourself via setTimeout and cancelTimeout (lodash is just a convenience). The purpose is to not trigger validation on every keyup but rather spread it around a bit.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download