CodeIgniter Forums
Over-engineering for a simple system - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: CodeIgniter 4 (https://forum.codeigniter.com/forum-28.html)
+--- Forum: CodeIgniter 4 Discussion (https://forum.codeigniter.com/forum-31.html)
+--- Thread: Over-engineering for a simple system (/thread-76180.html)



Over-engineering for a simple system - BilltheCat - 04-19-2020

I really feel like I'm making this harder than it needs to be, but I can't see a simpler solution... hopefully someone can help me on this.

I have a navigation sidebar (Bootstrap 4), and I want to set the navigation items as active when going to them.  Some items are in a secondary drop-down menu, and so I need to set the parent as active (menu-open) also.  So first I need to get the URI segments, and then determine if that path is under the parent and set both parent and child as active.

My problem with the method I'm using is that it uses a lot of PHP in the view, instead of separating the logic to the controller.  But I don't see a simple method of defining both paths in a controller, and then relaying that to the view for each of the menu items to be active or not active.

Admin Controller
PHP Code:
<?php

namespace App\Controllers;

class 
Admin extends Auth 
{
    public function __construct() 
    {
        parent::__construct();
        
        $uri 
= new \CodeIgniter\HTTP\URI(current_url());
        
        $this
->data['uri_segments'] = $uri->getSegments();
    }

    public function index() 
    {
        echo view('Admin/Pages/Dashboard'$this->data);
    }
    public function users($find null
    {
        $model = new \App\Models\UsersModel();
        $this->data['users'] = $model->paginate();
        $this->data['pager'] = $model->pager;

        echo view('Admin/Pages/Userlist'$this->data);
    }
    public function user($id null
    {
        $model = new \App\Models\UsersModel();
        $this->data['user'] = $model->getUser($id);

        echo view('Admin/Pages/User'$this->data);
    }


Sidebar View
PHP Code:
<nav class="mt-2">
    <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
        <li class="nav-item">
            <a href="<?= site_url('admin/profile'); ?>" class="nav-link <?= (uri_string() === 'admin/profile') ? 'active' : ''; ?>">
                <class="fas fa-user"></i>
                <p>
                    User Profile
                
</p>
            </a>
        </li>
        <li class="nav-item has-treeview <?= (in_array(implode('/',[$uri_segments[0],$uri_segments[1]]), ['admin/users', 'admin/user', 'admin/permissions', 'admin/roles'])) ? 'menu-open' : ''; ?>">
            <a href="#" class="nav-link">
                <class="nav-icon fas fa-tachometer-alt"></i>
                <p>User Management
                    
<class="right fas fa-angle-left"></i>
                </p>
            </a>
            <ul class="nav nav-treeview">
                <li class="nav-item">
                    <a href="<?= site_url('admin/users'); ?>" class="nav-link <?=(implode('/',[$uri_segments[0],$uri_segments[1]]) === 'admin/users' || 'admin/user') ? 'active' : ''; ?>">
                        <class="fas fa-users"></i>
                        <p>Users</p>
                    </a>
                </li>
            </
ul>
        </
li>
    </
ul>
</
nav



RE: Over-engineering for a simple system - berendbotje91 - 04-20-2020

Perhaps not the best way to tackle your problem, but here is how I "check" the current page for the navigation.

You could load the current controller or method with something service('router')->controllerName(); then pass that to the navigation view as your current controller. Then all you need is
PHP Code:
class="nav-item <?= $Controller == 'admin' ? 'active' : ''; ?>" 
However, there currently (version 4.0.2) is an problem where the controllerName() function returns something different depending on wether the route is defined in routes.php: https://github.com/codeigniter4/CodeIgniter4/issues/2520 so you might need some code to handle that.

Same can be done for ->methodName() if needed too.

This might decrease some php code in your view.


RE: Over-engineering for a simple system - InsiteFX - 04-20-2020

This might help you out, you may need to modify it a bit.

Highlight current page menu item with jQuery

Should point you in the right direction.


RE: Over-engineering for a simple system - BilltheCat - 04-20-2020

(04-20-2020, 01:24 AM)berendbotje91 Wrote: Perhaps not the best way to tackle your problem, but here is how I "check" the current page for the navigation.

You could load the current controller or method with something service('router')->controllerName(); then pass that to the navigation view as your current controller. Then all you need is
PHP Code:
class="nav-item <?= $Controller == 'admin' ? 'active' : ''; ?>" 
However, there currently (version 4.0.2) is an problem where the controllerName() function returns something different depending on wether the route is defined in routes.php: https://github.com/codeigniter4/CodeIgniter4/issues/2520 so you might need some code to handle that.

Same can be done for ->methodName() if needed too.

This might decrease some php code in your view.

Thanks, but I'm not sure what you're doing different here than what I already have?

PHP Code:
class="nav-link <?= (uri_string() === 'admin/profile') ? 'active' : ''; ?>" 

(04-20-2020, 04:04 AM)InsiteFX Wrote: This might help you out, you may need to modify it a bit.

Highlight current page menu item with jQuery

Should point you in the right direction.
I don't know why I didn't think of JQuery for this...  thanks!


RE: Over-engineering for a simple system - InsiteFX - 04-20-2020

If you scroll to the bottom of the page maybe the middle he shows you how to just what you are asking.