How to create the sticky header using Angular material? - html

I want to display sticky header.On scroll header1should be hidden and header2 should show,How can i achieve this using material?
Here is my expected DEMO
Thanks in advance

The basic implementation of a sticky header is the same whether you use Angular Material or not - watch the scroll position of the page and hide or show the second header as desired. Here's a rough example using the Angular Material toolbar component for the header:
<div style="min-height: 150vh;"> <!-- Set minimum height to force a scrollbar -->
<mat-toolbar color="primary">
<mat-toolbar-row>
<span>Header 1</span>
</mat-toolbar-row>
</mat-toolbar>
<mat-toolbar color="secondary" style="position: fixed; top: 0;" *ngIf="scrolled">
<mat-toolbar-row>
<span>Header 2</span>
</mat-toolbar-row>
</mat-toolbar>
</div>
And in the .ts file:
scrolled: false;
#HostListener('window:scroll', [])
onWindowScroll() {
// Depending on the desired effect, you should probably only show the second header
// if you've scrolled past the first header's height
this.scrolled = window.pageYOffset > 48;
}

Related

How do I make Angular Material's button toggle full width but left-align its contents?

I have a Tree of Button Toggles in a Button Toggle Group:
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl" class="example-tree">
<mat-button-toggle-group [ngModel]="selectedElement" (ngModelChange)="select($event)">
<!-- This is the tree node template for leaf nodes -->
<mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
<li class="mat-tree-node">
<!-- use a disabled button to provide padding for tree leaf -->
<button mat-icon-button disabled></button>
<mat-button-toggle class="selectable" [value]="node.ref">
<mat-icon class="type-icon">
{{getDisplayIcon(node.ref.type)}}
</mat-icon>
{{node.name}}
</mat-button-toggle>
</li>
</mat-tree-node>
<!-- This is the tree node template for expandable nodes -->
<mat-nested-tree-node *matTreeNodeDef="let node; when: hasChild">
<li>
<div class="mat-tree-node">
<button mat-icon-button matTreeNodeToggle [attr.aria-label]="'Toggle ' + node.name">
<mat-icon class="mat-icon-rtl-mirror">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
<mat-button-toggle class="selectable" [value]="node.ref">
<mat-icon class="type-icon">
{{getDisplayIcon(node.ref.type)}}
</mat-icon>
{{node.name}}
</mat-button-toggle>
</div>
<ul [class.example-tree-invisible]="!treeControl.isExpanded(node)">
<ng-container matTreeNodeOutlet></ng-container>
</ul>
</li>
</mat-nested-tree-node>
</mat-button-toggle-group>
</mat-tree>
It works, but each button toggle has a different width based on the size of its contents:
I can make each button full width by adding this to my .scss file:
.selectable {
width: 100%;
}
Which works, but all of them are centered rather than left-aligned (and the really long one goes beyond):
I've narrowed the problem down to this span that is generated by mat-button-toggle and surrounds my contents and has display: inline-block:
Adding width: 100% to this span lets me add a flex box to the contents and align them properly, but I can't change the span in Angular because it's not my component. I also can't style the mat-button-toggle to align content to the left, as the child button element is full width. How do I get it to do what I want?
As Francesco Lisandro pointed out, I could use my app's styles.css to modify the element I wouldn't normally be able to. This is what I added:
mat-button-toggle.selectable button span {
display: flex;
align-items: center
}

Put fixed navbar and sidebar in all components of Angular app

So, I am new to angular and building a new angular app which will consist of multiple components and I want the navbar and sidebar to be fixed on all components of my app.
I built navbar and sidebar as separate components. I want the navbar and sidebar to be like this, with the app content(all the component content) being in the white part of the screen:
I know the navbar can be easily imported with html like <navbarComponent><navbarComponent>, but the sidebar is a bit problematic to me since I want the app-content to be on the right of the sidebar component, so the only solution I know is to make a container in css like this:
random-component-html:
<app-navigation-bar></app-navigation-bar>
<div class="d-flex container1">
<div class="al-left">
<app-sidenav-bar></app-sidenav-bar>
</div>
<div class="al-right">
<div class="container">
<h2>Apps:</h2>
<mat-nav-list>
<mat-list-item *ngFor="let app of apps" (click)="redirect(app)">
<button mat-icon-button> {{app.name}}
</button>
</mat-list-item>
</mat-nav-list>
</div>
</div>
</div>
random-component-css:
.container1{
width: 100%;
}
.al-left{
float: left;
max-width: 15vw;
}
.al-right{
float: right;
max-width: 85vw;
}
but I feel that there must be an easier way to do this. Does anybody know a solution?
You can route all your other components within this white block
Lets say:
<app-navigation-bar></app-navigation-bar>
<div class="d-flex container1">
<div class="al-left">
<app-sidenav-bar></app-sidenav-bar>
</div>
<div class="al-right">
<div class="container">
<router-outlet></router-outlet>
</div>
</div>
</div>
You can add your header(navbar), sidebar, footer component in your app.component.html
<app-header></app-header>
<app-sidebar></app-sidebar>
<app-footer></app-footer>
<router-outlet></router-outlet>
You can also add footer as well as shown in above example.
And header sidebar & footer will remain in all the rest of the components.

large primeng components butcher css in flexbox

I have a simple Angular application, with a Navbar on top, a footer on the bottom and some content inbetween
<div id="app">
<app-navbar></app-navbar>
<div id="content">
<router-outlet></router-outlet>
</div>
<div id="footer">
<app-footer></app-footer>
</div>
</div>
html,
body {
height: 100%;
}
#app {
height: 100%;
display: flex;
flex-direction: column;
}
#content {
flex: 1;
}
in the content section, I have a tabView wrapped into a row/col setup, like this:
<div class="row ">
<div class="col-md-12">
Lorem ipsum works even with very large texts
</div>
</div>
The styling works perfectly, in that when the content section gets larger than the default size of the app, the footer moves down however much it needs.
However, if instead of putting plain HTML/ plain text I place any Primeng components (here: TabView) that are larger than the standard screen size/ standard position of the footer, the styling breaks and the content gets placed on top of the footer, instead of pushing the footer down.
<div class="col-md-12"> <-- ENLARGING THIS WORKS
<p-tabView orientation="top" [activeIndex]="tabIndex" (onChange)="handleChange($event)" class="order-form"
styleClass="tabview-compo-workbench height-test"> <-- ENLARGING THIS CAUSES THE ISSUE
<p-tabPanel class="tabview-panel-workbench" styleClass="tabview-compo-workbench">
<ng-template pTemplate="header">First Tab</ng-template>
<ng-template pTemplate="content">
some html content
</ng-template>
</p-tabPanel>
<p-tabPanel>
<ng-template pTemplate="header">Second Tab</ng-template>
<ng-template pTemplate="content">
some html content
</ng-template>
</p-tabPanel>
</p-tabView>
</div>
Is there any way to fix this issue? Worst case programmatically.

Angular 5 w/ Angular Material 2 - Optimal Way to load a background?

I'm wondering what's the best way to add a background to the app.component of my Angular 5 Application using Angular Material 2. I've seen a few previous stack overflow posts regarding this in previous versions of Angular and tried using them but to no avail.
So I was looking to see what is the currently reccomended way of doing this in Angular 5 w/ Angular Material 2.
Thank you
Path to the image from this component "../../images/background.jpg"
<div [class.app-dark-theme]="true">
<mat-sidenav-container fullscreen class="sidenav-container">
<!-- The Navigation button at the top of the application -->
<mat-toolbar color="primary">
<div class="select-discord">
<mat-icon svgIcon="thumbs-up"></mat-icon> Discord
</div>
<div class="select-twitch">
<mat-icon svgIcon="thumbs-up"></mat-icon> Twitch
</div>
<div class="select-twitter">
<mat-icon svgIcon="thumbs-up"></mat-icon> Twitter
</div>
<div class="select-youtube">
<mat-icon svgIcon="thumbs-up"></mat-icon> YouTube
</div>
</mat-toolbar>
<img class="img-responsive" src="../../images/background.jpg">
<!-- Main content of the website -->
<div class="app-content">
<mat-card>
text here
</mat-card>
</div>
</mat-sidenav-container>
</div>
A proper way of adding a background would be to add an id to your container and give that id the following css rule:
#my-bg {
background: url('../../images/background.jpg') no-repeat center;
background-size: cover;
}

how to open custom drop-down upwards

Currently, I'm working on a custom AngularJS drop-down, which is represented by the HTML structure below:
<div>
<label></label>
<div>
<a ng-class="{active: popover}">
<div></div> <!-- the selected item -->
</a>
<div style="position: relative;"> <!-- THIS is the div that presents -->
<!-- the list with the menu items-->
<div class="popover" ng-class="{popover-show}">
<input /> <--! this is a search box -->
<ul ng-repeat="item in items">
</ul>
</div>
</div>
</div>
</div>
The rules for .popover and .popover-show are from Twitter Bootstrap but the have the additional rules below:
.popover{
top: 20px;
left: auto;
right: 0;
max-width: none;
border-collapse: separate;
}
.popover.popover-show {
display : block !important;
}
The div with the postition:relative is the one that is wrap
The directive seems to work fine. However, when it's positioned below the middle of the page and it has too many items so it exceeds the window's height by default the vertical scroll of the bar appears. I've been looking to other similar questions, but none of them was close enough to my case. So, my question is what would be the smartest way to detect when I am about to exceed the window height (and of course, the best place to do it - CSS, the directive) and to set the bottom to 0?
Thanks in advance!
UPDATE: I'm trying to get around without using jQuery and the JS files for Twitter Bootstrap
use the data-placement=" " identifier
this is how to do it for a popover:
HTML
Click
JS
<script>
$(document).ready(function(){
$('[data-toggle="popover"]').popover();
});
</script>
For dropdowns this will work, to change from dropping down to dropping up,
HTML
<div class="dropup">
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
</div>