samedi 22 décembre 2018

Used AJAX to make my admin panel more SPA like, however, I'm not sure if I did it efficiently. I had to create a couple of extra routes and views

I realized that my admin panel was getting cluttered with information so I decided to split that information into different views and then load the different views into a div on button clicks. Even though I finished the functionality and it works, I feel like I butchered it with too much extra code/views/routes. This is why I'm interested in knowing if anything looks eye-poppingly bad.

I'm gonna use pseudo code for some parts so I don't misdirect your attention.

For starters, this is the original admin page from where everything begins:

@extends('layouts.app')
@section('content')
<div class="admin-tabs">
        <p class='admin-tab' data-tab='categories'>Categories</p>
        <p class='admin-tab' data-tab='users'>Users</p>
</div>
<div class="admin-container">
       Code that displays categories and allows me to delete them
</div>
    <script>
    var token = '';
    var adminTab = '';
</script>

@endsection

When the admin clicks one of the <p> elements, the code in .admin-container gets replaced with a code from a view thanks to this AJAX call:

$('.admin-tab').on('click', function(){
    var tab = $(this).data('tab');

    $.ajax({
        type: 'POST',
        url : adminTab,
        data: {
            tab: tab
        },
        headers: {
            'X-CSRF-TOKEN': token
        },
        success : function (data) {
            $(".admin-container").html(data);
            history.replaceState(null, null, '/admin/' + tab);
        }
    });
});

Using the data from the clicked <p> element, I determine which view should I display in my AjaxController:

public function adminTab(Request $request){
    $tab = $request['tab'];

    if ($tab == 'categories') {
        $categories = Category::orderBy('created_at', 'desc')->get();
        return view('partials/adminCategoriesTab', ['categories' => $categories]);
    } else {
        $users = User::orderBy('created_at', 'desc')->get();
        return view('partials/adminUsersTab', ['users' => $users]);
    }

}

And the used routes are:

    Route::get('/admin/categories', 'pagesController@admin')->name('admin');
    Route::get('/admin/users', 'pagesController@adminUsers')->name('adminUsers');
    Route::post('/admin/categories', 'AjaxController@adminTab')->name('adminTab');

The first 2 routes are used to directly display the views if the user accesses their URLs directly, and the third route is the post used for the AJAX request which only changes part of the first 2 route pages.

So far I am using 4 views:

partials/adminCategoriesTab.blade.php
partials/adminUsersTab.blade.php
admin.blade.php
adminUsers.blade.php

The partials are only used on the AJAX call so that specific code can be inserted into .admin-container, whereas admin.blade.php and adminUsers.blade.php are views presented on GET request to their specific URLs.

The partials contain stuff like:

<form action="" method="POST" enctype="multipart/form-data">

    <div class="form-group">
        <label class='label required' for="categoryName">Category Name</label>
        <input class='input' type="text" name="categoryName" placeholder="Category Name" value=''>
        @include('partials.invalid', ['field' => 'categoryName'])
    </div>

    <div class="form-group">
        <div class="upload-btn-wrapper">
            <button class="btn">Drop files here or click to upload</button>
            <input class='upload-input' type="file" name='categoryImage'>
            @include('partials.invalid', ['field' => 'categoryImage'])
        </div>
    </div>

    
    <button class='submit-btn' type="submit" name="submit">Upload</button>

</form>

Or:

@if(!empty($users) && count($users) > 0)
    @foreach($users as $user)
        <p></p>
    @endforeach
@endif

BUT admin.blade.php contains the whole page:

@extends('layouts.app')
@section('content')

    <div class="wrapper">
            <div class="admin-tabs">
                <p class='admin-tab' data-tab='categories'>Categories</p>
                <p class='admin-tab' data-tab='users'>Users</p>
            </div>
            <div class="admin-container">
                <form action="" method="POST" enctype="multipart/form-data">

                    <div class="form-group">
                        <label class='label required' for="categoryName">Category Name</label>
                        <input class='input' type="text" name="categoryName" placeholder="Category Name" value=''>
                        @include('partials.invalid', ['field' => 'categoryName'])
                    </div>

                    <div class="form-group">
                        <div class="upload-btn-wrapper">
                            <button class="btn">Drop files here or click to upload</button>
                            <input class='upload-input' type="file" name='categoryImage'>
                            @include('partials.invalid', ['field' => 'categoryImage'])
                        </div>
                    </div>

                    
                    <button class='submit-btn' type="submit" name="submit">Upload</button>

                </form>

                @if(!empty($categories) && count($categories) > 0)
                    <form method="POST" action="">
                    @foreach($categories as $category)
                        <div class="categories-flexbox">
                            <img class='profile-picture' src='' alt='Random image' />
                            <p></p>
                            <input type="checkbox" name="categories[]" value="">
                            <input type="hidden" name="categoryFiles[]" value="">
                        </div>
                    @endforeach
                    <button class='delete-btn' type="submit">Delete</button>
                    
                    
                    </form>
                @endif
            </div>
    </div>

    <script>
        var token = '';
        var adminTab = '';
    </script>

@endsection

I'm really curious if I have done this anything close to a conventional way of doing it and if there is anything that could be shortened or made better looking with less code. Thanks for reading, I appreciate it.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire