How to display validation errors? - laravel

Router
Route::get('/contact',['uses'=>'Admin\ContactController#show','as'=>'contact']);
Route::post('/contact',['uses'=>'Admin\ContactController#store']);
Controller
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Requests\ContactRequest;
use App\Http\Controllers\Controller;
use Validator;
class ContactController extends Controller
{
public function store(Request $request,$id=FALSE) {
if($request->isMethod('post')) {
$messages = [
'name.required' => 'ПОЛЕ :attribute обязательно к заполнению!!!!',
'email.max' => 'Максимально допустимое количество символов - :max',
];
$validator = Validator::make($request->all(),[
'name'=>'required',
/*'email'=>'required'*/
],$messages);
$validator->sometimes(['email','site'],'required',function($input) {
/*dump($input);
exit();*/
return strlen($input->name) >= 10;
});
$validator->after(function($validator) {
$validator->errors()->add('name','ДОполнительное сообщение');
});
if($validator->fails()) {
$messages = $validator->errors();
//dump ($messages->first());
dump($validator->failed());
exit();
return redirect()->route('contact')->withErrors($validator)->withInput();
}
}
return view('default.contact',['title'=>'Contacts']);
}
public function show() {
return view('default.contact',['title'=>'Contacts']);
}
}
Template
extends('default.layouts.layout')
#section('content')
<div class="col-md-9">
<div class="">
<h2>Contact us!</h2>
</div>
<p>
This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.
</p>
{{ count($errors)}}
#if(count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach($errors->all() as $error)
<li>{{ $error}}</li>
#endforeach
</ul>
</div>
#endif
<form method="post" action="{{ route('contact') }}">
{{ csrf_field() }}
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name="name" value="{{ old('name') }}" placeholder="Jane Doe">
</div>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" id="email" value="{{ old('email') }}" name="email" placeholder="Email">
</div>
<div class="form-group">
<label for="site">Site</label>
<input type="text" class="form-control" id="site" value="{{ old('site') }}" name="site" placeholder="Site">
</div>
<div class="form-group">
<label for="text">Text</label>
<textarea class="form-control" id="text" name="text" rows="3">{{ old('text') }}</textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
#endsection
The problem is that I have not displayed validation error and the message "further message". Although the validation is successful. The problem is. I don't want to display $messages I tried to walk on it with foreach, but laravel says that it found the $messages. Although the controller $messages displayed. The pattern also shows that the errors I have 0, but in the controller I have shows validation errors.
What's the problem?

try this:i hope it will work for you.
//controller
if ($request->method() == 'POST') {
$rules = [
'name' => 'required',
'email' => 'required'
];
$validator = Validator::make($request->all(), $rules);
if (!$validator->fails()) {
}
else{
//validation_error();
}
}
and use js for validation
$(function () {
$("#form_id").validate({
errorElement: 'small', errorClass: 'invalid-feedback',
rules: {
name: {
required: true,
},
email: {
required: true,
}
},
messages: {
name: {
required: "Name Field Is Required.",
},
email: {
required: "Email Field Is Required.",
}
},
highlight: function (element) {
$(element).closest('.form-group').addClass('has-error');
},
unhighlight: function (element) {
$(element).closest('.form-group').removeClass('has-error');
},
success: function (element) {
$(element).closest('.form-group').removeClass('has-error');
$(element).closest('.form-group').children('small.invalid-feedback').remove();
},
errorPlacement: function (error, element) {
error.appendTo(element.closest('.form-group'));
},
submitHandler: function (form) {
$(window).block({
'message': '<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>',
'css': {
border: '0',
padding: '0',
backgroundColor: 'none',
marginTop: '5%',
zIndex: '10600'
},
overlayCSS: {backgroundColor: '#555', opacity: 0.3, cursor: 'wait', zIndex: '10600'},
});
$.post('', $("#form_id").serialize(), function (data) {
if (data.code == '1') {
swal({
title: "",
text: data.message,
type: "success"
}, function () {
document.location.href = base_url + '/listing_page';
});
} else if (data === '0') {
swal("", "Something wrong while save building information.", "warning");
} else {
swal("", data, "error");
}
$(window).unblock();
});
}
});
$('select').change(function () {
$("#form_id").validate().element($(this));
});
});

Related

I'm trying in laravel to log in with my phone number but it doesn't work

I changed the login by mail to login with phone number in a laravel system, but it does not log in in any way. either it doesn't find it in the database or I'm doing something wrong. I asked chatgpt and searched many forums but still no success. where am i doing wrong?
LoginController
namespace App\Http\Controllers;
use Exception;
use App\Models\User;
use App\Helper\Reply;
use App\Models\Social;
use Illuminate\Http\Request;
use Laravel\Fortify\Fortify;
use App\Events\TwoFactorCodeEvent;
use App\Traits\SocialAuthSettings;
use Froiden\Envato\Traits\AppBoot;
use Illuminate\Support\Facades\DB;
use App\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
use \Illuminate\Validation\ValidationException;
class LoginController extends Controller
{
use AppBoot, SocialAuthSettings;
protected $redirectTo = 'account/dashboard';
public function checkEmail(LoginRequest $request)
{
exit ;
$user = User::where('mobile', $request->mobile)
->select('id')
->where('status', 'active')
->where('login', 'enable')
->first();
if (is_null($user)) {
throw ValidationException::withMessages([
Fortify::username() => __('messages.invalidOrInactiveAccount'),
]);
}
return response([
'status' => 'success'
]);
}
public function checkCode(Request $request)
{
$request->validate([
'code' => 'required',
]);
$user = User::find($request->user_id);
if($request->code == $user->two_factor_code) {
// Reset codes and expire_at after verification
$user->resetTwoFactorCode();
// Attempt login
Auth::login($user);
return redirect()->route('dashboard');
}
// Reset codes and expire_at after failure
$user->resetTwoFactorCode();
return redirect()->back()->withErrors(['two_factor_code' => __('messages.codeNotMatch')]);
}
public function resendCode(Request $request)
{
$user = User::find($request->user_id);
$user->generateTwoFactorCode();
event(new TwoFactorCodeEvent($user));
return Reply::success(__('messages.codeSent'));
}
public function redirect($provider)
{
$this->setSocailAuthConfigs();
return Socialite::driver($provider)->redirect();
}
public function callback(Request $request, $provider)
{
$this->setSocailAuthConfigs();
try {
try {
if ($provider != 'twitter') {
$data = Socialite::driver($provider)->stateless()->user();
}
else {
$data = Socialite::driver($provider)->user();
}
} catch (Exception $e) {
$errorMessage = $e->getMessage();
return redirect()->route('login')->with('message', $errorMessage);
}
$user = User::where(['email' => $data->email, 'status' => 'active', 'login' => 'enable'])->first();
if ($user) {
// User found
DB::beginTransaction();
Social::updateOrCreate(['user_id' => $user->id], [
'social_id' => $data->id,
'social_service' => $provider,
]);
DB::commit();
Auth::login($user, true);
return redirect()->intended($this->redirectPath());
}
else {
return redirect()->route('login')->with(['message' => __('messages.unAuthorisedUser')]);
}
} catch (Exception $e) {
$errorMessage = $e->getMessage();
return redirect()->route('login')->with(['message' => $errorMessage]);
}
}
public function redirectPath()
{
if (method_exists($this, 'redirectTo')) {
return $this->redirectTo();
}
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/login';
}
public function username()
{
return 'mobile';
}
}
Here blade code;
<label for="mobile">#lang('auth.mobile')</label>
<input tabindex="1" type="text" name="mobile"
class="form-control height-50 f-15 light_text" autofocus
placeholder="#lang('auth.mobile')" id="mobile">
<input type="hidden" id="g_recaptcha" name="g_recaptcha">
</div>
#if ($socialAuthSettings->social_auth_enable)
<button type="submit" id="submit-next"
class="btn-primary f-w-500 rounded w-100 height-50 f-18 ">#lang('auth.next') <i
class="fa fa-arrow-right pl-1"></i></button>
#endif
<div id="password-section"
#if ($socialAuthSettings->social_auth_enable) class="d-none" #endif>
<div class="form-group text-left">
<label for="password">#lang('app.password')</label>
<x-forms.input-group>
<input type="password" name="password" id="password"
placeholder="#lang('placeholders.password')" tabindex="3"
class="form-control height-50 f-15 light_text">
<x-slot name="append">
<button type="button" data-toggle="tooltip"
data-original-title="#lang('app.viewPassword')"
class="btn btn-outline-secondary border-grey height-50 toggle-password"><i
class="fa fa-eye"></i></button>
</x-slot>
</x-forms.input-group>
</div>
<div class="forgot_pswd mb-3">
#lang('app.forgotPassword')
</div>
<div class="form-group text-left">
<input id="checkbox-signup" type="checkbox" name="remember">
<label for="checkbox-signup">#lang('app.rememberMe')</label>
</div>
#if ($setting->google_recaptcha_status == 'active' && $setting->google_recaptcha_v2_status == 'active')
<div class="form-group" id="captcha_container"></div>
#endif
#if ($errors->has('g-recaptcha-response'))
<div class="help-block with-errors">{{ $errors->first('g-recaptcha-response') }}
</div>
#endif
<button type="submit" id="submit-login"
class="btn-primary f-w-500 rounded w-100 height-50 f-18">
#lang('app.login') <i class="fa fa-arrow-right pl-1"></i>
</button>
#if ($setting->allow_client_signup)
<a href="{{ route('register') }}"
class="btn-secondary f-w-500 rounded w-100 height-50 f-15 mt-3">
#lang('app.signUpAsClient')
</a>
#endif
</div>
</div>
</div>
</div>
</div>
</section>
</form>
<x-slot name="scripts">
#if ($setting->google_recaptcha_status == 'active' && $setting->google_recaptcha_v2_status == 'active')
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async
defer></script>
<script>
var gcv3;
var onloadCallback = function () {
// Renders the HTML element with id 'captcha_container' as a reCAPTCHA widget.
// The id of the reCAPTCHA widget is assigned to 'gcv3'.
gcv3 = grecaptcha.render('captcha_container', {
'sitekey': '{{ $setting->google_recaptcha_v2_site_key }}',
'theme': 'light',
'callback': function (response) {
if (response) {
$('#g_recaptcha').val(response);
}
},
});
};
</script>
#endif
#if ($setting->google_recaptcha_status == 'active' && $setting->google_recaptcha_v3_status == 'active')
<script
src="https://www.google.com/recaptcha/api.js?render={{ $setting->google_recaptcha_v3_site_key }}"></script>
<script>
grecaptcha.ready(function () {
grecaptcha.execute('{{ $setting->google_recaptcha_v3_site_key }}').then(function (token) {
// Add your logic to submit to your backend server here.
$('#g_recaptcha').val(token);
});
});
</script>
#endif
<script>
$(document).ready(function () {
$('#submit-next').click(function () {
const url = "{{ route('check_email') }}";
$.easyAjax({
url: url,
container: '#login-form',
disableButton: true,
buttonSelector: "#submit-next",
type: "POST",
data: $('#login-form').serialize(),
success: function (response) {
if (response.status === 'success') {
$('#submit-next').remove();
$('#password-section').removeClass('d-none');
$("#password").focus();
}
}
})
});
$('#submit-login').click(function () {
const url = "{{ route('login') }}";
$.easyAjax({
url: url,
container: '.login_box',
disableButton: true,
buttonSelector: "#submit-login",
type: "POST",
blockUI: true,
data: $('#login-form').serialize(),
success: function (response) {
if (response.two_factor == false) {
window.location.href = "{{ session()->has('url.intended') ? session()->get('url.intended') : route('dashboard') }}";
} else if (response.two_factor == true) {
window.location.href = "{{ url('two-factor-challenge') }}";
}
}
})
});
#if (session('message'))
Swal.fire({
icon: 'error',
text: '{{ session('message') }}',
showConfirmButton: true,
customClass: {
confirmButton: 'btn btn-primary',
},
showClass: {
popup: 'swal2-noanimation',
backdrop: 'swal2-noanimation'
},
})
#endif
});
</script>
</x-slot>
</x-auth> ```

Vue 3 checkbox component does not work in laravel as checkbox (Accept terms) situation

I'm working on a laravel 9 project that uses vue 3. For each form input has been made field components.Everything works fine except registration checkbox (Accept terms). If the checkbox is used normally in vue, it works fine. as soon as a component is made of it, it no longer works. By clicking the chackbox on and off I get the message that the accept terms is required!
I hope you can help me with this
-Vue Registration Form componetnt
<template>
<form class="text-left" method="post" #submit.prevent="submit()">
<div class="alert alert-success mb-1" v-if="success" v-html="successMessage"></div>
<div class="alert alert-danger mb-1" v-if="errors.message" v-html="errors.message"></div>
<InputFieldWithoutIcon ref="email" type="email" name="email" label="E-mail" :errors="errors" #update:field="fields.email=$event"/>
<InputFieldWithoutIcon ref="password" type="password" name="password" label="Password" :errors="errors" #update:field="fields.password=$event"/>
<InputFieldWithoutIcon ref="password_confirmation" type="password" name="password_confirmation" label="Password Confirmation" :errors="errors" #update:field="fields.password_confirmation=$event"/>
<Checkbox :text="newsletter_text" name="newsletter" type="checkbox" :errors="errors" #update:field="fields.newsletter=$event"/>
<Checkbox :text="policy_text" name="policy_accepted" type="checkbox" :errors="errors" #update:field="fields.policy_accepted=$event"/>
<SubmitButtonWithoutIcon name="create account" type="submit" custom_btn_class="btn-block btn-primary" custom_div_class=""/>
</form>
</template>
<script>
import InputFieldWithoutIcon from "../components/InputFieldWithoutIcon";
import SubmitButtonWithoutIcon from "../components/SubmitButtonWithoutIcon";
import Checkbox from "../components/Checkbox";
export default {
name: "RegistrationUser",
components: {
InputFieldWithoutIcon,
SubmitButtonWithoutIcon,
Checkbox
},
data() {
return {
fields: {
email: '',
password: '',
password_confirmation: '',
policy_accepted: '',
newsletter: '',
},
errors: {},
success: false,
successMessage: '',
newsletter_text: 'I want to receive newsletters',
policy_text: 'I accept <a class="text-bold text-underline" href="" target="_blank" title="privacy policy">the policy</a>',
}
},
methods: {
submit() {
axios.post('/api/registration', this.fields)
.then(response => {
if (response.status === 200) {
this.$refs.email.value = null;
this.$refs.password.value = null;
this.$refs.password_confirmation.value = null;
this.fields = {
email: '',
password: '',
password_confirmation: '',
policy_accepted: '',
newsletter: '',
};
this.errors = {};
this.success = true;
this.successMessage = response.data.message;
}
}).catch(errors => {
if (errors.response.status === 422 || errors.response.status === 401) {
this.errors = errors.response.data.errors;
}
});
}
}
}
</script>
-Vue Checkbox component
<template>
<div class="custom-control custom-checkbox">
<input class="custom-control-input"
:id="name"
:name="name"
:type="type"
v-model="value"
#input="updateField()"
>
<label class="custom-control-label" :for="name">
{{ text }}
</label>
<div class="invalid-feedback" v-text="errorMessage()"></div>
</div>
</template>
<script>
export default {
name: "Checkbox",
props: [
'name',
'type',
'text',
'errors'
],
data: function () {
return {
value: false
}
},
computed: {
hasError: function () {
return this.errors && this.errors[this.name] && this.errors[this.name].length > 0;
}
},
methods: {
updateField: function () {
this.clearErrors(this.name);
this.$emit('update:field', this.value)
},
errorMessage: function () {
if (this.errors && this.errors[this.name]) {
return this.errors[this.name][0];
}
},
clearErrors: function () {
if (this.hasError) {
this.errors[this.name] = null;
}
}
}
}
</script>
-Laravel Registration request
public function rules(): array
{
return [
'email' => 'required|email|unique:users',
'password' => 'required|confirmed|min:8',
'newsletter' => 'nullable|boolean',
'policy_accepted' => 'accepted'
];
}
I've found the solution.
In the checkbox template instead of using #input="updateField()" I replaced that with #change="updateField()"
That's all!

I want to show data on chart bar when I search by date wise using Laravel

I have chart bar and I am trying to show data by date wise when I filter by date but unfortunately data does not show on chart bar. I want that when I select a start date and end date record should be shown on chart bar by date wise.
Controller
public function status(Request $request)
{
$date = explode(' - ', $request->date);
$manager_hourlog = Hourlog::with('project', "user")->whereBetween('date', $date)
->get()
->groupBy('project.name');
$projects = [];
$totals = [];
foreach ($manager_hourlog as $key => $val) {
$projects[] = $key;
}
foreach ($manager_hourlog as $key2 => $val) {
$minutes = $val->sum('hour_work');
$totals[] = round($minutes / 60, 1);
}
$users = User::where("status", 1)->get();
$data = [
// manager report
'manager_projects' => $projects,
'totals' => $totals,
"manager_hourlog" => $manager_hourlog,
];
return $data;
return response()->json($data, 200);
}
html view
<form action="{{route('dashboard')}}" method="post" >
<div class="form-group">
<div class="input-group theme-input-group select-max-h-200">
<div class="input-group-prepend width-160px">
<div class="input-group-text">Date
</div>
</div>
<input parsley-trigger="change" required type="text" id="date" class="form-control" name="date" autocomplete="off">
<div class="input-group-append">
<span class="input-group-text">
<i class="md md-event-note">
</i>
</span>
</div>
</div>
<!-- input-group -->
</div>
</div>
<div class="col-lg-1">
<div class="text-right">
<button class="btn btn-light-theme waves-effect waves-light" id="search" name="search" type="submit">
<i class="fa fa-search pr-1">
</i> Search
</button>
</div>
</div>
</form>
script
<script type="text/javascript">
$(function () {
$('#search').on('click', function () {
var date = $("#date").val();
$.ajax({
type: 'GET',
url: '{{Route("dashboard.status")}}',
data: {
date: date
},
dataType: "JSon",
success: function(response){
// Employee report script
var colors = ["#1abc9c", "#2ecc71", "#3498db", "#9b59b6", "#34495e", "#16a085", "#27ae60", "#2980b9", "#8e44ad", "#2c3e50", "#f1c40f", "#e67e22", "#e74c3c", "#ecf0f1", "#95a5a6", "#f39c12", "#d35400", "#c0392b", "#bdc3c7", "#7f8c8d"];
#if ($auth->user_type != 1)
// manager report script
var managerchartbar = {
labels: {!! json_encode($manager_projects) !!},
datasets: [
#foreach($users as $user)
{
label: {!! json_encode($user->name) !!},
backgroundColor: colors[Math.floor(Math.random() * colors.length)],
data: [
#foreach($manager_hourlog as $hourlog)
{{$hourlog->where("user_id", $user->id)->sum("hour_work") / 60}},
#endforeach
]
},
#endforeach
]
};
var ctx = document.getElementById('manager').getContext('2d');
window.myBar = new Chart(ctx, {
type: 'bar',
data: managerchartbar,
options: {
title: {
display: true,
text: 'Project Report chart'
},
tooltips: {
mode: 'index',
intersect: false
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
});
#endif
console.log(response);
},
error: function(xhr){
console.log(xhr.responseText);
}});
});
});
</script>

Laravel 5.5 Multilanguage validation

Please tell me, I ran into a problem. There is a site based on Laravel 5.5. The site has a multilanguage (two languages en/ru). For multilanguage I'm using:
dimsav/laravel-translatable
mcamara/laravel-localization
Added language files to the directory resources/lang/ru. The problem is the validation of the form. The site has a feedback form in the modal window, working with ajax (sending and validating), error messages are displayed only in the default language, the default language is en. I tried to send data from the form without the help of ajax, everything works well, messages are displayed in both Russian and English.
reoutes/web.php
Route::group(['prefix' => LaravelLocalization::setLocale()], function(){
Route::get('/', 'PagesController#getProfile')->name('profile');
Route::get('/skills', 'PagesController#getSkills')->name('skills');
Route::get('/portfolio', 'PagesController#getPortfolio')->name('portfolio');
Route::get('/resume', 'PagesController#getResume')->name('resume');
Route::post('/contact', 'PagesController#contact');
});
controller
public function contact(Request $request){
$validator = Validator::make($request->all(), [
'name' => 'required',
'email' => 'required|email',
'message' => 'required'
]);
if ($validator->passes()) {
Mail::to('mycontactform#mail.ru')->send(new Contact($request));
return response()->json(['success'=>'Message sent successfully!']);
}
return response()->json(['error'=>$validator->errors()->all()]);
}
js
$(document).ready(function() {
$(".btn-send-message").click(function(e){
e.preventDefault();
$.ajax({
url: "/contact",
type:'POST',
data: $('#contact-form').serialize(),
beforeSend: function() {
$("#loading").show();
$(".fa-paper-plane").hide();
},
complete: function() {
$("#loading").hide();
$(".fa-paper-plane").show();
},
success: function(data) {
if($.isEmptyObject(data.error)){
printSuccessMsg();
}else{
printErrorMsg(data.error);
}
}
});
});
var $success_msg = $(".print-success-msg");
var $error_msg = $(".print-error-msg");
function printSuccessMsg() {
$success_msg.html('Message sent successfully!');
$success_msg.css('display','block');
$success_msg.delay(5000).fadeOut(350);
$('#contact-form')[0].reset();
}
function printErrorMsg (msg) {
$error_msg.find("ul").html('');
$error_msg.css('display','block');
$.each( msg, function( key, value ) {
$error_msg.find("ul").append('<li>'+value+'</li>');
});
$error_msg.delay(5000).fadeOut(350);
}
});
form
<div class="modal-body col-md-8 offset-md-2">
<div class="alert alert-danger print-error-msg" style="display:none">
<strong>Errors:</strong>
<ul></ul>
</div>
<div class="alert alert-success print-success-msg" style="display:none"></div>
{!! Form::open(['id'=>'contact-form']) !!}
<div class="form-group">
<input class="form-control" type="text" name="name" id="name" placeholder="Your Name">
</div>
<div class="form-group">
<input class="form-control" type="email" name="email" id="email" placeholder="Your Email">
</div>
<div class="form-group">
<textarea class="form-control" name="message" id="message" rows="3"></textarea>
</div>
<button type="button" class="btn btn-success btn-send-message"><i class="fas fa-paper-plane"></i>
Send Message <span id="loading" style="display: none;"><img class="loader"
src="{{ asset('images/loading.gif') }}"></span>
</button>
{!! Form::close() !!}
</div>
Use LaravelLocalization::getLocalizedURL() which returns an URL adapted to $locale.
So your ajax code will be.
$.ajax({
url: "{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(),'/contact') }}",
type:'POST',
data: $('#contact-form').serialize(),
beforeSend: function() {
$("#loading").show();
$(".fa-paper-plane").hide();
},
complete: function() {
$("#loading").hide();
$(".fa-paper-plane").show();
},
success: function(data) {
if($.isEmptyObject(data.error)){
printSuccessMsg();
}else{
printErrorMsg(data.error);
}
}
});
When you return your response try to use this helper __('translated_string')
To use this helper, you have to create some translate.php file in those folders resources/lang/en and resources/lang/en
For example:
File resources/lang/en/translate.php should contain this array
return [
'success_message' => 'Message sent successfully!',
];
File:
resources/lang/ru/translate.php should contain this array
return [
'success_message' => 'Сообщение успешно отправлено!',
];
For example:
return response()->json(['success'=> __('translate.success_message') ]);
To get some translated string, use dot notation for this helper;
Laravel localization helper

No error messages from 422 response on laravel form request from vue component

I'm trying to submit a form request using axios, have it validated, and return errors if the validation fails. The problem is, when I submit the form, no error messages are returned for me to show on the client side. Here's the HTTP request and vue component:
<div class="card">
<div class="card-header">
<h4>Information</h4>
</div>
<div class="card-body">
<p v-if='!isEditMode'><strong>Name:</strong> {{businessData.name}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-name">Name</label></strong>
<input class="form-control" name="business-name" v-model='businessData.name'>
</div>
<p v-if='!isEditMode'><strong>Description:</strong> {{businessData.description}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-description">Description</label></strong>
<textarea class="form-control normal" name="business-description"
placeholder="Enter your services, what you sell, and why your business is awesome"
v-model='businessData.description'></textarea>
</div>
</div>
</div>
<div class="card">
<h4 class="card-header">Address Information</h4>
<div class="card-body">
<p v-if="!isEditMode"><strong>Street Address: </strong> {{businessData.street}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-street">Street Address: </label></strong>
<input type="text" class="form-control" name="business-street" v-model='businessData.street' placeholder="1404 e. Local Food Ave">
</div>
<p v-if="!isEditMode"><strong>City: </strong> {{businessData.city}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-city">City: </label></strong>
<input class="form-control" type="text" name="business-city" v-model='businessData.city'>
</div>
<p v-if="!isEditMode"><strong>State: </strong> {{businessData.state}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-state">State: </label></strong>
<select class="form-control" name="business-state" id="state" v-model="businessData.state" >...</select>
</div>
<p v-if="!isEditMode"><strong>Zip: </strong> {{businessData.zip}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-zip">Zip: </label></strong>
<input class="form-control" type="text" maxlength="5" name="business-zip" v-model='businessData.zip'>
</div>
</div>
</div>
<div class="card">
<h4 class="card-header">Contact Information</h4>
<div class="card-body">
<p v-if="!isEditMode"><strong>Phone: </strong> {{businessData.phone}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-phone">Phone: </label></strong>
<input class="form-control" type="tel" name="business-phone" v-model='businessData.phone'>
</div>
<p v-if="!isEditMode"><strong>Email: </strong> {{businessData.email}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-Email">Email: </label></strong>
<input class="form-control" type="email" name="business-email" v-model='businessData.email'>
</div>
</div>
</div>
</div>
<script>
export default {
data () {
return {
isEditMode: false,
businessData: this.business,
userData: this.user,
errors: []
}
},
props: {
business: {},
user: {},
role: {}
},
//Todo - Institute client side validation that prevents submission of faulty data
methods: {
validateData(data) {
},
saveBusinessEdits () {
axios.put('/businesses/' + this.business.id , {updates: this.businessData})
.then(response => {
console.log(response.data)
// this.businessData = response.data;
this.isEditMode = false;
})
.catch (response => {
console.log(response.data)
this.isEditMode = false;
})
},
saveUserEdits () {
axios.put('/profile/' + this.user.id , {updates: this.userData})
.then(response => {
console.log(response.data)
this.userData = response.data;
this.isEditMode = false;
})
.catch (response => {
console.log(response)
this.isEditMode = false;
})
}
}
}
Route
Route::put('/businesses/{id}', 'BusinessesController#update');
BusinessController and update function
public function update(BusinessRequest $request, $id)
{
$business = Business::find($id)->update($request->updates);
$coordinates = GoogleMaps::geocodeAddress($business->street,$business->city,$business->state,$business->zip);
if ($coordinates['lat']) {
$business['latitude'] = $coordinates['lat'];
$business['longitude'] = $coordinates['lng'];
$business->save();
return response()->json($business,200);
} else {
return response()->json('invalid_address',406);
}
$business->save();
return response()->json($business,200);
}
and BusinessRequest class
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'business-name'=> 'required|string|max:255',
'business-description'=> 'required|string',
'business-phone' => 'nullable|phone|numeric',
'business-email' => 'nullable|email',
'business-street'=> 'required|string',
'business-city' => 'required|string',
'business-state' => 'required|string|max:2',
'business-zip' => 'required|min:5|max:5|numeric',
];
}
public function messages() {
return [
'business-zip.min:5' =>'your zip code must be a 5 characters long',
'business-email.email'=>'your email is invalid',
'business-phone.numeric'=>'your phone number is invalid',
];
}
}
I don't understand why, even if input valid data, it responds with a 422 response and absolutely no error messages. Since this is laravel 5.6, the 'web' middleware is automatic in all of the routes in the web.php file. So this isn't the problem. Could anyone help me normalize the validation behavior?
In Laravel a 422 status code means that the form validation has failed.
With axios, the objects that are passed to the then and catch methods are actually different. To see the response of the error you would actually need to have something like:
.catch (error => {
console.log(error.response)
this.isEditMode = false;
})
And then to get the errors (depending on your Laravel version) you would have something like:
console.log(error.response.data.errors)
Going forward it might be worth having a look at Spatie's form-backend-validation package
You can use Vue.js and axios to validate and display the errors. Have a route called /validate-data in a controller to validate the data.
app.js file:
import Vue from 'vue'
window.Vue = require('vue');
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
class Errors {
constructor() {
this.errors = {};
}
get(field) {
if (this.errors[field]) {
return this.errors[field][0];
}
}
record(errors) {
this.errors = errors;
}
clear(field) {
delete this.errors[field];
}
has(field) {
return this.errors.hasOwnProperty(field);
}
any() {
return Object.keys(this.errors).length > 0;
}
}
new Vue({
el: '#app',
data:{
errors: new Errors(),
model: {
business-name: '',
business-description: '',
business-phone: ''
},
},
methods: {
onComplete: function(){
axios.post('/validate-data', this.$data.model)
// .then(this.onSuccess)
.catch(error => this.errors.record(error.response.data.errors));
},
}
});
Make a route called /validate-data with a method in the controller, do a standard validate
$this->validate(request(), [
'business-name'=> 'required|string|max:255',
'business-description'=> 'required|string',
'business-phone' => 'nullable|phone|numeric',
'business-email' => 'nullable|email',
'business-street'=> 'required|string',
'business-city' => 'required|string',
'business-state' => 'required|string|max:2',
'business-zip' => 'required|min:5|max:5|numeric'
]
);
Then create your inputs in your view file, using v-model that corresponds to the vue.js data model fields. Underneath it, add a span with an error class (basic red error styling, for example) that only shows up if the errors exist. For example:
<input type="text" name="business-name" v-model="model.business-name" class="input">
<span class="error-text" v-if="errors.has('business-name')" v-text="errors.get('business-name')"></span>
Don't forget to include the app.js file in footer of your view file. Remember to include the tag, and run npm run watch to compile the vue code. This will allow you to validate all errors underneath their input fields.
Forgot to add, have a buttton that has #onclick="onComplete" to run the validate method.

Resources