اكتشف إطار PHP Laravel


الدرس: Ajax


الصفحة السابقة
Ajax هي تقنية Javascript شائعة الاستخدام تتيح لك إرسال الطلبات إلى الخادم وتلقي الردود دون إعادة تحميل الصفحة. إنه بهذه الطريقة من الممكن تعديل DOM بشكل حيوي ، وبالتالي جزء من الصفحة.
في هذا الفصل سوف نرى كيفية تنفيذ Ajax مع Laravel . سنبدأ من تثبيت Laravel جديد ونعد المصادقة المخططة مع Artisan . سنقوم بعد ذلك بتعديله لاستخدام Ajax لتسجيل المستخدم. لإضافة اهتمام إلى المثال ، سنضع النموذج في صفحة مشروطة.
لذلك قم بتثبيت جديد ثم استخدم أمر Artisan :

php artisan make:auth
أيضا إنشاء قاعدة بيانات وتنفيذ الترحيل.
تحقق من أن كل شيء يعمل بشكل صحيح. ثم سنقوم بتغيير الكود قليلاً ...

العرض


القالب
في القالب التلقائي ( resources/views/layouts/app.blade.php) سنقوم بإجراء تعديلين. إليك الكود الناتج:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel</title>

    <!-- Fonts -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css" rel='stylesheet' type='text/css'>
    <link href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700" rel='stylesheet' type='text/css'>

    <!-- Styles -->
    { {-- <link href="{ { elixir('css/app.css') }}" rel="stylesheet"> --}}
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">

    <style>
        body {
            font-family: 'Lato';
        }

        .fa-btn {
            margin-right: 6px;
        }
    </style>
</head>
<body id="app-layout">
    <nav class="navbar navbar-default">
        <div class="container">
            <div class="navbar-header">

                <!-- Collapsed Hamburger -->
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#spark-navbar-collapse">
                    <span class="sr-only">Toggle Navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>

                <!-- Branding Image -->
                <a class="navbar-brand" href="{ { url('/') }}">
                    Laravel
                </a>
            </div>

            <div class="collapse navbar-collapse" id="spark-navbar-collapse">
                <!-- Left Side Of Navbar -->
                <ul class="nav navbar-nav">
                    <li><a href="{ { url('/') }}">Home</a></li>
                </ul>

                <!-- Right Side Of Navbar -->
                <ul class="nav navbar-nav navbar-right">
                    <!-- Authentication Links -->
                    @if (Auth::guest())
                        <li><a href="{ { url('/login') }}">Login</a></li>
                    @else
                        <li class="dropdown">
                            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
                                { { Auth::user()->name }} <span class="caret"></span>
                            </a>

                            <ul class="dropdown-menu" role="menu">
                                <li><a href="{ { url('/logout') }}"><i class="fa fa-btn fa-sign-out"></i>Logout</a></li>
                            </ul>
                        </li>
                    @endif
                </ul>
            </div>
        </div>
    </nav>

    @yield('content')

    <!-- JavaScripts -->
    { {-- <script src="{ { elixir('js/app.js') }}"></script> --}}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

    @yield('scripts')

</body>
</html>
التعديلان هما:
  • حذف الكود الخاص بخيار "Register" في القائمة ، نحتفظ فقط بـ ""Login :
    
    @if (Auth::guest())
        <li><a href="{ { url('/login') }}">Login</a></li>
    @else
    
  • قسم جديد لإدراج برنامج نصي:
    
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    
    @yield('scripts')
    
    وبالتالي سيكون لشريط القائمة هذا المظهر عند عدم مصادقة أي شخص:
framework Laravel MVC
شريط القوائم بدون Register""
عرض تسجيل الدخول
هذا هو العرض (resources/views/auth/login.blade.php ) الذي سيخضع لمعظم التغييرات. فيما يلي كود طريقة العرض هذه:

@extends('layouts.app')

@section('content')

<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
        
            <div class="alert alert-success alert-dismissible hidden">
                You are now registered, you can login.
            </div>

            <div class="panel panel-default">
                <div class="panel-heading">Login</div>
                <div class="panel-body">
                    <form class="form-horizontal" role="form" method="POST" action="{ { url('/login') }}">
                        {!! csrf_field() !!}

                        <div class="form-group{ { $errors->has('email') ? ' has-error' : '' }}">
                            <label class="col-md-4 control-label">E-Mail Address</label>

                            <div class="col-md-6">
                                <input type="email" class="form-control" name="email" value="{ { old('email') }}">

                                @if ($errors->has('email'))
                                    <span class="help-block">
                                        <strong>{ { $errors->first('email') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group{ { $errors->has('password') ? ' has-error' : '' }}">
                            <label class="col-md-4 control-label">Password</label>

                            <div class="col-md-6">
                                <input type="password" class="form-control" name="password">

                                @if ($errors->has('password'))
                                    <span class="help-block">
                                        <strong>{ { $errors->first('password') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <div class="checkbox">
                                    <label>
                                        <input type="checkbox" name="remember"> Remember Me
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    <i class="fa fa-btn fa-sign-in"></i>Login
                                </button>

                                <a class="btn btn-link" id="register" href="#">Register</a>
                                <a class="btn btn-link" href="{ { url('/password/reset') }}">Forgot Your Password?</a>

                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                <h4 class="modal-title" id="myModalLabel">Register</h4>
            </div>
            <div class="modal-body">

                <form id="formRegister" class="form-horizontal" role="form" method="POST" action="{ { url('/register') }}">
                    {!! csrf_field() !!}

                    <div class="form-group">
                        <label class="col-md-4 control-label">Name</label>
                        <div class="col-md-6">
                            <input type="text" class="form-control" name="name">
                            <small class="help-block"></small>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label">E-Mail Address</label>
                        <div class="col-md-6">
                            <input type="email" class="form-control" name="email">
                            <small class="help-block"></small>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label">Password</label>
                        <div class="col-md-6">
                            <input type="password" class="form-control" name="password">
                            <small class="help-block"></small>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label">Confirm Password</label>
                        <div class="col-md-6">
                            <input type="password" class="form-control" name="password_confirmation">
                        </div>
                    </div>

                    <div class="form-group">
                        <div class="col-md-6 col-md-offset-4">
                            <button type="submit" class="btn btn-primary">
                                Register
                            </button>
                        </div>
                    </div>
                </form>                       

            </div>
        </div>
    </div>
</div>

@endsection

@section('scripts')

<script>

$(function(){

    $('#register').click(function() {
        $('#myModal').modal();
    });

    $(document).on('submit', '#formRegister', function(e) {  
        e.preventDefault();
         
        $('input+small').text('');
        $('input').parent().removeClass('has-error');
         
        $.ajax({
            method: $(this).attr('method'),
            url: $(this).attr('action'),
            data: $(this).serialize(),
            dataType: "json"
        })
        .done(function(data) {
            $('.alert-success').removeClass('hidden');
            $('#myModal').modal('hide');
        })
        .fail(function(data) {
            $.each(data.responseJSON, function (key, value) {
                var input = '#formRegister input[name=' + key + ']';
                $(input + '+small').text(value);
                $(input).parent().addClass('has-error');
            });
        });
    });

})

</script>

@endsection
لنرى التغييرات
  • إضافة شريط معلومات مخفي تلقائيا (hidden):
    
    <div class="alert alert-success alert-dismissible hidden">
        You are now registered, you can login.
    </div>
    
    سيكون لها هذا الجانب:
    framework Laravel MVC
    شريط المعلومات
  • إضافة رابط للتسجيل:
    
    <a class="btn btn-link" id="register" href="#">Register</a>
    <a class="btn btn-link" href="https://www.arabclassroom.com/password/reset">Forgot Your Password?</a>
    

    لذلك لدينا رابط جديد للتسجيل في هذا النموذج: framework Laravel MVC
    رابط للتسجيل
  • إضافة كود صفحة الوسائط التي تستضيف النموذج:
    
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                    <h4 class="modal-title" id="myModalLabel">Register</h4>
                </div>
                <div class="modal-body">
    
                    <form id="formRegister" class="form-horizontal" role="form" method="POST" action="{ { url('/register') }}">
                        {!! csrf_field() !!}
    
                        <div class="form-group">
                            <label class="col-md-4 control-label">Name</label>
                            <div class="col-md-6">
                                <input type="text" class="form-control" name="name">
                                <small class="help-block"></small>
                            </div>
                        </div>
    
                        <div class="form-group">
                            <label class="col-md-4 control-label">E-Mail Address</label>
                            <div class="col-md-6">
                                <input type="email" class="form-control" name="email">
                                <small class="help-block"></small>
                            </div>
                        </div>
    
                        <div class="form-group">
                            <label class="col-md-4 control-label">Password</label>
                            <div class="col-md-6">
                                <input type="password" class="form-control" name="password">
                                <small class="help-block"></small>
                            </div>
                        </div>
    
                        <div class="form-group">
                            <label class="col-md-4 control-label">Confirm Password</label>
                            <div class="col-md-6">
                                <input type="password" class="form-control" name="password_confirmation">
                            </div>
                        </div>
    
                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Register
                                </button>
                            </div>
                        </div>
                    </form>                       
    
                </div>
            </div>
        </div>
    </div>
    
    انها الترميز الكلاسيكي مع Bootstrap . لاحظ لكل عنصر تحكم في النموذج الجزء الذي سيتم استخدامه للعرض المحتمل لأخطاء التحقق من الصحة:
    
    <small class="help-block"></small>
    
    سيكون لدينا هذا الجانب لهذه النافذة المشروطة: framework Laravel MVC
    نافذة التسجيل مشروط
  • تمت إضافة كود JavaScript لإدارة نموذج التسجيل:
    
    $(function(){
    
        $('#register').click(function() {
            $('#myModal').modal();
        });
    
        $(document).on('submit', '#formRegister', function(e) {  
            e.preventDefault();
             
            $('input+small').text('');
            $('input').parent().removeClass('has-error');
             
            $.ajax({
                method: $(this).attr('method'),
                url: $(this).attr('action'),
                data: $(this).serialize(),
                dataType: "json"
            })
            .done(function(data) {
                $('.alert-success').removeClass('hidden');
                $('#myModal').modal('hide');
            })
            .fail(function(data) {
                $.each(data.responseJSON, function (key, value) {
                    var input = '#formRegister input[name=' + key + ']';
                    $(input + '+small').text(value);
                    $(input).parent().addClass('has-error');
                });
            });
        });
    
    })
    
JavaScript
سنلقي نظرة فاحصة على جزء جافا سكريبت ...
عند تقديم النموذج ، يجب عليك تجنب وجود الارسال العادي:

e.preventDefault();
ثم نحذف كل آثار الخطأ السابقة:

$('input+small').text('');
$('input').parent().removeClass('has-error');
يجب عليك بعد ذلك إرسال الطلب باستخدام القيم المدخلة ، لتبسيط حياتك بالتسلسل:

$.ajax({
    method: $(this).attr('method'),
    url: $(this).attr('action'),
    data: $(this).serialize(),
    dataType: "json"
})
إذا كان التحقق من الصحة صحيحًا ، يجب عليك عرض شريط المعلومات وإخفاء نافذة الوسائط:

.done(function(data) {
    $('.alert-success').removeClass('hidden');
    $('#myModal').modal('hide');
})
في حالة وجود خطأ في عملية التحقق ، نقوم بمسح الأخطاء ونقوم بإعداد النمط:

.fail(function(data) {
    $.each(data.responseJSON, function (key, value) {
        var input = '#formRegister input[name=' + key + ']';
        $(input + '+small').text(value);
        $(input).parent().addClass('has-error');
    });
});
على سبيل المثال ، إذا لم تقم بملء عنصر تحكم الاسم:
framework Laravel MVC
الاسم غير موجود

المعالجة


وحدة التحكم
هنا هو وحدة تحكم جديدة app/Http/Controllers/Auth/AuthController  :

<?php

namespace App\Http\Controllers\Auth;

use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;

class AuthController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Registration & Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users, as well as the
    | authentication of existing users. By default, this controller uses
    | a simple trait to add these behaviors. Why don't you explore it?
    |
    */

    use AuthenticatesAndRegistersUsers, ThrottlesLogins;

    /**
     * Where to redirect users after login / registration.
     *
     * @var  string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new authentication controller instance.
     *
     * @return  void
     */
    public function __construct()
    {
        $this->middleware('guest', ['except' => 'logout']);
        $this->middleware('ajax', ['only' => 'register']);
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param    array  $data
     * @return  \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|confirmed|min:6',
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param    array  $data
     * @return  User
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
    }


    /**
     * Handle a registration request for the application.
     *
     * @param    \Illuminate\Http\Request  $request
     * @return  \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $validator = $this->validator($request->all());

        if ($validator->fails()) {
            $this->throwValidationException(
                $request, $validator
            );
        }

        $this->create($request->all());
 
        return response()->json();
    }

}
توجد الطريقة register عادة في الخط. لكننا نحتاج إلى تعديل الكود الذي نفرط في تحميله على هذه الطريقة في وحدة التحكم. الاختلافات الوحيدة معكود الخط هي:
  • لا يوجد مصادقة فورية عند التسجيل ،
  • استجابة JSON .
الوسيطة
يمكننا أيضًا أن نلاحظ في وحدة التحكم وجود وسيط جديد  ajax  :

<?php
$this->middleware('ajax', ['only' => 'register']);
في الواقع ، نريد أن register تكون طريقتنا قابلة للوصول فقط إذا تلقينا طلبًا من Ajax . هذه الوسيطة غير موجودة بشكل تلقائي في Laravel ، لذلك يجب عليك إنشاؤها ( app/Http/Middlewares/Ajax.php) :

<?php

namespace App\Http\Middleware;

use Closure;

class Ajax
{

    public function handle($request, Closure $next)
    {
        if ($request->ajax())
        {
            return $next($request);         
        }

        abort(404);
    }

}
Ajax يتيح لنا طريقة الطلب بسهولة معرفة ما إذا كان طلبًا من هذا النوع ، وإذا لم يكن الأمر كذلك ، فنرى خطأ 404. يجب إبلاغ Laravel بوجود الوسيطة لدينا ( app/Http/Kernel.php) :

<?php
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'ajax' => \App\Http\Middleware\Ajax::class,
];

في الخلاصة


  • Ajax سهل التنفيذ مع Laravel .
  • يتم استخدام التسلسل لتنسيق الإدخالات في النموذج.
  • يمكننا توفير برنامج وسيط محدد لطلبات Ajax .