RoffDaniel's avatar

How to make JS validation?

Hello everyone Perhaps this is a very frequent question, but how much I am a student, I did not find a good answer, a good, in the sense, understandable. I can't figure out how to pass validator responses to JSON in Javascript. I use separate Form Request rules. Please tell me...

Controller and template codes below: Login view

@extends('layouts.account')

@section('content')
    <div class="bg-image" style="background-image: url('{{ asset('/media/sa-wallpapers/night-sf.jpg') }}');">
        <div class="row no-gutters bg-primary-op">
            <div class="hero-static col-md-6 d-flex align-items-center bg-white">
                <div class="p-3 w-100">
                    <div class="mb-3 text-center">
                        <a class="link-fx font-w700 font-size-h1" href="">
                            <small><i class='fad fa-times font-size-h4'></i></small><span class="text-muted">ID</span>
                        </a>
                        <p class="text-uppercase font-w700 font-size-sm text-muted">Авторизация</p>
                    </div>
                    <div class="row no-gutters justify-content-center">
                        <div class="col-sm-8 col-xl-6">
                            <form class="js-validation-signin" action="{{ route('xid-login') }}" method="POST" novalidate="novalidate">
                                @csrf
                                <div class="py-3">
                                    <div class="form-group">
                                        <input type="text" class="form-control form-control-lg form-control-alt" id="uLogin" name="uLogin" placeholder="{{ __('Логин') }}" value="{{ old('uLogin') }}" autocomplete="uLogin" autofocus>
                                    </div>
                                    <div class="form-group">
                                        <input type="password" class="form-control form-control-lg form-control-alt" id="uPassword" name="uPassword" placeholder="{{ __('Пароль') }}" autocomplete="current-password">
                                    </div>
                                </div>
                                <div class="form-group">
                                    <button type="submit" class="btn btn-block btn-hero-lg btn-hero-primary">
                                        <i class="fad fa-fw fa-sign-in mr-1"></i> {{ __('Войти') }}
                                    </button>
                                    <p class="mt-3 mb-0 d-lg-flex justify-content-lg-between">
                                        @if (Route::has('xid-login-recovery'))
                                            <a class="btn btn-sm btn-light d-block d-lg-inline-block mb-1" href="/login/recovery">
                                                <i class="fad fa-exclamation-triangle text-muted mr-1"></i> Забыл пароль
                                            </a>
                                        @elseif (Route::has('xid-register'))
                                            <a class="btn btn-sm btn-light d-block d-lg-inline-block mb-1" href="/register">
                                                <i class="fad fa-plus text-muted mr-1"></i> Регистрация
                                            </a>
                                        @endif
                                    </p>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
            <div class="hero-static col-md-6 d-none d-md-flex align-items-md-center justify-content-md-center text-md-center">
                <div class="p-3">
                    <p class="display-4 font-w700 text-white mb-3">
                        Добро пожаловать в будущее!
                    </p>
                    <a class="text-white" href="">
                        <small><i class='fad fa-times font-size-sm'></i></small>STAR Project
                    </a> <i class="fad fa-copyright text-white ml-1 mr-1"></i> <span class="text-white" data-toggle="year-copy"></span>
                    <p class="text-white">Создано и разработано в <a class="font-weight-bold text-white" href="https://kdevteam.ru/" target="_blank">KDEV PRODUCTION</a></p>
                </div>
            </div>
        </div>
    </div>
@endsection

@section('js_after')
    <script src="{{ mix('/js/plugins/jquery-validation/jquery.validate.min.js') }}"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            Dashmix.helpers("validation")
            $(".js-validation-signin").validate({
                rules: {
                    "uLogin": { required: true, minlength: 3, remote: {
                        url: '{{ route('xid-login') }}',
                        type: 'POST',
                        data: {
                            'uLogin': function () {
                                return $('#uLogin').val();
                            }
                        }
                    }},
                    "uPassword": { required: true, minlength: 5, remote: {
                        url: '{{ route('xid-login') }}',
                        type: 'POST'
                    }}
                },
                messages: {
                    'uLogin': { required: "Пожалуйста, введите логин", minlength: "Ваш логин должен состоять не менее чем из 3 символов", remote: 'Аккаунт с введенным логином не найден' },
                    "uPassword": { required: "Пожалуйста, укажите пароль", minlength: "Ваш пароль должен содержать не менее 5 символов" },
                },
            });
        });
    </script>
@endsection

LoginController

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\RedirectsUsers;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use App\Http\Requests\LoginRequest;

class LoginController extends Controller
{
    use RedirectsUsers, ThrottlesLogins;

    public $username;

    /**
     * LoginController constructor.
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
        $this->username = new LoginRequest();
    }

    /**
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function showLoginForm()
    {
        $data = [
            'pageTemplate' => 'xid_index',
            'title' => 'xID',
            'pageUrl' => route('xid-index'),
            'pageDescription' => 'xSTAR - современный SA:MP проект, представляющий игрокам огромное количество возможностей, которые ранее казались невозможными или просто не столь интересными. Мы переворачиваем стандартные, очевидные вещи и делаем из них что-то новое, интересное для пробы. Мы уверены, что хотя бы одна вещь на нашем проекте сможет удивить лично вас.',
        ];

        return view('pages.account.login', ['data' => $data]);
    }

    /**
     * @param LoginRequest $request
     * @return Response|\Symfony\Component\HttpFoundation\Response|void
     * @throws ValidationException
     */
    public function login(LoginRequest $request)
    {
        // If the class is using the ThrottlesLogins trait, we can automatically throttle
        // the login attempts for this application. We'll key this by the username and
        // the IP address of the client making these requests into this application.
        if (method_exists($this, 'hasTooManyLoginAttempts') &&
            $this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }

        if ($this->attemptLogin($request)) {
            return $this->sendLoginResponse($request);
        }

        // If the login attempt was unsuccessful we will increment the number of attempts
        // to login and redirect the user back to the login form. Of course, when this
        // user surpasses their maximum number of attempts they will get locked out.
        $this->incrementLoginAttempts($request);

        return $this->sendFailedLoginResponse($request);
    }

//    public function login(LoginRequest $request)
//    {
//        $data = DB::select('select `uSalt`, `uPassword` from `users` where `uLogin` = ?', ['ruffic']);
//        //return $request->request->filter('uPassword');
//        if ($data != null) {
//            dd($data);
//        } else {
//            echo 'LOX';
//        }
//    }

    /**
     * Attempt to log the user into the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    protected function attemptLogin(LoginRequest $request)
    {
        return $this->guard()->attempt($this->credentials($request));
    }

    /**
     * Get the needed authorization credentials from the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function credentials(LoginRequest $request)
    {
        return $request->only($this->username->username(), 'uPassword');
    }

    /**
     * Send the response after the user was authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    protected function sendLoginResponse(LoginRequest $request)
    {
        $request->session()->regenerate();

        $this->clearLoginAttempts($request);

        if ($response = $this->authenticated($request, $this->guard()->user())) {
            return $response;
        }

        return $request->wantsJson()
            ? new Response('', 204)
            : redirect()->intended($this->redirectPath());
    }

    /**
     * The user has been authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  mixed  $user
     * @return mixed
     */
    protected function authenticated(LoginRequest $request, $user)
    {
        //
    }

    /**
     * Get the failed login response instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    protected function sendFailedLoginResponse(LoginRequest $request)
    {
        return \response()->json($request);
//        throw ValidationException::withMessages([
//            $this->username->username() => [trans('auth.failed')],
//        ]);
    }

    /**
     * Log the user out of the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function logout(Request $request)
    {
        $this->guard()->logout();

        $request->session()->invalidate();

        $request->session()->regenerateToken();

        if ($response = $this->loggedOut($request)) {
            return $response;
        }

        return $request->wantsJson()
            ? new Response('', 204)
            : redirect('/');
    }

    /**
     * The user has logged out of the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return mixed
     */
    protected function loggedOut(Request $request)
    {
        //
    }

    public function username() {
        return $this->username->username();
    }

    /**
     * Get the guard to be used during authentication.
     *
     * @return \Illuminate\Contracts\Auth\StatefulGuard
     */
    protected function guard()
    {
        return Auth::guard();
    }
}

And LoginRequest

<?php

namespace App\Http\Requests;

use App\Http\Controllers\Auth\LoginController;
use Illuminate\Foundation\Http\FormRequest;

class LoginRequest extends FormRequest
{

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validator instance for the request.
     *
     * @return \Illuminate\Validation\Validator
     */
    protected function getValidatorInstance()
    {
        $factory = $this->container->make('Illuminate\Validation\Factory');

        if (method_exists($this, 'validator'))
        {
            return $this->container->call([$this, 'validator'], compact('factory'));
        }
        return $factory->make(
            $this->json()->all(), $this->container->call([$this, 'rules']), $this->messages(), $this->attributes()
        );
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            $this->username() => 'required|string',
            'uPassword' => 'required|string',
        ];
    }

    /**
     * @return string
     */
    public function username() {
        return 'uLogin';
    }
}

Thank you in advance!

0 likes
7 replies
RoffDaniel's avatar

@thewebartisan7 Unfortunately, this is not quite the case. When I fill in all the fields incorrectly, the page reloads to display a message that the data is incorrect. I try to make everything through js

thewebartisan7's avatar

I think you didn't install it correctly, the validation is not even on submit but on focusout first time, then on key press.

Be sure that you are using the package custom validation, see https://github.com/proengsoft/laravel-jsvalidation/tree/master/public/js

And here are the views that show validation in case you need to change: https://github.com/proengsoft/laravel-jsvalidation/tree/master/resources/views

This is the only things you need in view:

<form>
    <!-- ... My form stuff ... -->
</form>

<!-- Javascript Requirements -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>

<!-- Laravel Javascript Validation -->
<script type="text/javascript" src="{{ asset('vendor/jsvalidation/js/jsvalidation.js')}}"></script>

{!! JsValidator::formRequest('App\Http\Requests\LoginRequest') !!}
1 like
RoffDaniel's avatar

@thewebartisan7 I'm sorry, but I'm not sure what You're talking about. I'm trying to use validation for absolutely all errors and non-errors, that is, via AJAX. But I still can't output errors under fields using the "jQuery Validation" plugin...

$(document).ready(function () {
    Dashmix.helpers("validation")
    $(".js-validation-signin").validate({
        submitHandler: function (form) {
            let formData = {
                _token: $('input[name="_token"]').attr('value'),
                uLogin: $('#uLogin').val(),
                uPassword: $('#uPassword').val(),
            };

            $.ajax({
                type: 'POST',
                url: '{{ route('xid-login') }}',
                data: formData,
                success: function (data) {
                    console.log('ENTER');
                },
                error: function (data) {
                    let error = JSON.parse(data.responseText).errors;

                    //....
                }
            });
        }
    });
});
thewebartisan7's avatar
Level 14

If you install that package jsvalidation for Laravel, and then in your view you add:


{!! JsValidator::formRequest('App\Http\Requests\LoginRequest') !!}

This will generate the JS code for validation and via ajax. That is all.

I suppose you are not trying to validate only login, so this package will help you.

I also don't think that make sense to validate login via ajax just for check two rules if is required, you can do that client side. Ajax validation make sense when you need to check for example in registration if email already exist in database. With package that I suggest, you can do that easily.

If you don't want to use this package, and write JS code alone, then check this: https://laracasts.com/discuss/channels/javascript/validate-form-served-via-ajax-call-using-jquery-validation

Seem there is what are you trying to do.

But again, make ajax validation in login for rule require and string doesn't make sense.

1 like
Phread's avatar

If you want to perform the Validation on the Client Side with NO communications to the Server, you could do the following ( I do not recommend that this be used for Login/Register/Forgot-Password ).

 <form action="{{route($formAction)}}" method="POST" enctype="multipart/form-data" name="myform"
        onsubmit="return validateform()" >

And the JavaScript Validation could be something like the following:

<script>
	// \
	// This Validation is used to verify that the required fields have been entered and/or the length is
	// correct.
	// /
    function validateform(){
	// \
	// Get the values from the fields being dealt with for this form.
	// /
        var name=document.myform.accountName.value;
        var acctnbr=document.myform.AcctNbr.value;
        var bankname=document.myform.bankName.value;
        var thelen = document.myform.routingNbr.value.length;
        var thecount=0;
        var thealert="";
        var btnval = "";

	// \
	// Verify that the account name has been entered.
	// /
        if (name==null || name==""){
            thecount = thecount + 1;
            thealert = thealert.concat(thecount, ") Account's Name cannot be blank");
        }
	// \
	// Verify that the Bank Name has been entered.
	// /
        if(bankname==null || bankname==""){
            thecount = thecount + 1;
            if (thecount > 1){
                thealert = thealert.concat("<br>");
            }
            thealert = thealert.concat(thecount, ") Bank's Name cannot be blank");
        }
	// \
	// Verify that the Account # has been entered.
	// /
        if(acctnbr==null || acctnbr==""){
            thecount = thecount + 1;
            if (thecount > 1){
                thealert = thealert.concat("<br>");
            }
            thealert = thealert.concat(thecount, ") Account Number cannot be blank");
        }
	// \
	// Verify that the Routing # is 9 numbers if anything has been entered..
	// Note: 
	//	1) We do NOT need to verify if the User has entered more than 9
	// 	     digits as the field is set to accept 9 or less numbers.
	//	2) We do not need to verify if the User entered any non-number characters as
	//	     the field is set to only accept numbers.
	// /
        if(thelen > 0 && thelen < 9 ){
            thecount = thecount + 1;
            if (thecount > 1){
                thealert = thealert.concat("<br>");
            }
            thealert = thealert.concat(thecount, ") The Routing #, if any, must be 9 characters");
        }
	// \
	// Determine if 1 or more error have been found.  If 1 error that use singular, otherwise use plural.
	// /
        if (thecount > 1){
            btnval = 'Issues needing Correction';
        } else {
            btnval = 'Issue needing Correction';
        }
	// \
	// Display the errors, if any and return "FALSE" as this script failed.
	// /
        if(thecount > 0) {
            Swal.fire({
                showCloseButton: true,
                confirmButtonText: btnval,
                footer: thealert,
                confirmButtonColor: '#d33',
                backdrop: `rgba(77, 0, 0, .35)`
            });
            return false;

        }
	// \
	// No errors exist.  Nice Job!
	// Set the Password fields to be of type "Text".  This alleviates the Browser asking the User if they want to 
	// save the password.  
	// /
        if (thecount==0) {
            safeVerbalPassword.type = "text";
            unsafeVerbalPassword.type = "text";
            loginUsername.type = "text";
            loginPwd.type = "text";
        }
    }
</script>
1 like

Please or to participate in this conversation.