Skip to content

Commit

Permalink
navbar bug fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
Nur Alam committed Jun 5, 2023
1 parent 2ae647d commit 654cd05
Show file tree
Hide file tree
Showing 12 changed files with 613 additions and 324 deletions.
344 changes: 253 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,74 +1,69 @@
# Laravel Navbar

This package generate navigation bar for laravel application. In two ways we can generate navbar. One is defining navigation during route definition, it means define the navigation in the controller. Other one is defining the navigation using `Navbar::class`
This package generates navigation/navbar for laravel application. The package also provide a build in html navigation UI, it also allows you to build your own custom navigation UI.


## Sample
Define the navigation in the controller
# Sample & Usages
```php
use RadiateCode\LaravelNavbar\Traits\Navbar;
use RadiateCode\LaravelNavbar\Contracts\WithNavbar;

class OfficeController extends Controller implements WithNavbar
{
use Navbar;

public function navigation()
{
$this->nav()
->addNav('Offices','fa fa-landmark')
->addNavLink('index') // route associate method
->childOf('Meta','fa fa-wrench');
}


public function index(){
// code
}

}

.............

class ProjectController extends Controller implements WithNavbar
{

public function navigation()
{
$this->nav()
->addNav('Project','fa fa-project-diagram')
->addNavLink('create','New','fa fa-plus-circle')
->addNavLink('index','List','fa fa-list');
}

public function index(){
// code
}

public function create(){
// code
}

}

$navitems = Nav::make()
->header('Adminland', function (Nav $nav) {
$nav
->addIf(hasPermission('role-list'), 'Roles', route('role-list'), ['icon' => 'fa fa-user-tag'])
->addIf(hasPermission('system-user-list'), 'Users', route('system-user-list'), ['icon' => 'fa fa-users']);
})
->header('Employee Management', function (Nav $nav) {
$nav
->add('Employee', '#', ['icon' => 'fa fa-user'], function (Children $children) {
$children
->add('List', route('employee-list'), ['icon' => 'fa fa-list'])
->add('Create', route('create-employee'), ['icon' => 'fa fa-plus-circle']);
})
->add('Transfer', '#', ['icon' => 'fa fa-money-check-alt'], function (Children $children) {
$children
->add('List', route('transfer-list'), ['icon' => 'fa fa-list'])
->add('Create', route('create-transfer'), ['icon' => 'fa fa-plus-circle']);
});
})
->render(); // array of nav items

$navbar = Navbar::navs($navitems)->render(); // navbar html
```
Generate navigation bar using view composer
> **Note:** You can(should) generate the navbar in the [View Composer](https://laravel.com/docs/10.x/views#view-composers)
### Navbar In View Composer Example
```php
use RadiateCode\LaravelNavbar\NavService;
use RadiateCode\LaravelNavbar\Nav;
use RadiateCode\LaravelNavbar\Children;
use RadiateCode\LaravelNavbar\Facades\Navbar;

class ViewServiceProvider extends ServiceProvider
{

public function boot()
{
View::composer('layouts.partials._left_nav',function(View $view){
$view->with('navbar', NavService::instance()->menus()->toHtml())
$navitems = Nav::make()
->add('Roles', route('role-list'), ['icon' => 'fa fa-user-tag'])
->add('Users', route('system-user-list'), ['icon' => 'fa fa-users'])
->add('Employee', '#', ['icon' => 'fa fa-user'], function (Children $children) {
$children
->addif(condition: true, 'List', route('employee-list'), ['icon' => 'fa fa-list'])
->addif(condition: false, 'Create', route('create-employee'), ['icon' => 'fa fa-plus-circle']);
})
->render(); // array of nav items

// Navbar UI builder
$navbar = Navbar::navs($navitems));

// Now attach the $navbar to your view.
$view->with('navbar', $navbar->render();
});

// Or you can use `class based view composer`. place the Navbar generator code inside the compose().
View::composer('layouts.partials._left_nav', NavComposer::class);
}

}

```
In **_left_nav** partials

Expand All @@ -91,8 +86,8 @@ In **_left_nav** partials
# Requirements
- [PHP >= 7.1](https://www.php.net/)
- [Laravel 5.7|6.x|7.x|8.x|9.x](https://github.com/laravel/framework)
- [JQuery](https://jquery.com/) [Optional]
- [Bootstrap](https://getbootstrap.com/) [Optional when you use custom navbar styling]
- [JQuery](https://jquery.com/) [Optional for custom navbar UI styling]
- [Bootstrap](https://getbootstrap.com/) [Optional for custom navbar UI styling]

# Installation
You can install the package via composer:
Expand All @@ -105,54 +100,221 @@ Publish config file (optional)

# Usage

## Controller Basis
## Nav available methods
### 1. Header : it is use to group certain nav items

To create navigation by route definiation implement the **WithNavbar** Interface and use the **Navbar** trait in controller. Define the menu in the `navigation()` by using `$this->nav()`. This will provide some methods to prepare the nav items.
Syntax:

`header(string $name, Closure $closure, array $attributes = [])` : 1st arg is the name of the header, 2nd arg is a closure to add nav items under the header, 3rd is for any extra attributes (ex: icon, class etc.)
```php
use RadiateCode\LaravelNavbar\Contracts\WithNavbar;
use RadiateCode\LaravelNavbar\Traits\Navbar;

class ExampleController extends Controller implements WithNavbar
{
use Navbar;

public function navigation(): void
{
$this->menu()
->addNav('ManuName','fa fa-project-diagram')
->addNavLink('create','New','fa fa-plus-circle')
->addNavLink('index','List','fa fa-list');
}

}
// example
Nav::make()
->header('Adminland', function (Nav $nav) {
// add nav items under the Adminland header
})
```
### Methods

- `addHeader(string $name)` : Add header for navbar

- `addNav(string $name, string $icon = 'fa fa-home')` : Define the menu name
### 2. Add: add nav items
Syntax:

- `addNavLink(string $method_name,string $title = null,string $icon = null,array $css_classes = [])` : Define the method name which will work as a nav item link. Defined method must be a route associative method. `$title` param is optional if no title pass the package generate a title from the name of **route**.
`add(string $title, string $url, ?array $attributes = null, ?callable $children = null)`: 1st arg name of the nav item, 2nd arg is the nav url, 3rd is for any extra attributes (ex: nav icon, classes), 4th arg is for if you want to add children nav.

- `addNavLinkIf($condition,string $method_name,string $title = null,string $icon = null,array $css_classes = [])` : Conditionally create a nav link. Under the hood the method implement the `addNavLink()` if certain condition is true.

- `childOf(string $name,string $icon = 'fa fa-circle')` : Define the parent menu. If the menu is a child of another menu then define that parent menu. We can pass controler name as a parent menu or we can pass just string name as a parent menu. See [example]()

- `createIf($condition)` : If certain condition is true then create the navigation with nav links.

## Render Menu

To rendered the menus you can use `MenuService` class.
```php
//Example 1
$navitems = Nav::make()
->add('Roles', route('role-list'), ['icon' => 'fa fa-user-tag'])
->add('Users', route('user-list'), ['icon' => 'fa fa-users'])
->render();

// Example 2: with header
$navitems = Nav::make()
->header('Adminland', function (Nav $nav) {
$nav
->add('Roles', route('role-list'), ['icon' => 'fa fa-user-tag'])
->add('Users', route('system-user-list'), ['icon' => 'fa fa-users'])
->add('Settings', route('system-settings'), ['icon' => 'fa fa-wrench'])
})
->render();
```

NavService::instance()->menus()->toHtml();
### 3. Add If: Conditionally add nav
Syntax:

`addIf($condition, string $title, string $url, array $attributes = [], ?callable $configure = null)`: 1st arg is the condition bool or closure return bool, 2nd name of the nav, 3rd nav url, 4th extra attributes, 5th a closure for adding children nav.
```php
//Example 1
$navitems = Nav::make()
->addIf(true, 'Roles', route('role-list'), ['icon' => 'fa fa-user-tag'])
->addIf(false, 'Users', route('user-list'), ['icon' => 'fa fa-users'])
->render();

//Example 2: with header
$navitems = Nav::make()
->header('Adminland', function (Nav $nav) {
$nav
->addIf(true, 'Roles', route('role-list'), ['icon' => 'fa fa-user-tag'])
->addIf(false, 'Users', route('system-user-list'), ['icon' => 'fa fa-users'])
->addIf(true, 'Settings', route('system-settings'), ['icon' => 'fa fa-wrench'])
})
->render();
```
### 4. Chidlren nav: you can add children navs
You have already noticed how we added children nav. We can also conditionally add children nav
```php
// Example
$navitems = Nav::make()
->header('Employee Management', function (Nav $nav) {
$nav
->add('Employee', '#', ['icon' => 'fa fa-user'], function (Children $children) {
$children
->add('List', route('employee-list'), ['icon' => 'fa fa-list'])
->add('Create', route('create-employee'), ['icon' => 'fa fa-plus-circle']);
})
->add('Transfer', '#', ['icon' => 'fa fa-money-check-alt'], function (Children $children) {
// we can also conditionally add children nav
$children
->addIf(true, 'List', route('transfer-list'), ['icon' => 'fa fa-list'])
->addIf(true, 'Create', route('create-transfer'), ['icon' => 'fa fa-plus-circle']);
})
})
->render();
```
### 5. Render: and the render method to get the array of nav items
```php
// render() result sample
[
"adminland" => [ // header
"title" => "Adminland",
"attributes" => [],
"type" => "header",
"nav-items" => [ // nav items under the adminland header
[
"title" => "Roles",
"url" => "http://hrp.test/role-list",
"attributes" => [
"icon" => 'fa fa-user-tag'
],
"is_active" => false,
"type" => "menu",
"children" => [] // no children
],
[
"title" => "User",
"url" => "http://hrp.test/system-user-list",
"attributes" => [
"icon" => 'fa fa-users'
],
"is_active" => false,
"type" => "menu",
"children" => [] // no children
]
]
],
"employee-management" => [ // header
"title" => "Employee Management",
"attributes" => [],
"type" => "header",
"nav-items" => [ // nav items under the employee managment
[
"title" => "Employee", // parent nav
"url" => "#",
"attributes" => [
"icon" => 'fa fa-user'
],
"is_active" => false,
"type" => "menu",
"children" => [ // children nav items of employee nav
"nav-items" => [
[
"title" => "List",
"url" => "http://hrp.test/employee-list",
"attributes" => [
"icon" => 'fa fa-list'
],
"is_active" => false,
"type" => "menu",
"children" => []
],
[
"title" => "Create",
"url" => "http://hrp.test/create-employee",
"attributes" => [
"icon" => 'fa fa-plus-circle'
],
"is_active" => false,
"type" => "menu",
"children" => []
]
]
]
]
]
],
"nav-items" => [] // nav items without header will be append here
]
```
## Navbar UI Builder
`Laravel-Navbar` provide a built in navbar UI builder so that you can easily integrate the UI with your app.
> Note: You can built your own custom Navbar UI by defining custom [Navbar Presenter](#navbar-presenter). Or, you can comes up with your own approch to show navbar.
Or
**Example:** see the view composer [example](#navbar-in-view-composer-example)

NavService::instance()->menus()->toArray();
### Methods
Available methods of the builder
- `navs(array $navItems)` : generated nav items
- `render()` : Render the html
- `navActiveScript()` : Nav active script usefull if you want to active the current nav item in the front-end by Js(JQuery). It has another benefit, if you cache the generated navbar this script will help you to active your current nav because the back-end active function only active once before cache, after cached it always show that same active nav. So it is **recommended** if you want to cache your navbar you should disable back-end `nav-active` from the [Config](#Config) and use this script in the front-end.
```php
// Example of nav active script
$navbar = Navbar::navs($navitems);

$view->with('navbar', $navbar->render())
->with('navScript',$navbar->navActiveScript());
```
```html
<!-- assume you have layouts.partials._left_nav.blade.php -->

> `toHtml()` return built-in html navbar, which is built top of the **bootstrap navbar**. But you can modify the style of the navbar by defining a custom **Nav Presenter** class.
<div class="sidebar">
<!-- Sidebar Menu -->
{!! $navbar !!}
<!-- /.sidebar-menu -->
</div>

<!-- Note: We assume you have @stack('js') in your template layout-->
@prepend('js')
{!! $navScript !!}
@endprepend
<!-- ./ end Js-->
```
Or, you can add it to you script partials
```html
<!-- assume: you have layouts.partials._script.blade.php -->

{!! RadiateCode\LaravelNavbar\Facades\Navbar::navActiveScript(); !!}

<script>
// other js code
</script>
```
## Navbar Presenter
Navbar presenter is nothing but a class which contain some functionality to generate navbar html. Under the hood the [Navbar builder](#navbar-ui-builder) use this presenter. You can use your own custom presenter. If you use custom presenter make sure you have add it in your [Navbar Config](#config)

## Config
```php
/**
* Presenter for navbar style
*
* [HTML presenter]
*/
'nav-presenter' => NavbarPresenter::class,

/**
* It will set active to requested/current nav
*
* [Note: if you want to set nav active by front-end (Js/Jquery)
* Or, if you cached your rendered navbar, then you should disable it]
*/
'enable-nav-active' => true
```

## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
Expand Down
Loading

0 comments on commit 654cd05

Please sign in to comment.