Laravel ile sınırsız kategori ve alt kategori yapalım

regex Takip Et

1 ay önce , Okuma süresi 5 dakika.

Bu yazımızda Laravel ile sınırsız kategori ve alt kategori yani hiyerarşik kategori ağacı üzerinde bir çalışma yapacağız.
Laravel ile sınırsız kategori ve alt kategori yapalım

Öncelikle yazıya başlamadan önce diğer yayınlarım için takip etmeyi unutmayın!

Hazırsak başlayalım; 
Öncelikle terminalden bir veritabanı tablosu oluşturalım; Tablomuz "category" olsun. 

php artisan make:migration create_category_table

Burada yaptığımız işlem neticesinde “app/database/migrations” dosyası oluşturulduğunu ve içerisinde modelleme yapıldığını göreceksiniz. 

Bu dosyayı açtığımızda ise ; 

<?php

use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

class CreateCategoryTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('category', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('category');
    }
}
?>

Bu kodu değiştireceğiz ve son çıktı aşağıdaki gibi görünecek.

<?php

use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

class CreateCategoryTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->integer('parent_id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('categories');
    }
}
?>

Şimdi veritabanı dosyamızı güncelledik sırada php için tabloyu oluşturmaya geldi.
Terminalden aşağıdaki satırı çalıştıralım; 

php artisan migrate

Bu , veritabanında “ categories ” tablo adını oluşturur .

Şimdi Model dosyamızı oluşturalım. 
Terminalden aşağıdaki komutu girerek çalıştralım. 

php artisan make:model Category

Bu bize “app/Category.php” şeklinde bir model dosyası oluşturacaktır. Dosyamızı açtığımızda ise şu şekilde görünmesi gerekiyor. 

<?php
namespace App;
use IlluminateDatabaseEloquentModel;
class Category extends Model
{
    //
}

Şimdi bu dosyayı aşağıdaki kodla aynı şekilde güncelleyin.

<?php

namespace App;

use IlluminateDatabaseEloquentModel;

class Category extends Model
{
      public $fillable = ['title','parent_id'];

    /**

     * Get the index name for the model.

     *

     * @return string

     */

    public function childs() {

        return $this->hasMany('AppCategory','parent_id','id') ;

    }
}

Şimdi Route tanımlayalım. “routes/web.php“. dosyamızı açalım ve aşağıdaki iki yolu tanımlayalım. 

Route::get('category-tree-view','[email protected]')->name('category-tree-view');
Route::post('add-category','[email protected]')->name('add.category');

Evet buraya kadar sorunsuz geldik. Bu aşamaya kadar;
1-) Veritabanı tablomuzu oluşturup isteğimiz doğrultuda güncelledik.
2-) Model oluşturduk ve değerleri tanımladık. 
3-) Route ile yollarımız tanımladık. 

Şimdi Controller yapımızı oluşturalım. Bunun için hemen terminal alanımızdan aşağıdaki komutu çalıştırıyoruz. 

php artisan make:controller CategoryController

Bu bize “app/Http/Controllers” dizini altında CategoryController.php dosyası oluşturacak. 
Dosyamızı açtığımızda aşağıdaki gibi görünecektir  

<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;

class CategoryController extends Controller
{
    //
}

Bu dosyamızı aşağıdaki gibi güncelliyoruz. 

<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;
use AppHttpRequests;
use AppCategory;

class CategoryController extends Controller
{
    /**
     * Show the application dashboard.
     *
     * @return IlluminateHttpResponse
     */

    public function manageCategory()
    {
        $categories = Category::where('parent_id', '=', 0)->get();

        $allCategories = Category::all();

        return view('category.categoryTreeview',compact('categories','allCategories'));
    }


    /**
     * Show the application dashboard.
     *
     * @return IlluminateHttpResponse
     */

    public function addCategory(Request $request)
    {
        $this->validate($request, [
            'title' => 'required',
        ]);

        $input = $request->all();
        $input['parent_id'] = empty($input['parent_id']) ? 0 : $input['parent_id'];

        Category::create($input);
        return back()->with('success', 'New Category added successfully.');

    }
}

Şimdi View zamanı....

Şimdi bir görünüm dosyası oluşturacağız, bu yüzden “app/resources/view” dizini altında  bir category klasörü oluşturalım.

Bu klasörün içerisinde “categoryTreeview.blade.php” and “manageChild.blade.php” şeklinde iki adet dosyamızı oluşturuyoruz. 

categoryTreeview.blade.php

<!DOCTYPE html>

<html>

<head>

    <title>Laravel Unlimited Hierarchical Category Tree View Example</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" />

    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css" rel="stylesheet">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

    <link href="{{ asset('css/treeview.css') }}" rel="stylesheet">

</head>

<body>

<div class="container">

    <div class="panel panel-primary">

        <div class="panel-heading">Unlimited Hierarchical Category Tree View</div>

        <div class="panel-body">

            <div class="row">

                <div class="col-md-6">

                    <h3>Category List</h3>

                    <ul id="tree1">

                        @foreach($categories as $category)

                            <li>

                                {{ $category->title }}

                                @if(count($category->childs))

                                    @include('category.manageChild',['childs' => $category->childs])

                                @endif

                            </li>

                        @endforeach

                    </ul>

                </div>

                <div class="col-md-6">

                    <h3>Add New Category</h3>

                    <form role="form" id="category" method="POST" action="{{ route('add.category') }}" enctype="multipart/form-data">
                    @csrf

                    <div class="form-group {{ $errors->has('title') ? 'has-error' : '' }}">

                        <label>Title:</label>

                        <input type="text" id="title" name="title" value="" class="form-control" placeholder="Enter Title">
                        @if ($errors->has('title'))
                            <span class="text-red" role="alert">
                                <strong>{{ $errors->first('title') }}</strong>
                            </span>
                        @endif

                    </div>


                    <div class="form-group {{ $errors->has('parent_id') ? 'has-error' : '' }}">

                        <label>Category:</label>
                        <select id="parent_id" name="parent_id" class="form-control">
                            <option value="0">Select</option>
                            @foreach($allCategories as $rows)
                                    <option value="{{ $rows->id }}">{{ $rows->title }}</option>
                            @endforeach
                        </select>

                        @if ($errors->has('parent_id'))
                            <span class="text-red" role="alert">
                                <strong>{{ $errors->first('parent_id') }}</strong>
                            </span>
                        @endif

                    </div>


                    <div class="form-group">

                        <button type="submit" class="btn btn-success">Add New</button>

                    </div>


                    </form>


                </div>

            </div>




        </div>

    </div>

</div>

<script src="{{ asset('js/treeview.js') }}"></script>

</body>

</html>

manageChild.blade.php

<ul>

    @foreach($childs as $child)

        <li>

            {{ $child->title }}

            @if(count($child->childs))

                @include('category.manageChild',['childs' => $child->childs])

            @endif

        </li>

    @endforeach

</ul>

Şimdi CSS ve JS Dosyalırımızı oluşturalım. 

Aşağıdaki css dosyasını  “public/css” ,  js dosyasını ise  “public/js” içine oluşturalım. 

treeview.css

 

.tree, .tree ul {

    margin:0;

    padding:0;

    list-style:none

}

.panel-primary > .panel-heading {
    color: #fff;
    background-color: #606ec3;
    border-color: #606ec3;
}

.panel-primary {

    border-color: #606ec3;
    margin: 3%;

}
.tree ul {

    margin-left:1em;

    position:relative

}

.tree ul ul {

    margin-left:.5em

}

.tree ul:before {

    content:"";

    display:block;

    width:0;

    position:absolute;

    top:0;

    bottom:0;

    left:0;

    border-left:1px solid

}

.tree li {

    margin:0;

    padding:0 1em;

    line-height:2em;

    color:#369;

    font-weight:700;

    position:relative

}

.tree ul li:before {

    content:"";

    display:block;

    width:10px;

    height:0;

    border-top:1px solid;

    margin-top:-1px;

    position:absolute;

    top:1em;

    left:0

}

.tree ul li:last-child:before {

    background:#fff;

    height:auto;

    top:1em;

    bottom:0

}

.indicator {

    margin-right:5px;

}

.tree li a {

    text-decoration: none;

    color:#369;

}

.tree li button, .tree li button:active, .tree li button:focus {

    text-decoration: none;

    color:#369;

    border:none;

    background:transparent;

    margin:0px 0px 0px 0px;

    padding:0px 0px 0px 0px;

    outline: 0;

}

treeview.js

 

$.fn.extend({
    treed: function (o) {

        var openedClass = 'glyphicon-minus-sign';
        var closedClass = 'glyphicon-plus-sign';

        if (typeof o != 'undefined'){
            if (typeof o.openedClass != 'undefined'){
                openedClass = o.openedClass;
            }
            if (typeof o.closedClass != 'undefined'){
                closedClass = o.closedClass;
            }
        };

        //initialize each of the top levels
        var tree = $(this);
        tree.addClass("tree");
        tree.find('li').has("ul").each(function () {
            var branch = $(this); //li with children ul
            branch.prepend("<i class='indicator glyphicon " + closedClass + "'></i>");
            branch.addClass('branch');
            branch.on('click', function (e) {
                if (this == e.target) {
                    var icon = $(this).children('i:first');
                    icon.toggleClass(openedClass + " " + closedClass);
                    $(this).children().children().toggle();
                }
            })
            branch.children().children().toggle();
        });
        //fire event from the dynamically added icon
        tree.find('.branch .indicator').each(function(){
            $(this).on('click', function () {
                $(this).closest('li').click();
            });
        });
        //fire event to open branch if the li contains an anchor instead of text
        tree.find('.branch>a').each(function () {
            $(this).on('click', function (e) {
                $(this).closest('li').click();
                e.preventDefault();
            });
        });
        //fire event to open branch if the li contains a button instead of text
        tree.find('.branch>button').each(function () {
            $(this).on('click', function (e) {
                $(this).closest('li').click();
                e.preventDefault();
            });
        });
    }
});

//Initialization of treeviews

$('#tree1').treed();

$('#tree2').treed({openedClass:'glyphicon-folder-open', closedClass:'glyphicon-folder-close'});

$('#tree3').treed({openedClass:'glyphicon-chevron-right', closedClass:'glyphicon-chevron-down'});

Neredeyse bitti şimdi artık sitemizin ön izlemesini açalım;  Benim çalışma dizinime göre aşağıdaki linkten ön izlememi açıyorum. 

http://localhost/laravel-hierarchical-category/public/category-tree-view

Kaynak : https://codescompanion.com/laravel-unlimited-hierarchical-category-tree-view/

GitHub : https://github.com/pringal/laravel-unlimited-hierarchical-category-tree-view

#php #Laravel