Skip to content

Add modal

leantony edited this page Apr 7, 2018 · 10 revisions

The grid comes with support for bootstrap's modal component. Please check the pre-requisites section to know what to include for this to work. But including the required assets alone is not enough. Assuming you have all the requirements ready, this are the steps you will follow to render a modal on your page, when you click the 'create' button.

For this steps, we will be assuming you want a modal displayed when you click on the 'create' button, so that you get a form that will help you create a user. This of course also assumes you already have a grid generated already.

You also need to have published the grid's assets. If you haven't done that already, run the command php artisan vendor:publish --provider="Leantony\Grid\Providers\ServiceProvider"

Include the grid's javascript asset on your page

Add this to your layout. Just some basic setup.

<head>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    // .. other stuff
</head>
// .. layout code

// .. other javascript assets, e.g Jquery, bootstrap, Pjax, etc
<script src="{{ asset('vendor/leantony/grid/js/grid.js') }}"></script>
<script>
    // ensure the CSRF header is sent in an AJAX request.
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
</script>
@stack('grid_js')

The @stack('grid_js') will ensure that the javascript for any grid you create is automatically injected on the page.

Add the modal container to your page

This is a simple laravel view that comes with the grid installation. It will serve as an injection point for the modal HTML. Ideally, this view should be included on your layout.

// .. layout code
<div class="container">
    @yield('content')
</div>
@include('leantony::modal.container')
// .. layout code

Create the modal view

This is identical to creating any laravel view. You may copy the sample included with the package, and this can be found once you publish the resources for the package. The copy can be found at resources/views/vendor/leantony/modal/form-sample.blade.php. Feel free to alter it to suit your needs, while avoiding the obvious parts - class names, HTML id's, etc since they are used in javascript.

@if(isset($method))
    {!! BootForm::openHorizontal(['sm' => [4, 8], 'lg' => [2, 10]])->action($route)->class('form-horizontal')->id('modal_form')->data($dataVars ?? [])->$method() !!}
@else
    {!! BootForm::openHorizontal(['sm' => [4, 8], 'lg' => [2, 10]])->action($route)->class('form-horizontal')->id('modal_form')->data($dataVars ?? [])->post() !!}
@endif
<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
    <h4 class="modal-title">{{ ucwords($action . ' '. class_basename($model)) }}</h4>
</div>
<div class="modal-body">
    <div id="modal-notification"></div>
    @if(isset($data))
        {!! BootForm::bind($data) !!}
    @endif
    {!! BootForm::text('Name', 'name') !!}
    {!! BootForm::text('Email', 'email') !!}
    {!! BootForm::password('Password', 'password') !!}
</div>
<div class="modal-footer">
    <button type="button" class="btn btn-default" data-dismiss="modal"><i class="fa fa-times"></i>&nbsp;{{ 'Close' }}
    </button>
    <button type="submit" class="btn btn-success"><i class="fa fa-floppy-o"></i>&nbsp;{{ 'Save' }}</button>
</div>
{!! BootForm::close() !!}

Then name it users_modal.blade.php.

The provided form sample uses bootforms to reduce HTML boilerplate.

Add a controller method to handle fetching of the modal form

This is pretty straightforward. You're only writing code to load the form you've created just above and passing in the variables from the controller.

/**
     * Show the form for creating a new resource.
     *
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws \Throwable
     */
    public function create(Request $request)
    {
        $data = [
            'model' => class_basename(User::class),
            'route' => route('users.store'),
            'action' => 'create',
            'dataVars' => [
                // you'll need this so that the PJAX container(grid) can be refreshed once you create a record
                'pjax-target' => '#' . $request->get('ref')
            ]
        ];
        // modal
        return view('users_modal', $data)->render();
    }

We use render(), so that just the HTML for the form is sent as a string, instead of the layout n etc.

By this point, clicking the grid's create button should be enough to render the modal. However, we also need to have an action to handle the POSTING of data.

Add a controller method to handle posting of the user's data

This should also be pretty straightforward. The major change should be returning json instead of redirecting or rendering a view. Any validation errors will be displayed on the modal itself.

/**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @return JsonResponse|\Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|min:3',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:6'
        ]);
        User::creating(function ($user) {
            $user->password = bcrypt($user->password);
        });
        $user = User::query()->create($request->all());
        return new JsonResponse([
            'success' => true,
            'message' => 'User with id ' . $user->id . ' has been created.'
        ]);
    }

This should be enough. You can then reload your page, and click on the create button on your grid. The modal will be loaded dynamically via AJAX, and it should pop up.

Clone this wiki locally