How to update a multilevel category and subcategory in Laravel – Part3?

/
/
/
1241 Views

In this tutorial of 91 TechSquare, we will learn how to update a multilevel category and subcategory in Laravel. Earlier we have already learned how to create a multilevel category and subcategory in Laravel and how to display a multilevel category and subcategory in Laravel.

We will use the same project with the same database table and model. This article is the enhancement of the previous article, in which we learned about how to display a multilevel category and subcategory in Laravel.

We will implement the functionality to update a multilevel category and subcategory with the below simple steps. Please follow the below steps to accomplish this.

update a multilevel category and subcategory in laravel
update a multilevel category and subcategory in laravel

1. Create a route to update a multilevel category and subcategory in Laravel:

In this step, we will create a route to update the categories. This route will handle the request to update a multilevel category and subcategory.

Route::any('category/edit/{id}', [CategoryController::class, 'editCategory'])->name('editCategory');

We used any request route to update categories. You can create according to your need as well.

We have already created the CategoryController in the previous article to create a multilevel category and subcategory in Laravel. CategoryController already includes at the top of the route file so do not be confused.

2. Create a method to update category:

In this step, we will create a method editCategory() to handle the update category route and render them to view file.

Use the following code into your controller for editCategory route.

use Illuminate\Validation\Rule;
public function editCategory($id, Request $request)
    {
        $category = Category::findOrFail($id);
        if($request->method()=='GET')
        {
            $categories = Category::where('parent_id', null)->where('id', '!=', $category->id)->orderby('name', 'asc')->get();
            return view('edit-category', compact('category', 'categories'));
        }

        if($request->method()=='POST')
        {
            $validator = $request->validate([
                'name'     => 'required',
                'slug' => ['required', Rule::unique('categories')->ignore($category->id)],
                'parent_id'=> 'nullable|numeric'
            ]);
            if($request->name != $category->name || $request->parent_id != $category->parent_id)
            {
                if(isset($request->parent_id))
                {
                    $checkDuplicate = Category::where('name', $request->name)->where('parent_id', $request->parent_id)->first();
                    if($checkDuplicate)
                    {
                        return redirect()->back()->with('error', 'Category already exist in this parent.');
                    }
                }
                else
                {
                    $checkDuplicate = Category::where('name', $request->name)->where('parent_id', null)->first();
                    if($checkDuplicate)
                    {
                        return redirect()->back()->with('error', 'Category already exist with this name.');
                    }
                }
            }

            $category->name = $request->name;
            $category->parent_id = $request->parent_id;
            $category->slug = $request->slug;
            $category->save();
            return redirect()->back()->with('success', 'Category has been updated successfully.');
        }
    }

3. Link URL for update category:

To update multilevel category and subcategory, in this step we will use the URL of the update category inside the file of display categories. To link the URL we will use two files.

  • views/all-category.blade.php
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<section class="content" style="padding:50px 20%;">
    <div class="row">
        <div class="col-md-12">
            <div class="box box-primary">
                <div class="box-header with-border">
                    <a class="add-new" href="{{Route('createCategory')}}">
                        <button class="btn btn-primary btn-xs">Add New Category</button>
                    </a>
                </div>
                <div class="box-body">
                    <table class="table table-bordered table-striped">
                        <thead>
                        <tr>
                            <th>S.No.</th>
                            <th>Category Name</th>
                            <th>Category Slug</th>
                            <th>Parent Category</th>
                            <th>Action</th>
                        </tr>
                        </thead>
                        <tbody>
                        @if(isset($categories))
                            <?php $_SESSION['i'] = 0; ?>
                            @foreach($categories as $category)
                                <?php $_SESSION['i']=$_SESSION['i']+1; ?>
                                <tr>
                                    <?php $dash=''; ?>
                                    <td>{{$_SESSION['i']}}</td>
                                    <td>{{$category->name}}</td>
                                     <td>{{$category->slug}}</td>
                                    <td>
                                        @if(isset($category->parent_id))
                                            {{$category->subcategory->name}}
                                        @else
                                            None
                                        @endif

                                    </td>
                                   <td>                                  
                                        <a href="{{Route('editCategory', $category->id)}}">
                                            <button class="btn btn-sm btn-info">Edit</button>
                                        </a>
                                    </td>
                                </tr>
                            
                                 @if(count($category->subcategory))
                                     @include('sub-category-list',['subcategories' => $category->subcategory])
                                 @endif

                            @endforeach
                            <?php unset($_SESSION['i']); ?>
                        @endif
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</section>
  • views/sub-category-list.blade.php
<?php $dash.='-- '; ?>
@foreach($subcategories as $subcategory)
    <?php $_SESSION['i']=$_SESSION['i']+1; ?>
    <tr>
        <td>{{$_SESSION['i']}}</td>
        <td>{{$dash}}{{$subcategory->name}}</td>
        <td>{{$subcategory->slug}}</td>
        <td>{{$subcategory->parent->name}}</td>
       <td>
            <a href="{{Route('editCategory', $subcategory->id)}}">
                <button class="btn btn-sm btn-info">Edit</button>
            </a>
        </td>
    </tr>
    @if(count($subcategory->subcategory))
        @include('sub-category-list',['subcategories' => $subcategory->subcategory])
    @endif
@endforeach

Now display categories page will be look like this:

update a multilevel category and subcategory in laravel
update a multilevel category and subcategory in laravel

4. Create view for update category route:

To update multilevel category and subcategory, in this step we will create view files. Here we will create two files for the update category, first one is to update the category, and the second one is to display the parent categories dropdown list in hierarchical order:

Create two blade files as following:

  • edit-category.blade.php
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<section class="content" style="padding:50px 30%;">
    <div class="row">
        <div class="col-md-12">
            <div class="box box-primary">
                <div class="box-header with-border">
                    <h3 class="box-title">Edit Category</h3>
                </div>
            
                <form role="form" method="post">
                    {{csrf_field()}}
                    <div class="box-body">
                        <div class="row">
                            <div class="col-sm-6">
                                <div class="form-group">
                                    <label>Category name*</label>
                                    <input type="text" name="name" class="form-control" placeholder="Category name" value="{{$category->name}}" required />
                                </div>
                            </div>

                            <div class="col-sm-6">
                                <div class="form-group">
                                    <label>Category slug*</label>
                                    <input type="text" name="slug" class="form-control" placeholder="Category slug" value="{{$category->slug}}" required />
                                </div>
                            </div>

                            <div class="col-sm-12">
                                <div class="form-group">
                                    <label>Select parent category*</label>
                                    <select type="text" name="parent_id" class="form-control">
                                        <option value="">None</option>
                                        @if($categories)
                                            @foreach($categories as $item)
                                                <?php $dash=''; ?>
                                                <option value="{{$item->id}}" @if($category->parent_id == $item->id ) selected @endif>{{$item->name}}</option>
                                                @if(count($item->subcategory))
                                                    @include('sub-category-list-option-for-update',['subcategories' => $item->subcategory])
                                                @endif
                                            @endforeach
                                        @endif
                                    </select>
                                </div>
                            </div>

                        </div>

                    </div>
                    <div class="box-footer">
                        <button type="submit" class="btn btn-primary">Update</button>

                    </div>

                </form>
                @if ($errors->any())
                    <div>
                        @foreach ($errors->all() as $error)
                            <li class="alert alert-danger">{{ $error }}</li>
                        @endforeach
                    </div>
                @endif
                @if(\Session::has('error'))
                    <div>
                        <li class="alert alert-danger">{!! \Session::get('error') !!}</li>
                    </div>
                @endif
                @if(\Session::has('success'))
                    <div>
                        <li class="alert alert-success">{!! \Session::get('success') !!}</li>
                    </div>
                @endif
            </div>
        </div>
    </div>
</section>
  • sub-category-list-option-for-update.blade.php
<?php $dash.='-- '; ?>
@foreach($subcategories as $subcategory)
    @if($category->id != $subcategory->id )
        <option value="{{$subcategory->id}}" @if($category->parent_id == $subcategory->id ) selected @endif >
        	{{$dash}}{{$subcategory->name}}
        </option>
    @endif
    @if(count($subcategory->subcategory))
        @include('sub-category-list-option-for-update',['subcategories' => $subcategory->subcategory])
    @endif
@endforeach

We used the dash variable to show serial numbers and dashes before the child categories. It is just to get a feel of displaying the list in hierarchical order, so do not get confused.

That’s it, now you can run the project by command php artisan serve, and visit the below route to update a multilevel category and subcategory:

http://127.0.0.1:8000/categories

Hopefully, You got an idea about how to update a multilevel category and subcategory in Laravel using a single table. If you want to know more about this then click on how to delete category and subcategory in Laravel?

4 Comments

    • You can use methods inside form action and You can validate the method in controller accordingly. I have not used all method(only used GET and POST) but just created route. If you need to use all methods then You can use as per your need.

Leave a Comment

Your email address will not be published. Required fields are marked *

This div height required for enabling the sticky sidebar