TopNav Menu Navigation Example - Icon not shows on first menu - html

I've followed Dynamic nested topnav menu to create a navigation bar.
It was working perfectly until that I've tried to add an icon to the parents menu by change the code iconName: 'close' to iconName: 'arrow_circle_down' for DevFestFL.
The icon just cannot be displayed, but it works fine on its children.
{
displayName: 'DevFestFL',
iconName: 'arrow_circle_down',
children: [
{
displayName: 'Speakers',
iconName: 'arrow_circle_down',
children: [
{
displayName: 'Michael Prentice',
iconName: 'person',
route: 'michael-prentice',
children: [
{
displayName: 'Create Enterprise UIs',
iconName: 'star_rate',
route: 'material-design',
},
],
},
Thank you Agustin L. Lacuara
I have installed the package, and I have tried Angular Material Icons.
displayName: 'Reports',
iconName: 'arrow_downward',
children: [
{
displayName: 'Content History Report',
iconName: 'arrow_downward',
route: 'reports/content-history'
},
{
displayName: 'Drive History Report',
iconName: 'article',
route: 'reports/drive-history'
}
]
However, it only worked for child menu.
Icon is not working for parents menu

Try using icons from Angular Material Icons. Here there is a cheatsheet that might help you, it did in some projects for me.
https://jossef.github.io/material-design-icons-iconfont/

<!-- Handle branch node buttons here -->
<span *ngIf="item.children && item.children.length > 0">
<button
mat-button
[matMenuTriggerFor]="menu.childMenu"
[disabled]="item.disabled"
>
{{ item.displayName }}
<mat-icon>{{ item.iconName }} </mat-icon>
</button>
<app-menu-item #menu [items]="item.children"></app-menu-item>
</span>
One line was missed from the example.

Related

How am I able to add the property pInitEditableRow in the Menu Items defined in TypeScript to allow the editing of row in the DataTable?

I have the HTML file that is as shown in the following codes.
<button
*ngIf="!editing"
type="button"
pButton
pRipple
class="p-button-text"
icon="pi pi-ellipsis-v"
(click)="menu.toggle($event)">
</button>
<p-menu
#menu
[popup]="true"
[model]="items"
appendTo="body">
</p-menu>
My Menu Items are being populated in the Type Script file.
this.items = [
{
label: 'Edit Name',
icon: 'pi pi-pencil',
},
{
label: 'Replace File',
icon: 'pi pi-file'},
{
label: 'Delete File',
icon: 'pi pi-trash',
},
];
If I would like to add the property "pInitEditableRow" for PrimeNG only when I click on the Edit Name Menu Item how can I do about it in this case?

Scrolling to a div inside a container with overflow-y in Angular

In an angular app I have two bootstrap columns - the left col contains a scrollable div with overflow-y: auto; - the right col is a set of links that are essentially bookmarks that jump to the sections within the left scrollable container.
As far as I can see I'm facing two challenges:
1 - Setting up Angular to recognise I wish to scroll to page section when routing is enabled.
This I've over come by using router options and fragments
const routerOptions: ExtraOptions = {
useHash: false,
scrollPositionRestoration: 'enabled',
anchorScrolling: 'enabled',
scrollOffset: [0, 64]
};
imports: [
...
RouterModule.forRoot(appRoutes, routerOptions),
...
]
And the link:
<a [routerLink]='"."' fragment="uniquedivid">Link</a>
2 - Getting a fragment / anchor to be scrolled into place when it's inside an overflow
From what I've read on SO and other blogs I can see a varying array of ways to do this but most of them use JQuery (which I want to avoid as I'm using pure Angular) and none of these methods seem to compliment the route system in Angular.
I don't know if this makes a difference but my links come AFTER my overflow-ed div as shown below:
<div class="row">
<div class="col">
<div id="overflow">
<div id="section-1"></div>
<div id="section-2"></div>
<div id="section-3"></div>
</div>
</div>
<div class="col">
<a [routerLink]='"."' fragment="section-1">Section 1</a>
<a [routerLink]='"."' fragment="section-2">Section 1</a>
<a [routerLink]='"."' fragment="section-3">Section 3</a>
</div>
</div>
I feel like I'm along the right lines here there's just something I'm missing, or maybe I'm overcomplicating things and there's a simpler way I'm not aware of?
I'm not sure you got a solution for it, but if I were you, I would have used a well organized npm module that can directly help you organize the breadcrumbs. If I understand the question correctly, you can use angular-crumbs.
You can organize your routing like this :
export const rootRouterConfig: Routes = [
{path: '', redirectTo: 'home', pathMatch: 'full'},
{path: 'home', ..., data: { breadcrumb: 'Home'}},
{path: 'about', ..., data: { breadcrumb: 'About'}},
{path: 'github', ..., data: { breadcrumb: 'GitHub'},
children: [
{path: '', ...},
{path: ':org', ..., data: { breadcrumb: 'Repo List'},
children: [
{path: '', ...},
{path: ':repo', ..., data: { breadcrumb: 'Repo'}}
]
}]
}
];
Then try to add the breadcrumb selector in the component where your routes are destined to (when using bootstrap):
<breadcrumb #parent>
<ol class="breadcrumb">
<ng-template ngFor let-route [ngForOf]="parent.breadcrumbs">
<li *ngIf="!route.terminal" class="breadcrumb-item">
{{ route.displayName }}
</li>
<li *ngIf="route.terminal" class="breadcrumb-item active" aria-current="page">{{ route.displayName }}</li>
</ng-template>
</ol>
</breadcrumb>
There are other ways too, you can check here to implement.

An angular-material-multilevel-menu for Angular 6?

I have tried to achieve a multilevel sidenav and I found this that meets my requirements:
angular-material-multilevel-menu
Demo - Note the accordion type
Unfortunately this is created for AngularJS (1.0?), which seems to not work in Angular 6.
My questions are:
Is there any other multilevel sidenav component for Angular 6? Have note found any similar on Google that works.
Is it possible to "upgrade" this Angular 1.0 menu to Angular 6? How?
Is there any simple instructions or courses to build your own multilevel side nav? There are many instructions for one-level, but I have found none multi-level.
I don't know if you are still looking for angular-material-multilevel-menu but I have found one made by ShankyTiwari.
Here is the link for GitHub and the link for the demo.
Very easy to use and to implement. For example, I implemented it in a sidebar because it does not exist with Angular material.
If not an alternative would be PrimeNG as #Dino said.
Angular Material 6.0 doesn't come with multilevel menu out of the box. You would have to create it on your own. It would be a combination of Nested Menu, and Side Nav.
And to answer your first question, I'd suggest you to take a look at PrimeNG's Panel Menu. It does exactly what you need and with some little effort, you'll also be able to change it's design into Material like. (I did it with some PrimeNG components, so I can confirm that it works.
Please take in consideration that PrimeNG 6.0.0 is currently in
Alpha-2 version.
I found a PART of a solution.
Here is a demo using "mat-expansion-panel"
There are still some issues that must be solved.
The shadow and offset of the Expansion Level
The shutdown instead of stay selected
Better way to do this?
Any suggestions?
I was looking to create multi-level menus with native angular material but still under development by ng material team. So, I'd like to suggest to use ng-material-multilevel-menu package for now by follow the below:
npm install --save ng-material-multilevel-menu or yarn add --save ng-material-multilevel-menu
Then import NgMaterialMultilevelMenuModule by
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
/* Import the module*/
import { NgMaterialMultilevelMenuModule } from 'ng-material-multilevel-menu';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
NgMaterialMultilevelMenuModule // Import here
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Call <ng-material-multilevel-menu [configuration]='config' [items]='appitems' (selectedItem)="selectedItem($event)"></ng-material-multilevel-menu> in your html.
Finally, declare appitems for your list items and config object
appitems = [
{
label: 'NPM',
icon: 'favorite',
link: 'https://www.npmjs.com/package/ng-material-multilevel-menu',
externalRedirect: true
},
{
label: 'Item 1 (with Font awesome icon)',
faIcon: 'fab fa-500px',
items: [
{
label: 'Item 1.1',
link: '/item-1-1',
faIcon: 'fab fa-accusoft'
},
{
label: 'Item 1.2',
faIcon: 'fab fa-accessible-icon',
items: [
{
label: 'Item 1.2.1',
link: '/item-1-2-1',
faIcon: 'fas fa-allergies'
},
{
label: 'Item 1.2.2',
faIcon: 'fas fa-ambulance',
items: [
{
label: 'Item 1.2.2.1',
link: 'item-1-2-2-1',
faIcon: 'fas fa-anchor',
onSelected: function() {
console.log('Item 1.2.2.1');
}
}
]
}
]
}
]
},
{
label: 'Item 2',
icon: 'alarm',
items: [
{
label: 'Item 2.1',
link: '/item-2-1',
icon: 'favorite'
},
{
label: 'Item 2.2',
link: '/item-2-2',
icon: 'favorite_border'
}
]
},
{
label: 'Item 3',
link: '/item-3',
icon: 'offline_pin',
onSelected: function() {
console.log('Item 3');
}
},
{
label: 'Item 4',
link: '/item-4',
icon: 'star_rate',
hidden: true
}
];
config = {
paddingAtStart: false,
classname: 'my-custom-class',
listBackgroundColor: '#fafafa',
fontColor: 'rgb(8, 54, 71)',
backgroundColor: '#fff',
selectedListFontColor: 'red',
interfaceWithRoute: true
};
Note: interfaceWithRoute will enable root item to be linkable if link property is available.

How to implement custom Tab indicator color in Material-UI v1

I have MUI v1 beta 32 running on a production site, very nicely.
Time to update to v1!
So far, changes have been very simple. It's mostly been a matter of updating the import tags.
But I am running into an issue with my selected <Tab/> indicator.
I was using the rootInheritSelected style override in order to apply the color of my choice.
How to implement it in v1?
In the end I found it was much simpler:
<Tabs
textColor="inherit"
fullWidth
centered
classes={{
indicator: classes.indicator
}}>
<Tab />
<Tab />
</Tabs>
and the styles:
const styles = theme => ({
indicator: {
backgroundColor: 'white',
},
})
I was able to do this with the TabIndicatorProps.
Example:
<Tabs
value={this.state.value}
onChange={(event, newValue) => {
this.setState({value: newValue})
}}
TabIndicatorProps={{
style: {
backgroundColor: "your_custom_color"
},
}}
>
This allowed me to also add different indicator colors based on what tab is active

Durandaljs generating sub menu from json

Alright, I am fairly new to durandal. I am really struggling getting trying to accomplish this.
Here is what I am trying to do: There is a main navigation that is compromised of an inbox, draft, submitted, etc. Clicking on these, gives the user a submenu that comes out to the side of the main navigation. This submenu is generated by json data that I get from the server. Clicking an an option from the submenu should open the document in a viewer viewmodel based on the id of the document.
Ex.
User clicks on inbox
2. Menu comes out that has documents from their inbox. User clicks on view
3. Document that is clicked is displayed to the user.
4. So when they get to this point, I want the url to be mysite.com/#inbox/viewer/123456 (123456 is documentid)
I just haven't been able to find decent examples that are similar to this, and was wondering if someone could help point me in the right direction.
I kind of did it by making each main navigation link to a module, and have a document window in each of those modules, but I thought there had to be a better way. So what I am trying to do is keep my subnavigation in the shell. I don't want to have a module for each of my main navigation items.
Here is my shell code right now:
shell.js
define(['durandal/system', 'services/logger', 'plugins/router', 'durandal/activator'], function (system, logger, router, activator) {
//#region Internal Methods
function log(msg, data, showToast) {
logger.log(msg, data, system.getModuleId(shell), showToast);
}
function logError(msg, data, showToast) {
logger.logError(msg, data, system.getModuleId(shell), showToast);
}
function navigateRoute(hashValue) {
var target = hashValue.hash;
$("body").addClass("subnav-active");
document.cookie = "subNav=true";
$(target).addClass("current");
router.navigate(target, {replace: true, trigger: false });
}
var routes = [
{ route: '', hash: '#home', moduleId: 'home', title: '', nav: false, cssClass: 'icon-inbox' },
{ route: 'inbox', hash: '#inbox', moduleId: 'inbox', title: 'Inbox', nav: true, cssClass: 'icon-inbox' },
{ route: 'drafts', hash: '#drafts', moduleId: 'drafts', title: 'Drafts', nav: true, cssClass: 'icon-file-alt' },
{ route: 'submitted', hash: '#submitted', moduleId: 'submitted', title: 'Submitted', nav: true, cssClass: 'icon-hand-right' },
{ route: 'completed', hash: '#completed', moduleId: 'completed', title: 'Completed', nav: true, cssClass: 'icon-check' },
{ route: 'settings', hash: '#settings', moduleId: 'settings', title: 'Settings', nav: true, cssClass: 'icon-cog' }
];
//#endregion
var shell = {
activate: function () {
router.on('router:route:not-found', function (fragment) {
logError('No Route Found', fragment, true);
});
return router.makeRelative({ moduleId: 'viewmodels' }) // router will look here for viewmodels by convention
.map(routes) // Map the routes
.buildNavigationModel() // Finds all nav routes and readies them
.activate(); // Activate the router
}
,
router: router,
navigateRoute: navigateRoute
};
return shell;
});
shell.html
<div class="main-wrapper wrapper">
<div class="container_template">
<header class="pageheader">
<nav class="mobile-nav">
<a class="menu-button" href="#main-navigation">
<i class="icon-reorder"></i><span>Menu</span>
</a>
</nav>
<h1 class="logo">template</h1>
<nav class="nav-user">
<a class="close" href="#">
<i class="icon-chevron-right"></i>
<span>Main</span>
</a>
</nav>
</header>
<!-- Begin Header/Navigation -->
<div class="main-navigation" role="banner">
<div class="main-navigation-inner inner">
<nav class="navigation">
<ul data-bind="foreach: router.navigationModel">
<li>
<a class="nav-button" data-bind="attr: {'data-target': hash,}, css: {'nav-button' : isActive, active: isActive }, click: function(hash) { $root.navigateRoute(hash);return true},">
<i data-bind="css: cssClass"></i>
<span data-bind="html: title"></span>
</a>
</li>
</ul>
</nav>
</div>
</div>
<!-- End Header/Navigation -->
<!-- Sub Navigation Elements -->
<!--This is my sbumenu-->
<div id="inbox" class="navigation-sub">
<div class="navigation-sub-inner inner">
<div class="navigation-sub-header">
<a class="close" href="#">×</a>
<h3>Inbox</h3>
</div>
<div class="navigation-sub-search">
<form>
<input type="text" placeholder="Search" />
<button>Go</button>
</form>
</div>
<ul data-bind="contentsOfInbox">
<li>
<a data-bind="href : linktoDocuemntViewer" href="" class="form-open">
<i class="icon-file-alt"></i><span data-bind="html: NameofDocumentHere"></span>
<span class="date" data-bind="html: DateOfDocumentHere"></span>
</a>
</li>
</ul>
</div>
</div>
<!-- End SUB NAV -->
<!--Begin Main-->
<!--Documents would appear here-->
<div class="main" data-bind=" router: { cacheViews: false }">
</div>
<!-- End Main -->
</div>
Thanks for any help
For what you are trying to do it sounds like using the navigationModel will not work. From my experience, the navigationModel and route are a 1 to 1 relationship. What you are trying to do is have one route with parameters tied to multiple menu items. To do this you should separate your menus and routes. Remember at the heart of everything you are just binding javascript objects and collections to html elements. The router.navigationModel property is just that, a collection of javascript objects that is built from your defined routes. When you call .buildNavigationModel() that is what it is doing, building up a new collection of javascript objects for you to bind to your menu html. There is nothing stopping you from creating a completely new property on your shell viewmodel that contains your own custom collection of javascript menu objects and binding that to your UL/LI navigation html. If you make this new menu collection a computedObservable you could then add to it in a lazy fashion as you needed to and since it is bound with knockout, changes would appear in the UI automatically. I have done this on a number of different projects and it works fine. I build a menu table in the backend and then just return only the items that the user has access to and use that to build my UI menu. To make navigation work, I keep the urlhash in the table and bind that to the anchor tags. When you are creating routes, you don't have to set the hash property, the router plugin will take care of that for you. So for your requested example, create a menu collection like this:
{ displayname: 'Inbox' cssClass: 'icon-inbox', urlHash: '' children[
{ displayname: 'Doc 1' cssClass: 'icon-message', urlHash: 'inbox/viewer/12345' },
{ displayname: 'Doc 2' cssClass: 'icon-message', urlHash: 'inbox/viewer/12346' },
{ displayname: 'File 1' cssClass: 'icon-message', urlHash: 'inbox/viewer/12347' }]}
create a route like this:
{ route: 'inbox/viewer/:messageId', moduleId: 'home', title: '', nav: false, cssClass: 'icon-inbox' },
see the durandal docs for info on passing parameters to routes
expose this menu as a computedObesrvable from your shell and bind that to you UL/LI menu html instead of the router.NavigationModel. When needed, change the contents of the children property of the inbox menu with new data from the server.