validation error in ajax form
I can use captcha in a simple form, but in ajax form I always see validation error wrong captcha. I cannot understand how to fix it.
blade view
<form method="POST" action="/modalform" method="POST" @submit.prevent="submitData()">
@csrf
<div class="bg-white">
<div class="modalheader flex place-items-center text-center border-b cursor-pointer text-lg leading-6 font-medium text-gray-900">
<h3 class="p-2 hover:bg-blue-500 hover:text-white"
@click="$dispatch('callback')"
:class="callback ? 'bg-blue-500 text-white' : ''"
>
Перезвоните мне
</h3>
<h3 class="p-2 hover:bg-blue-500 hover:text-white"
@click="$dispatch('zamer')"
:class="zamer ? 'bg-blue-500 text-white' : ''"
>
Записаться на замер
</h3>
<h3 class="p-2 hover:bg-blue-500 hover:text-white"
@click="$dispatch('eskiz')"
:class="eskiz ? 'bg-blue-500 text-white' : ''"
>
Отправить эскиз
</h3>
<div class="p-2 place-self-stretch hover:bg-blue-500 hover:text-white" @click="closeModal()" >
<span class="text-3xl">×</span>
</div>
</div>
<div class="modalbody flex items-center w-full h-full p-5"
x-show="sent"
x-text="message"
x-transition:enter="transition ease-out duration-500"
x-transition:enter-start="opacity-0 scale-90"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100 "
x-transition:leave-end="opacity-0 "
>
</div>
<div class="modalbody flex items-start flex-wrap p-5"
x-show="!sent"
x-transition:enter="transition ease-out duration-500"
x-transition:enter-start="opacity-0 scale-90"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-200"
>
<div class="text-left w-full">
<div class="mt-2 grid grid-cols-2 gap-x-4 gap-y-2 mb-2">
<!-- Name -->
<div class="name"
:class="errorData.name ? 'text-red-500' : ''"
>
<x-modules.label for="name" :value="__('auth.user.name')" />
<div class="relative text-gray-400 focus-within:text-gray-800">
<div class="absolute flex border border-transparent left-0 top-0 h-full w-10" >
<x-modules.svg type="user-solid" class="flex items-center justify-center rounded-l bg-gray-100 h-full w-full px-0.5"/>
</div>
<x-modules.input id="name" class="block w-full pl-12" type="text" name="name" :value="old('name')" x-model="formData.name" placeholder="Введите имя" autofocus />
</div>
<span x-text="errorData.name" class="text-red-500 text-xs"> </span>
</div>
<!-- Phone -->
<div class="phone"
:class="errorData.phone ? 'text-red-500' : ''"
>
<x-modules.label for="phone" :value="__('auth.user.phone')" />
<div class="relative text-gray-400 focus-within:text-gray-800">
<div class="absolute flex border border-transparent left-0 top-0 h-full w-10 ">
<x-modules.svg type="phone-ringing-outline" class="flex items-center justify-center rounded-l bg-gray-100 h-full w-full px-0.5"/>
</div>
<x-modules.input id="phone" class="block w-full pl-12" type="text" name="phone" :value="old('phone')" x-model="formData.phone" placeholder="Введите телефон" required autofocus />
</div>
<span x-text="errorData.phone" class="text-red-500 text-xs"> </span>
</div>
<!-- Email Address -->
<div class="email"
x-show="zamer || eskiz"
:class="errorData.email ? 'text-red-500' : ''"
>
<x-modules.label for="email" :value="__('email')" />
<div class="relative text-gray-400 focus-within:text-gray-800">
<div class="absolute flex border border-transparent left-0 top-0 h-full w-10 ">
<x-modules.svg type="envelope-outline" class="flex items-center justify-center rounded-l bg-gray-100 h-full w-full px-0.5"/>
</div>
<x-modules.input id="email" class="block w-full pl-12" type="email" name="email" :value="old('email')" x-model="formData.email" autofocus />
</div>
<span x-text="errorData.email" class="text-red-500 text-xs"> </span>
</div>
<!-- Address -->
<div class="address"
x-show="zamer || eskiz"
:class="errorData.address ? 'text-red-500' : ''"
>
<x-modules.label for="address" :value="__('auth.user.address')" />
<div class="relative text-gray-400 focus-within:text-gray-800">
<div class="absolute flex border border-transparent left-0 top-0 h-full w-10 ">
<x-modules.svg type="facade" class="flex items-center justify-center rounded-l bg-gray-100 h-full w-full px-0.5"/>
</div>
<x-modules.input id="address" class="block w-full pl-12" type="text" name="address" :value="old('address')" x-model="formData.address" autofocus />
</div>
<span x-text="errorData.address" class="text-red-500 text-xs"> </span>
</div>
<!-- Upload field -->
<div class="upload" x-show="eskiz">
<label class="flex items-center justify-evenly p-2 bg-white text-gray-700 rounded-lg shadow-lg border border-gray-300 cursor-pointer hover:bg-blue-500 hover:text-white">
<x-modules.svg type="upload" class="w-8 h-8"/>
<span>Выберите файл</span>
<input type="file" class="hidden" multiple />
</label>
</div>
</div>
<!-- Message -->
<div class="message">
<x-modules.label for="message" :value="__('auth.user.message')" />
<x-modules.textarea rows="2" id="message" class="block w-full" name="message" x-model="formData.message" placeholder="Кратко опишите ваш вопрос"/></textarea>
<span x-text="errorData.message" class="text-red-500 text-xs"> </span>
</div>
<!-- captcha -->
<div class="mt-4 captcha flex">
<div class="w-32 mr-4 img">{!! captcha_img() !!}</div>
<x-modules.svg type="refresh" class="w-6 h-6 mr-1 reload cursor-pointer" id="reload"/>
</div>
<div class="mt-4">
<x-modules.input id="captcha" class="block mt-1 w-full" type="text" name="captcha" placeholder="Enter Captcha" x-model="formData.captcha" required />
</div>
</div>
</div>
<div class="modalfooter bg-gray-50 px-4 py-3 sm:px-6 flex justify-between ">
<x-modules.button text="Отмена" style="black-outline" class="px-4" @click.prevent="closeModal()" />
<x-modules.button x-text="buttonLabel" style="blue-solid" class="px-4" @click.prevent="submitData()" />
</div>
</div>
</form>
<script>
function topbar() {
return {
mailTooltip: false,
instagramTooltip: false,
openModal: false,
callback: true,
zamer: false,
eskiz: false,
formData: {
name: '',
phone: '',
email: '',
address: '',
message: '',
captcha: '',
_token: '{{ csrf_token() }}'
},
message: '',
responseData: [],
errorStates: {
name: false,
phone: false,
email: false,
address: false,
message: false,
captcha: false
},
errorData: [],
loading: false,
sent: false,
buttonLabel: 'Отправить',
resetFields() {
this.formData.name = '',
this.formData.phone = '',
this.formData.email = '',
this.formData.address = '',
this.formData.message = '',
this.formData.captcha = ''
},
closeModal() {
this.openModal = false;
this.callback = false;
this.zamer = false;
this.eskiz = false;
},
submitData() {
axios.post('/modalform', this.formData)
.then( (response) => {
this.buttonLabel = 'Отправляем...';
this.loading = true;
console.log(response);
this.resetFields();
this.sent = true;
this.message = 'Сообщение успешно отправлено!';
this.responseData = response.data;
})
.then( () => {
this.loading = false;
this.sent = false;
this.closeModal();
this.buttonLabel = 'Отправить';
this.message = '';
})
.catch( (error) => {
console.log(error);
this.message = 'Ooops! Что-то пошло не так!'
this.errorData = error.response.data.errors;
this.isErrorName();
});
},
isErrorName() {
if (error.response.data.errors.name === 'undefined') {
this.errorStates.name = false;
} else {
this.errorStates.name = true;
}
},
}
}
</script>
routes/web.php
Route::post('/modalform', 'MainController@modalform')->name('modalform');
app/Http/Controllers/MainController.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\Modalform;
use App\Http\Requests\ModalformRequest;
class MainController extends Controller
{
public function modalform(ModalformRequest $request) {
Mail::to( config('mail.to.address') )->send(new Modalform());
return response()->json([
'status' => 'success',
'messageHeader' => 'Ваш вопрос отправлен!',
'messageContent' => 'В ближайшее время мы свяжемся с вами.',
]);
}
}
app/Mail/Modalform.php
use Illuminate\Http\Request;
use App\Http\Requests\ModalformRequest;
use Illuminate\Mail\Mailable;
class Modalform extends Mailable
{
public function build(ModalformRequest $request)
{
$this->from( config('mail.from.address') )
->view('emails.modalform')
->withRequest($request);
}
}
App/Http/Requests/ModalformRequest.php
<?php
use Illuminate\Foundation\Http\FormRequest;
class ModalformRequest extends FormRequest
{
public function rules()
{
return [
'name' => 'bail|required|string|between:2,20',
'phone' => 'bail|required',
'email' => 'bail|email:rfc|nullable',
'address' => 'bail|string|max:100|nullable',
'message' => 'bail|string|max:500|nullable',
'captcha' => 'required|captcha',
];
}
}
I can use captcha in a simple form, but in ajax form I always see validation error wrong captcha. I cannot understand how to fix it.
blade view
<form method="POST" action="/modalform" method="POST" @submit.prevent="submitData()"> @csrf <div class="bg-white"> <div class="modalheader flex place-items-center text-center border-b cursor-pointer text-lg leading-6 font-medium text-gray-900"> <h3 class="p-2 hover:bg-blue-500 hover:text-white" @click="$dispatch('callback')" :class="callback ? 'bg-blue-500 text-white' : ''" > Перезвоните мне </h3> <h3 class="p-2 hover:bg-blue-500 hover:text-white" @click="$dispatch('zamer')" :class="zamer ? 'bg-blue-500 text-white' : ''" > Записаться на замер </h3> <h3 class="p-2 hover:bg-blue-500 hover:text-white" @click="$dispatch('eskiz')" :class="eskiz ? 'bg-blue-500 text-white' : ''" > Отправить эскиз </h3> <div class="p-2 place-self-stretch hover:bg-blue-500 hover:text-white" @click="closeModal()" > <span class="text-3xl">×</span> </div> </div> <div class="modalbody flex items-center w-full h-full p-5" x-show="sent" x-text="message" x-transition:enter="transition ease-out duration-500" x-transition:enter-start="opacity-0 scale-90" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-200" x-transition:leave-start="opacity-100 " x-transition:leave-end="opacity-0 " > </div> <div class="modalbody flex items-start flex-wrap p-5" x-show="!sent" x-transition:enter="transition ease-out duration-500" x-transition:enter-start="opacity-0 scale-90" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-200" > <div class="text-left w-full"> <div class="mt-2 grid grid-cols-2 gap-x-4 gap-y-2 mb-2"> <!-- Name --> <div class="name" :class="errorData.name ? 'text-red-500' : ''" > <x-modules.label for="name" :value="__('auth.user.name')" /> <div class="relative text-gray-400 focus-within:text-gray-800"> <div class="absolute flex border border-transparent left-0 top-0 h-full w-10" > <x-modules.svg type="user-solid" class="flex items-center justify-center rounded-l bg-gray-100 h-full w-full px-0.5"/> </div> <x-modules.input id="name" class="block w-full pl-12" type="text" name="name" :value="old('name')" x-model="formData.name" placeholder="Введите имя" autofocus /> </div> <span x-text="errorData.name" class="text-red-500 text-xs"> </span> </div> <!-- Phone --> <div class="phone" :class="errorData.phone ? 'text-red-500' : ''" > <x-modules.label for="phone" :value="__('auth.user.phone')" /> <div class="relative text-gray-400 focus-within:text-gray-800"> <div class="absolute flex border border-transparent left-0 top-0 h-full w-10 "> <x-modules.svg type="phone-ringing-outline" class="flex items-center justify-center rounded-l bg-gray-100 h-full w-full px-0.5"/> </div> <x-modules.input id="phone" class="block w-full pl-12" type="text" name="phone" :value="old('phone')" x-model="formData.phone" placeholder="Введите телефон" required autofocus /> </div> <span x-text="errorData.phone" class="text-red-500 text-xs"> </span> </div> <!-- Email Address --> <div class="email" x-show="zamer || eskiz" :class="errorData.email ? 'text-red-500' : ''" > <x-modules.label for="email" :value="__('email')" /> <div class="relative text-gray-400 focus-within:text-gray-800"> <div class="absolute flex border border-transparent left-0 top-0 h-full w-10 "> <x-modules.svg type="envelope-outline" class="flex items-center justify-center rounded-l bg-gray-100 h-full w-full px-0.5"/> </div> <x-modules.input id="email" class="block w-full pl-12" type="email" name="email" :value="old('email')" x-model="formData.email" autofocus /> </div> <span x-text="errorData.email" class="text-red-500 text-xs"> </span> </div> <!-- Address --> <div class="address" x-show="zamer || eskiz" :class="errorData.address ? 'text-red-500' : ''" > <x-modules.label for="address" :value="__('auth.user.address')" /> <div class="relative text-gray-400 focus-within:text-gray-800"> <div class="absolute flex border border-transparent left-0 top-0 h-full w-10 "> <x-modules.svg type="facade" class="flex items-center justify-center rounded-l bg-gray-100 h-full w-full px-0.5"/> </div> <x-modules.input id="address" class="block w-full pl-12" type="text" name="address" :value="old('address')" x-model="formData.address" autofocus /> </div> <span x-text="errorData.address" class="text-red-500 text-xs"> </span> </div> <!-- Upload field --> <div class="upload" x-show="eskiz"> <label class="flex items-center justify-evenly p-2 bg-white text-gray-700 rounded-lg shadow-lg border border-gray-300 cursor-pointer hover:bg-blue-500 hover:text-white"> <x-modules.svg type="upload" class="w-8 h-8"/> <span>Выберите файл</span> <input type="file" class="hidden" multiple /> </label> </div> </div> <!-- Message --> <div class="message"> <x-modules.label for="message" :value="__('auth.user.message')" /> <x-modules.textarea rows="2" id="message" class="block w-full" name="message" x-model="formData.message" placeholder="Кратко опишите ваш вопрос"/></textarea> <span x-text="errorData.message" class="text-red-500 text-xs"> </span> </div> <!-- captcha --> <div class="mt-4 captcha flex"> <div class="w-32 mr-4 img">{!! captcha_img() !!}</div> <x-modules.svg type="refresh" class="w-6 h-6 mr-1 reload cursor-pointer" id="reload"/> </div> <div class="mt-4"> <x-modules.input id="captcha" class="block mt-1 w-full" type="text" name="captcha" placeholder="Enter Captcha" x-model="formData.captcha" required /> </div> </div> </div> <div class="modalfooter bg-gray-50 px-4 py-3 sm:px-6 flex justify-between "> <x-modules.button text="Отмена" style="black-outline" class="px-4" @click.prevent="closeModal()" /> <x-modules.button x-text="buttonLabel" style="blue-solid" class="px-4" @click.prevent="submitData()" /> </div> </div> </form> <script> function topbar() { return { mailTooltip: false, instagramTooltip: false, openModal: false, callback: true, zamer: false, eskiz: false, formData: { name: '', phone: '', email: '', address: '', message: '', captcha: '', _token: '{{ csrf_token() }}' }, message: '', responseData: [], errorStates: { name: false, phone: false, email: false, address: false, message: false, captcha: false }, errorData: [], loading: false, sent: false, buttonLabel: 'Отправить', resetFields() { this.formData.name = '', this.formData.phone = '', this.formData.email = '', this.formData.address = '', this.formData.message = '', this.formData.captcha = '' }, closeModal() { this.openModal = false; this.callback = false; this.zamer = false; this.eskiz = false; }, submitData() { axios.post('/modalform', this.formData) .then( (response) => { this.buttonLabel = 'Отправляем...'; this.loading = true; console.log(response); this.resetFields(); this.sent = true; this.message = 'Сообщение успешно отправлено!'; this.responseData = response.data; }) .then( () => { this.loading = false; this.sent = false; this.closeModal(); this.buttonLabel = 'Отправить'; this.message = ''; }) .catch( (error) => { console.log(error); this.message = 'Ooops! Что-то пошло не так!' this.errorData = error.response.data.errors; this.isErrorName(); }); }, isErrorName() { if (error.response.data.errors.name === 'undefined') { this.errorStates.name = false; } else { this.errorStates.name = true; } }, } } </script>routes/web.php
Route::post('/modalform', 'MainController@modalform')->name('modalform');app/Http/Controllers/MainController.php
use Illuminate\Http\Request; use Illuminate\Support\Facades\Mail; use App\Mail\Modalform; use App\Http\Requests\ModalformRequest; class MainController extends Controller { public function modalform(ModalformRequest $request) { Mail::to( config('mail.to.address') )->send(new Modalform()); return response()->json([ 'status' => 'success', 'messageHeader' => 'Ваш вопрос отправлен!', 'messageContent' => 'В ближайшее время мы свяжемся с вами.', ]); } }app/Mail/Modalform.php
use Illuminate\Http\Request; use App\Http\Requests\ModalformRequest; use Illuminate\Mail\Mailable; class Modalform extends Mailable { public function build(ModalformRequest $request) { $this->from( config('mail.from.address') ) ->view('emails.modalform') ->withRequest($request); } }App/Http/Requests/ModalformRequest.php
<?php use Illuminate\Foundation\Http\FormRequest; class ModalformRequest extends FormRequest { public function rules() { return [ 'name' => 'bail|required|string|between:2,20', 'phone' => 'bail|required', 'email' => 'bail|email:rfc|nullable', 'address' => 'bail|string|max:100|nullable', 'message' => 'bail|string|max:500|nullable', 'captcha' => 'required|captcha', ]; } }
validation of captcha will done by captcha_check() method not in Laravel validator function. this method will return a boolean response for validation. you should pass the code to this method like this : if (captcha_check($request->captcha_input) == false) { return back()->with('invalid-captcha','captcha is invalid'); }