Angular Material 2 - Not rendering in full page - javascript

I am using Angular Material 2 for my Angular 2 app. My dashboard page is not rendering full page in the browser. Attached is the screenshot of the above mentioned issue.
AppComponent - Template file:
<router-outlet></router-outlet>
DashboardComponent - Template file :
<md-sidenav-layout>
<md-sidenav #sidenav mode="side" class="app-sidenav md-sidenav-over" (open)="list.focus()">
<ul #list>
<li> Item 1</li>
<li> Item 2</li>
<li> Item 3</li>
</ul>
</md-sidenav>
<md-toolbar color="primary">
<button class="app-icon-button" (click)="sidenav.toggle()">
<i class="material-icons app-toolbar-menu">menu</i>
</button>
<span class="margin-left10"> Angular Material2 Portal </span>
<span class="app-toolbar-filler"></span>
<button md-button router-active [routerLink]=" ['Index']">
Index
</button>
<button md-button router-active [routerLink]=" ['Home']">
{{ 'HOME.TITLE' | translate }}
</button>
<button md-button router-active [routerLink]=" ['About'] ">
{{ 'ABOUT.TITLE' | translate }}
</button>
</md-toolbar>
<div class="app-content">
<md-card>
Dashboard Content Goes Here..!!
</md-card>
</div>
<footer>
<span id="footerText">Dashboard Footer</span>
</footer>
</md-sidenav-layout>
DashboardComponent.ts:
import {Component, Inject, ElementRef, OnInit, AfterViewInit} from '#angular/core';
import {TranslatePipe} from 'ng2-translate/ng2-translate';
console.log('`Dashboard` component loaded asynchronously');
#Component({
selector: 'dashboard',
styles: [
require('./dashboard.component.css')
],
template: require('./dashboard.component.html'),
pipes: [TranslatePipe]
})
export class Dashboard implements {
elementRef:ElementRef;
constructor(#Inject(ElementRef) elementRef:ElementRef) {
this.elementRef = elementRef;
}
ngOnInit() {
console.log('hello `Dashboard` component');
}
}
Am I missing something here ?
Please refer :
Screenshot of my half-page rendered dashboard page
Appreciate your help.

You are missing the fullscreen attribute inside of the md-sidenav-layout tag.
This attribute will add these properties to the md-sidenav-layout:
[_nghost-oog-2][fullscreen] {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
It's not very well documented quite yet that such an attribute can be added to the md-sidenav-layout since it is still in alpha. But within this preview at ngconf they demonstrate some of what you can currently use from Material 2.

Related

I don't know how to create a changeable text for a reusable component in Vue Js

I was creating a reusable tabs component by watching tutorial. Having watched it, I figured out how it works. But, as for my project, I need to create tabs with heading containing a title that can be changed because this is a reusable component, so I have to change each heading's title for each new tab, but I haven't figured out how to do it. I need somehow to get title from component TabsWrapper that I added to my page
<div class="tab_header">{{title}}</div>
and then make this title change a text inside this div that is the main header of a TabsWrapper component.
<div class="tab_header">{{title}}</div>
My code:
The first one is the code out of component that I added to my homepage of the website.
<TabsWrapper>
<Tab title="Tab 1">Hello 1</Tab>
<Tab title="Tab 2">Hello 2 </Tab>
<Tab title="Tab 3">Hello 3</Tab>
<Tab title="Tab 4">Hello 4</Tab>
</TabsWrapper>
The second one is the code inside the component that is responsible for TabsWrapper
<template>
<div class="tabs">
<div class="tab_header"></div>
<ul class="tabs_header">
<li
v-for="title in tabTitles"
:key="title"
#click="selectedTitle = title"
:class=" {selected: title ==selectedTitle}"
>
{{ title }}
</li>
</ul>
<slot />
</div>
</template>
<script>
import { ref} from 'vue';
import { provide } from 'vue';
export default{
setup(props,{slots}){
const tabTitles=ref(slots.default().map((tab)=> tab.props.title))
const selectedTitle=ref(tabTitles.value[0])
provide("selectedTitle", selectedTitle)
return{
selectedTitle,
tabTitles,
}
}
}
</script>
This chunk of code takes each title from Tab
<Tab title="Tab 1">Hello 1</Tab>
And this chunk of code renders it out
<li
v-for="title in tabTitles"
:key="title"
#click="selectedTitle = title"
:class=" {selected: title ==selectedTitle}"
>
{{ title }}
</li>
I've tried to repeat the same technique, but it worked out, but I think that there's the better way to do it
<div class="tabs">
<div class="tab_header" v-for="headtitle in headTitles" :key="headtitle">{{headtitle}}</div>
<ul class="tabs_header">
<li
v-for="title in tabTitles"
:key="title"
#click="selectedTitle = title"
:class=" {selected: title ==selectedTitle}"
>
{{ title }}
</li>
</ul>
<slot />
</div>
</template>
<script>
import { ref} from 'vue';
import { provide } from 'vue';
export default{
setup(props,{slots}){
const tabTitles=ref(slots.default().map((tab)=> tab.props.title))
const headTitles=ref(slots.default().map((tab)=>tab.props.headtitle))
const selectedTitle=ref(tabTitles.value[0])
provide("selectedTitle", selectedTitle)
return{
selectedTitle,
tabTitles,
headTitles,
}
}
}
</script>
You can simply pass props in the script tag and directly access them using this keyword and prop name.
export default {
props: ['foo'],
created() {
// props are exposed on `this`
console.log(this.foo)
}
}
In the template tag like this
<span>{{ foo }}</span>
you don't need to use ref you can directly use v-for and loop over the array elements.
<li v-for="(item, index) in foo">
{{item}}
</li>

Passing context to tooltip of ngx bootstrap

I'm working with tooltip in ngx-bootstrap, and want to pass data to the ng-template being to the tooltip. The documentation provides [tooltipContext], but it didn't seem to be working. I have provided a code snippet.
HTML:
<ng-template #tooltipTmpl let-view="view">
<div class="tooltip-section">
<div class="section-title">
{{ view.dateRangeText }}
</div>
<div class="section-text">
{{ view.data }}
</div>
</div>
</ng-template>
<div
*ngIf="view.isVisible"
[tooltip]="tooltipTmpl"
[tooltipContext]="{view: view}"
containerClass="white-tool-tip"
placement="top"
>
<div class="sub-title">
{{ view.title }}
</div>
</div>
REF: https://valor-software.com/ngx-bootstrap/#/tooltip
I have used bootstrap popover in my projects, so would recommend using popover.
Also, there was an issue created on GitHub but the user ended up using popover -
https://github.com/valor-software/ngx-bootstrap/issues/4775
#Yiu Pang Chan - you can have views array with following approach.
In app.component.html file
<div *ngFor="let view of views; let i = index">
<button type="button" class="btn btn-success"
*ngIf="view.isVisible"
[tooltip]="tooltipTmpl" on-mouseover="setTooltipData(view)" >
Show me tooltip with html {{ view.title }}
</button>
</div>
<ng-template #tooltipTmpl>
<h4>
{{ viewDateRangeText }}
</h4>
<div>
<i>
{{ viewData }}
</i>
</div>
</ng-template>
In app.component.ts file
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
public viewDateRangeText: string;
public viewData: any;
setTooltipData(view: any){
viewDateRangeText = view.dateRangeText;
viewData = view.data;
}
}
I have face the same problem , so far I have check the source code the tooltipContext mark as deprecated you can do a work a round thi like this
you can still access to the view property inside the ng-template
<button type="button" class="btn btn-success"
*ngIf="view.isVisible"
[tooltip]="tooltipTmpl">
Show me tooltip with html {{ view.title }}
</button>
<ng-template #tooltipTmpl>
<h4>
{{ view.dateRangeText }}
</h4>
<div>
<i>
{{ view.data }}
</i>
</div>
</ng-template>
demo 🔥🔥
Updated 🚀🚀
incase you want to use my solation with array of views , you juest need to move ng-template to the body of the ngFor.
template
<ng-container *ngFor=" let view of views">
<button type="button" class="btn btn-success"
*ngIf="view.isVisible"
[tooltip]="tooltipTmpl">
Show me tooltip with html {{ view.title }}
</button>
<ng-template #tooltipTmpl>
<h4>
{{ view.dateRangeText }}
</h4>
<div>
<i>
{{ view.data }}
</i>
</div>
</ng-template>
<br>
<br>
</ng-container>
demo 🚀🚀
#rkp9 Thanks for the codes. It does solve the issue, but it added viewDateRangeText, viewData, and setTooltipData in the TS codes.
I went with the approach #MuhammedAlbarmavi suggested, since it is without extra variables and functions. The comment on Github didn't have the configuration that we need for popover to act like a tooltip. I have it in the following.
<ng-template #tooltipTmpl let-view="view">
<div class="tooltip-section">
<div class="section-title">
{{ view.dateRangeText }}
</div>
<div class="section-text">
{{ view.data }}
</div>
</div>
</ng-template>
<div
[popoverContext]="{ view: view }"
[popover]="tooltipTmpl"
triggers="mouseenter:mouseleave"
placement="top"
>
<div class="sub-title">
{{ view.title }}
</div>
</div>

Vuejs toggle class to the body on button click in a components

I want to toggle a class to the body or to the root element("#app") if I click on the button inside the header component
Header.vue :
<template lang="html">
<header>
<button class="navbar-toggler navbar-toggler align-self-center" type="button" #click="collapedSidebar">
<span class="mdi mdi-menu"></span>
</button>
</header>
</template>
<script>
export default {
name: 'app-header',
data: {
isActive: false
},
methods: {
collapedSidebar() {
}
}
}
</script>
App.vue :
<template lang="html">
<div id="app" :class="{ active: isActive }">
...
</div>
</template>
! Please correct me if I'm in the wrong direction. I'm new in Vuejs :)
You can emit an event inside your header and maybe catch it in the mounted of app component like this:
In your sidebar or other component:
on_some_btn_click: function (){
this.$emit('toggle_root_class');
}
In your app component:
mounted: function(){
var _this = this;
this.$on('toggle_root_class', function(){
_this.active = !_this.active;
});
}
Vue may restrict event from being observed in sibling components. So I use EventBus in my projects to handle sending events easily.
the problem lies in your component scope. You tried to access data in Header.vue in App.vue which is impossible by the structure in showed in your code. Consider moving isActive data to App.vue or use Vuex.
You can use jquery to toggle class for an element which is not inside the Vue template.
You can call a function on click of a button and inside it, you can toggle class in body tag using jquery.
<template lang="html">
<header>
<button class="navbar-toggler navbar-toggler align-self-center" type="button" :class="{ active: isActive }" #click="activeLink">
<span class="mdi mdi-menu"></span>
</button>
</header>
</template>
<script>
export default {
name: 'app-header',
data: {
isActive: false
},
methods: {
activeLink() {
$('body').toggleClass('.class-name');
}
}
}
</script>

How to have nested routerLink in Angular

I have a project in angular 7
I have router links with <a> tag, and I have nested <a> tags that both have routerLink property,
the issue I am facing is , the inner <a> route doesn't work
<a [routerLink]="[ './comp1']">
Comp1
<a [routerLink]="['./comp2']">
Navigate to comp2 (Nested)
</a>
</a>
this is working if I separate it
<div>
<a [routerLink]="['./comp2']">
Navigate to comp2 (Not Nested)
</a>
</div>
Also I tried the below code and still same
<a [routerLink]="[ './comp1']">
Comp1
<a [routerLink]="['./comp2']" (click)="$event.preventDefault()>
Navigate to comp2 (Nested)
</a>
</a>
changing a tags to span also doesn't solve the issue
<span [routerLink]="[ './comp1']" >
Comp1
<span [routerLink]="['./comp2']" (click)="$event.preventDefault()">
Navigate to comp2 (Nested)
</span>
</span>
Here is the https://stackblitz.com/edit/angular-nested-router for it
In your stackblitz add the following function to your component class. It receives the event as parameter and calls the stopPropagation function on it.
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
stop(event: Event) {
event.stopPropagation();
}
}
In your template do
<router-outlet></router-outlet>
<a routerLink="/comp1">
Comp1
<a routerLink="/comp2" (click)="stop($event)">
Navigate to comp2 (Nested)
</a>
</a>
See my stackblitz fork.

Angular2 Route events

I'm using Angular2 routing and I need to subscribe to an event when route is changed. (i.e. user clicked on one of the route links). The important thing is that the event should be when the new view HTML is inserted to DOM.
Are there any events like onNavigating and onNavigated, so I can subscribe to?
I've found a couple of examples on stackoverflow and tried to use them (see constructor below), but that didn't work. Any ideas?
/// <reference path="../../typings/tsd.d.ts" />
import {Component, View} from 'angular2/angular2';
import {RouteConfig, Router, RouterOutlet, RouterLink} from 'angular2/router';
#RouteConfig([...])
#Component({
selector: 'app'
})
#View({
directives: [RouterOutlet, RouterLink],
template: `
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<span class="mdl-layout-title">Test</span>
<div class="mdl-layout-spacer"></div>
<nav class="mdl-navigation mdl-layout--large-screen-only">
<a class="mdl-navigation__link" [router-link]="['/routelink1']">routelink1</a>
</nav>
</div>
</header>
<main class="mdl-layout__content" style="padding: 20px;">
<router-outlet></router-outlet>
</main>
</div>
`
})
export class App {
constructor(private router: Router){
router.subscribe((val) => function(){...}); //here is I need to process HTML
}
}
I ended up with having base class for my routing components and it contains routerOnNavigate override.
import {OnActivate, ComponentInstruction} from 'angular2/router';
export class BaseView implements OnActivate {
routerOnActivate(next: ComponentInstruction, prev: ComponentInstruction) {
componentHandler.upgradeDom();
}
}

Categories

Resources