Bootstrap Navbar Element Select Active in Laravel - html

So I have a problem and as per usual given I am trying to learn frontend stuff i am out of my depth. I am currently writing a website that has a forum, live chat, profile, and a few other things. These I would call "Menu items" with sections of those i.e. unread messages being placed on a dropdown menu item for messages. As per blade fashion I am using a menu blade which is part of the layout blade and finally the page incorporates whichever layout it wants.
The last solution I tried after seeing a post was to add {{ Request::segment(1) === 'messages' ? 'active' : '' }} or {{ Request::segment(1) === 'messages' ? 'active' : 'null' }} into the class section of the corresponding li for the menu item, this successfully updated some of the menu items styles but also broke the dropdown functionality.
Below is my code which still has my last solution contained within it:
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand {{ Request::segment(1) === '/' ? 'active' : '' }}" data-toggle="tab" href="/">Home</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li role="presentation" class="dropdown {{ Request::segment(1) === 'forum' ? 'active' : '' }}">
<a class="dropdown-toggle" data-toggle="dropdown tab" href="/forum" role="button" aria-haspopup="true" aria-expanded="false">Forum<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Newest Posts</li>
<li>Trending</li>
<li>Something</li>
<li role="separator" class="divider"></li>
<li>Create New Post <span class="glyphicon glyphicon-edit"></span></li>
<li>Your Posts</li>
</ul>
</li>
<li class="{{ Request::segment(1) === 'chat' ? 'active' : null }}">Chat</li>
<li role="presentation" class="dropdown {{ Request::segment(1) === 'messages' ? 'active' : '' }}">
<a class="dropdown-toggle" data-toggle="dropdown tab" href="#" role="button" aria-haspopup="true" aria-expanded="false">Messages<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Unread</li>
<li>Read</li>
<li>Sent</li>
<li role="separator" class="divider"></li>
<li>All</li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<nav class="navbar navbar-default"></nav>
I appreciate I am new and that most solutions require something like js or jquery, if this is the case you will need to be explicit in how and where I put it as I have never even thought of using it yet!
Thanks!

I did have this problem recently, I found two useful packages in packagist.org
watson/active: This package is very simple and useful you can add active or any other classes to your menu base on their route, this could be route, action or url activation.
lavary/laravel-menu: I personally found this package most useful than the previous one, you can create hierarchical menus, activate a menu base on route, action or url, or even you can activate your menu base on any other url (this is useful for parent menus, e.g. when you are in a child link related to a parent link in your menu, both child link and parent link will be activated.). This package is most complicated than the other one, but I think the documentation written very clear and if you read it carefully you can do anything you want with your menus.

Here is my solution
<a class="#if(Request::is('home')) active #endif" href="{{ route('home') }}">Home</a>

I've been doing this many times and I've come up with 2 solutions depending on the type of navigations.
The easiest, works fine when you have simple entities (like Post, Category, Tag) and 1 menu entry for each.
Posts
This will match all classic endpoints such as /posts, /posts/new, /posts/{post}, ...
I've been using this for my latest projects because it's simple and allows much more customisation. It's pretty useful if you have something like nested navigation items.
Posts
All Posts
New Post
Posts Settings
Categories
All Categories
New Category
I'm just passing a variable to my layout like this.
// views/posts/index.blade.php
#extends('layouts.app', ['activeMenu' => 'posts.index'])
#section('content')
// Your content
#stop
// views/layouts/app.blade.php
<html>
//...
<li class="{{ $activeMenu == 'posts.index' ? 'active' : '' }}">All Posts</li>
<li class="{{ $activeMenu == 'posts.create' ? 'active' : '' }}">New Post</li>
// ...
You can also play with nested active states like this.
// views/posts/index.blade.php
#extends('layouts.app', ['activeMenu' => 'posts' 'activeSubMenu' => 'posts.index'])
#section('content')
// Your content
#stop
// views/layouts/app.blade.php
<html>
//...
<li class="dropdown {{ $activeMenu == 'posts' ? 'active' : '' }}">
<a class="dropdown-toggle" data-toggle="dropdown tab">Posts <span class="caret"></span></a>
<ul class="dropdown-menu">
<li class="{{ $activeSubMenu == 'posts.index' ? 'active' : '' }}">All Posts</li>
<li class="{{ $activeSubMenu == 'posts.create' ? 'active' : '' }}">New Post</li>
</ul>
// ...
Otherwise I suggest you take a look at spatie/laravel-menu

Related

How to change nav "active" class on different pages with base.html

I have my navbar on my base.html, so I extend it on all other pages.
But I have a class "active" on the home page, so it also stays active in all other pages.
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" href="http://127.0.0.1:8000/backend/">
<i class="ni ni-shop text-primary"></i>
<span class="nav-link-text">Dashboard</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://127.0.0.1:8000/backend/clientes">
<i class="ni ni-ungroup text-orange"></i>
<span class="nav-link-text">Clients</span>
</a>
</li>
</ul>
How can I change the active class to a different menu item based on the page I am?
There's no one-size-fits-all answer to your question, it really depends on your project's structure, url hierarchy etc. But usually, the best solutions are either a custom template tag taking the request as argument (and/or other context variables or plain constants, depending on your own project's logic) to compute the current "section" and render the navbar accordingly.
Send name as variable and value with active.
def index(request):
# your code
context = {
'dashboard': 'active',
}
return render(request, 'index.html', context)
def clients(request):
# your code
context = {
'clients': 'active',
}
return render(request, 'clients.html', context)
Use variable like this:
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link {{ dashboard }}" href="http://127.0.0.1:8000/backend/">
<i class="ni ni-shop text-primary"></i>
<span class="nav-link-text">Dashboard</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link {{ clients }}" href="http://127.0.0.1:8000/backend/clientes">
<i class="ni ni-ungroup text-orange"></i>
<span class="nav-link-text">Clients</span>
</a>
</li>
</ul>
OPTION 1
You can use django contex_processors.
add your settings.py
TEMPLATES = [
{
#other settings
'BACKEND': 'django.template.backends.django.DjangoTemplates',
#other settings
'OPTIONS': {
'context_processors': [
#other options
'context_file_path.defaults',
],
},
},
]
in your context_file.py
def defaults(request):
active_bar = "" # your active bar logic
return {
'active_bar': active_bar,
}
with this method, each request decide which bar active. And active_bar variable is being passed to your template. In your template you can add active class if active_bar variable equals your bar name. Like that:
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link {% if active_bar == 'dashboard' %}active{% endif %}" href="http://127.0.0.1:8000/backend/">
<i class="ni ni-shop text-primary"></i>
<span class="nav-link-text">Dashboard</span>
</a>
</li>
<li class="nav-item {% if active_bar == 'clients' %}active{% endif %}">
<a class="nav-link" href="http://127.0.0.1:8000/backend/clientes">
<i class="ni ni-ungroup text-orange"></i>
<span class="nav-link-text">Clients</span>
</a>
</li>
</ul>
OPTION 2
You can write a custom js file and add your base html. In this js file you can detect url and decide active pane. After that you can add active class to list pane.

Thymeleaf: how to hide the sub-menu

I need to modify the existing sidebar of this project. I want to hide the sub-menu that I didn't select. I can't figure out how to do this.
below is the HTML file for the side bar:
`
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="sidebar" class="sidebar">
<ul class="list-unstyled">
<li th:each="postDto,iterStat : ${categories}">
<a th:attr="aria-expanded=${#lists.contains(postDto.posturl, url)} ? 'true' : ''"
th:attrappend="href='#submenu'+${iterStat.index}"
data-toggle="collapse" th:text="${postDto.categoryName}">
</a>
<ul th:attr="id='submenu'+${iterStat.index}"
th:classappend="${#lists.contains(postDto.posturl, url)} ? 'show' : ''"
class="list-unstyled collapse" th:each="post : ${postDto.post}">
<li th:classappend="${#strings.contains(url, post.link)} ? 'active' : ''">
<a th:href="${post.link}" th:text="${post.title}"></a>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
`
here is the output:
screen shot of the sidebar
I selected Uploading SSS Loan Repayments under the FILE UPLOADS menu. I want to only display the sub-menu under the FILE UPLOADS but the other sub-menu under UPLOAD AND TRANSACTION STATUS , eGOVERNMENT SERVICES is also on display.

Implementing Custom dropdown in Angular 2/4

I have been working on a custom dropdown functionality with a horizontal divider seperating two sets of values and have general select dropdown functionalities like using up and down arrow to navigate through the values, as well as go to specific values on press of a alphabet.
Code:
<div class="btn-group d-flex dropdown" dropdown>
<div class="floatLabelContainer w-100">
<button id="button-basic" dropdownToggle type="button" float-label [addLabel]="false" [hasFloat]="true" class="mb-2" aria-controls="dropdown-basic">
{{selectedCountry}}
<span class="caret" id="country-caret"></span>
</button>
<label for="button-basic" class="label-class" id="label-class">Country</label>
</div>
<ul id="dropdown-basic" slimScroll width="100%" height="250px" size="3px" alwaysVisible="true" wheelStep="20" *dropdownMenu
class="dropdown-menu d-block" role="menu" aria-labelledby="button-basic">
<li role="menuitem">
<a class="dropdown-item" tabindex="0" (click)="selectedCountry = country.name" *ngFor="let country of restOfCountries | orderBy : 'name'">{{country.name}}</a>
</li>
<li class="divider dropdown-divider"></li>
<li role="menuitem">
<a class="dropdown-item" tabindex="0" (click)="selectedCountry = country.name" *ngFor="let country of asianCountries | orderBy : 'name'">{{country.name}}</a>
</li>
</ul>
</div>
I have been able to achieve the divider part with the above code,
but is there away to implement arrows and alphabet press functionality also.
I would prefer to have angular specific implementation or a plugin, rather than js or jQuery
There is the possibility of evaluating keydown and keyup events:
https://alligator.io/angular/binding-keyup-keydown-events/
According to this you should be able to achieve this functionality by implementing click listeners such as:
<div class="btn-group d-flex dropdown"
(keydown.arrowup)="select(items[i-1])"
(keydown.arrowdown)="select(items[i+1])"
dropdown>
EDIT: so I tried this and turns out this does not work on any item on default. It works on inputs, how the example shows but I could not get i ti to work on a list by now.

How can I insert html into navbar with registerHelper?

Here is my html:
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="/" data-toggle="collapse" data-target="#navbar">
{{chooseScriptLevel
'Home'
'zhŭyè'
'主页'
}}
</a></li>
</ul>
</div>
Here is my helper:
Template.registerHelper('chooseScriptLevel', function (english, pinyin, simplified) {
var userSkillLevel = Meteor.user().profile.skillLevel
switch (userSkillLevel) {
case 0:
return english
break
case 1:
var ruby = '<ruby>' + simplified + '<rt>' + pinyin + '</rt></ruby>'
return ruby
break
case 3:
return simplified
break
default:
english
}
})
My navbar is showing: <ruby>主页<rt>zhŭyè</rt></ruby>. Literally showing the html tags to the user.
How can I get it to show the user this:
zhŭyè
主页
If I do it manually, like this, , it works:
<li><a href="/" data-toggle="collapse" data-target="#navbar">
<ruby>主页<rt>zhŭyè</rt></ruby>
</a></li>
Just use triple braces around your helper - this is necessary if the helper returns html:
{{{chooseScriptLevel 'Home' 'zhŭyè' '主页' }}}

Changing the Values in an Unordered List <ul> using ng-repeat; also set an active <li>

I have been trying to work out how to produce a list, where if you click on one of the objects in the list, it becomes active. I have managed to get it working in the non-dynamic version of the code with ease. However, working on AngularJS dynamic version, I just can't seem to get it to work. The data is ok, so it can't be data related, it has to be my dynamic code that is not working.
This is a working piece of code (however not dynamic)
<ul class="nav nav-pills" ng-init="catVal = 1">
<li ng-class="{active: catVal===1}">
Category 1
</li>
<li ng-class="{active: catVal===2}">
Category 2
</li>
<li ng-class="{active: catVal===3}">
Category 3
</li>
</ul>
Now What I really want is an AngularJS dynamic version of this code. This is what I have tried and failed so far.
<ul class="nav nav-pills">
<li ng-repeat="category in model" ng-init="catVal = 1" ng-class="active: catVal === category.catID ">
{{category.catName}}
</li>
</ul>
The catID is associated with the category and should give the same results as the previous list. I get the names in the correct place, just the value is not working.
try this.
var app = angular.module("app",[]);
app.controller("ctrl" , function($scope){
$scope.rowIndex = -1;
$scope.items = [{"name":"ali","score":2},{"name":"reza","score":4},{"name":"amir","score":5},{"name":"asd","score":10}];
$scope.selectRow = function(index){
if(index == $scope.rowIndex)
$scope.rowIndex = -1;
else
$scope.rowIndex = index;
}
});
.active{
background-color:#a11af0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl" class="panel-group" id="accordion">
<ul class="nav nav-pills" ng-init="catVal = 1">
<li ng-repeat="item in items" ng-class="{'active':rowIndex == $index }" ng-click="selectRow($index)">
{{item.name}}
</li>
</ul>
</div>