Angular Material - Disable mat-sidenav transition animation but keep children animations? - javascript

I have an Angular app with a mat-sidenav that's structured like this:
<mat-sidenav-container>
<mat-sidenav [mode]="'side'">
<!-- Sidenav content -->
</mat-sidenav>
<mat-sidenav-content>
<!-- Main content -->
</mat-sidenav-content>
</mat-sidenav-container>
I'd like to disable the transition animation for the mat-sidenav but keep the sidenav content's animations (e.g. for a mat-vertical-stepper). However, I haven't been able to find a way to do this.
So far, I've found this similar GitHub issue, but the fixes described there seem to disable the sidenav content's animations too. For example, I've tried the following:
<mat-sidenav-container [#.disabled]="true">
<mat-sidenav [mode]="'side'">
<!-- Sidenav content -->
</mat-sidenav>
<mat-sidenav-content>
<!-- Main content -->
</mat-sidenav-content>
</mat-sidenav-container>
which disables the sidenav transition animation, but also disables all other animations. The following doesn't seem to work either:
<mat-sidenav-container [#.disabled]="true">
<mat-sidenav [mode]="'side'" [#.disabled]="false">
<!-- Sidenav content -->
</mat-sidenav>
<mat-sidenav-content [#.disabled]="false">
<!-- Main content -->
</mat-sidenav-content>
</mat-sidenav-container>
I've also found this article in Angular's documentation, but it seems very complicated and I can't figure out how to apply it to components without custom animations (like the mat-vertical-stepper).
Is there any easy way to disable a mat-sidenav's transition animation while still keeping its children's animations?

This is a workaround.
Temporarily disable it.
Demo
in HTML:
<mat-sidenav-container [#.disabled]="temporaryDisabled">
<mat-sidenav [mode]="'side'" #sidenav>
Sidenav content
</mat-sidenav>
<mat-sidenav-content>
<div class="header">
<button mat-stroke-button (click)="toggle()">toggle sidenav</button>
</div>
<div class="stepper">
<mat-vertical-stepper [linear]="isLinear" #stepper >
(... stepper codes ...)
</mat-vertical-stepper>
</div>
</mat-sidenav-content>
</mat-sidenav-container>
in .ts file:
temporaryDisabled: boolean = false;
toggle(){
this.temporaryDisabled = true;
this.sidenav.toggle();
setTimeout(()=>{
this.temporaryDisabled = false;
},10);
}

using Angular module `NoopAnimationsModule`
1 Import
import {NoopAnimationsModule} from '#angular/platform-browser/animations';
2 ensure you add it to NgModule
#NgModule({
imports: [NoopAnimationsModule]...
})
export class YourMaterialModule { }
To remove animation/transition on some specific components you can also do it via CSS like this
.mat-sidenav{ transition: none; }
Check out this for disableRipple or this answer

Related

change page layout on link click vue.js

I'm learning how to use vue.js
I've a shared hosting plan where I can only use html. I'm fetching the data I need using axios and a remote wordpress installation that will act as a backend only. What I need to know, is how I can change the DOM content of the index.html using vue if the user click on a link and I need to change the layout of the page because a different presentation for the contents is needed?
See the example:
<div id="vue-app">
link to layout 2
<div class="col-12">starting layout </div>
</div>
// after the user click the link (v-on:click) the layout change
<div id="vue-app">
link to layout 1
// layout change
<div class="col-6">new layout </div>
<div class="col-6">new layout </div>
</div>
Please read up on Conditional Rendering in Vue.js.
You can have a boolean variable in the data compartment of your script tag and change it on click.
And in the tags put v-if="your_bool_variable".
<div id="vue-app" v-if="layout_switch">
link to layout 2
<div class="col-12">starting layout </div>
</div>
// after the user click the link (v-on:click) the layout change
<div id="vue-app" v-else>
link to layout 1
// layout change
<div class="col-6">new layout </div>
<div class="col-6">new layout </div>
</div>
Negate the boolean variable at the #click event.
Data could look like the following:
<script>
export default {
name: "YourComponent",
data: () => {
return {
layout_switch: true
}
},
methods: {
changeLayout() {
this.layout_switch = !this.layout_switch;
}
}
}
</script>

Angular lazy load modules from main component

I have the below setup in my app.routing.module.ts.
app.component.html
<router-outlet></router-outlet>
modules/core/components/home/home.component.html
<mat-sidenav-container autosize>
<mat-sidenav #sidenav role="navigation">
<!--this is a place for us to add side-nav code-->
<wn-sidenav-list (sidenavClose)="sidenav.close()"></wn-sidenav-list>
</mat-sidenav>
<mat-sidenav-content>
<!--in here all the content must reside. We will add a navigation header as well-->
<wn-header (sidenavToggle)="sidenav.toggle()"></wn-header>
<main>
<!-- I want the components child components of the home components to be loaded here -->
<router-outlet></router-outlet>
</main>
<wn-footer></wn-footer>
</mat-sidenav-content>
Problem
When I access localhost:4200/campaigns or localhost:4200/dashboard their respective components are displayed but they aren't using their parent's (home.component.html) view
My Goal
I want all sub-components of the home component to be displayed in the router-outlet of the home.component.html and other components will be displayed in the router-outlet of app.component.html
I've had a setup like this before but I wasn't using modules at the time and it was working perfectly. Is there something about lazy loading that I don't understand?
When I access localhost:4200/campaigns or localhost:4200/dashboard the
components of the campaign module are displayed but they aren't using
their parent's (home.component.html) view
In your route config you are using redirectTo:'/dashboard' so that's why you will see the view of campaign modue

Why do background images load when navigating by anchor link but not by routerLink?

I have a feeling the answer to this question is quite simple, but I cannot find an answer to it anywhere. I am build a very simple app with Vue.js (v2.6.11) that consists of just two pages, a home page and another page with a form. Now, on both of these pages, there are several parallax containers made with MaterializeCSS. If you're unfamiliar, a parallax container is basically just a div with an image as its background, and when the user scrolls, the background image moves at a different rate than the foreground of the site.
My problem is that when I navigate from the home page to the page with the form using a Vue.js link, <router-link :to="{name: "FormPage"}>Form Page</router-link>, the images in the parallax containers DO NOT load. However, if I refresh the page, the images load fine and everything is well. Similarly, If I replace the <router-link> with a simple Form Page the images load fine, everything works as it should.
So my question is this: why don't my parallax container images load on the page navigated to with <router-link></router-link>, but then when I navigate to that same page with a the images do load? In other words, what is <router-link></router-link> doing that prevents my parallax container images from loading??
Any and all feedback would be appreciated. Otherwise, I hope you have a marvelous day, and thank you for you time in reading and or answering my question :)
--Update--
CODE:
This is the component on the homepage that contains the link in question:
<template>
<div id="index-banner" class="parallax-container" style="height: 400px;">
<div class="section no-pad-bot">
<div class="container">
<br><br>
<h1 class="header center white-text">{{ translations.title }}</h1>
<div class="row center">
<h5 class="header col s12 white-text light">{{ translations.subtitle }}</h5>
</div>
<div class="row center">
<!-- <router-link :to="{name: 'Generator', force: true }" class="btn-large waves-effect waves-light teal lighten-1 center-align">{{ buttonText }}</router-link> -->
{{ translations.buttonText }}
</div>
</div>
</div>
<div class="parallax"><img :src="img" alt="Unsplashed background img 1"></div>
</div>
</template>
<script>
export default {
name: 'Banner1',
props: {
translations: String,
img: String
},
}
</script>
<style>
</style>
This is the 'view' that is navigated to, containing the parallax containers in question:
<template>
<div>
<PageTitle
:translations="$t('generatorPage.components.pageTitle')"
img="/imgs/parallax5.jpeg"
/>
<SigForm
:translations="$t('generatorPage.components.sigForm')"
/>
<Separator
img="/imgs/parallax5.jpeg"
/>
</div>
</template>
<script>
import PageTitle from '#/components/banner/parallax/PageTitle'
import Separator from '#/components/banner/parallax/Separator'
import SigForm from '#/components/generator/SigForm'
export default {
name: 'Generator',
components: {
PageTitle,
SigForm,
Separator,
}
}
</script>
<style>
</style>
Here is the 'PageTitle' component with a parallax container:
<template>
<div class="parallax-container form-parallax-container">
<h1 class="white-text center">{{ translations.title }}</h1>
<div class="parallax"><img :src="img"></div>
</div>
</template>
<script>
export default {
name: 'PageTitle',
props: {
translations: String,
img: String
}
}
</script>
<style>
</style>
And here is the 'Separator' with a parallax container:
<template>
<div class="parallax-container form-parallax-container">
<div class="parallax"><img :src="img"></div>
</div>
</template>
<script>
export default {
name: 'Separator',
props: {
img: String
}
}
</script>
<style>
</style>
---UPDATE: Complete repo & sandboxed app---
Someone mentioned it would be eaiser if I provided a sandboxed app or whatever to debug it, so I just made the github repo public and also uploaded it to codesandbox.io. You'll notice that on codesandbox.io, the parallax images aren't even loading at all...on the homepage, on the form page, or upon refresh!
Ok so this is not the answer, but I needed to post some code to illustrate.
I have to confess that I'm not fully au-fait with JS frameworks, but I do know materializecss very well. I've been trying to help another user with a React based problem where the sidenav stops working when the react router is used - until he refreshes the page, when it works fine again.
So here's my hunch:
Parallax is a component that needs initialising like so:
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.parallax');
var instances = M.Parallax.init(elems);
});
// Or with jQuery
$(document).ready(function(){
$('.parallax').parallax();
});
If you leave that initialisation code out, it won't work. And, taken from the docs for select fields dynamically added components need reinitialising.
You must initialize the select element as shown below. In addition,
you will need a separate call for any dynamically generated select
elements your page generates.
So my hunch is that when the page is re-rendered via a navigator, we get a new component added to the dom - but this is after the initialisation has already run. So that component is not initialised.
Could be wrong, hope I'm not for your sake more than mine. As I said, I don't know Vue or React very well at all, and my suggestions to run the init at each render didn't work for the React issue - but there are so many moving parts it's hard to rule out.

Modify sidebar component based on content section component in Vue

Here is my template section:
<template>
<!-- START Home.vue section -->
<div class="container-fluid" v-if="user.authenticated">
<!-- START Sidebar.vue section -->
<sidebar-component></sidebar-component>
<!-- END Sidebar.vue section -->
<div class="main-container">
<!-- START Nav.vue section -->
<nav-component></nav-component>
<!-- END Nav.vue section -->
<!-- START Content Section -->
<router-view></router-view>
<!-- END Content Section -->
</div>
</div>
<!-- END Home.vue section -->
</template>
Clearly it has 3 components: NavComponent,SidebarComponent, Main component area that will be replaced by the routed component.
I have another component ApplicationList component that when will replace the router-view section of above template, is supposed to cause the sidebar component to behave differently(say for example sidebar becomes hidden or its background becomes red).
So how do I do it?
Install https://github.com/vuejs/vuex-router-sync . It will give you your current route state in your Vuex.
In your <sidebar-component> just refer to this.$store.state.route.name (or path, or whatever you need) and use it in your v-if or some watch .
This is the easiest and most scalable solution to handle changes in components based on current route in application.
Hope it helps.

paper-drawer-panel defaults to narrow

Using Polymer 1.0 on Firefox 39.0 and Chrome 43.0
Polymer Starter Kit
I essentially have:
<body unresolved class="fullbleed layout vertical">
<template is="dom-bind" id="app">
<paper-drawer-panel id="paperDrawerPanel" narrow="true">
<div drawer>
Drawer
</div>
<div main>
Main
</div>
</paper-drawer-panel>
</template>
</body>
This is from the Polymer Starter Kit.
I removed the forceNarrow attribute from the paper-drawer-panel, and even tried adding the attribute narrow="false", but when I view the site in my browser on my laptop (15" screen), the panel is always in narrow mode. When I look at the narrow attribute in the console, it is set to true.
It is my understanding that both the drawer and the main content to appear side-by-side when the window is larger than responsiveWidth. So why am I not seeing this behavior?
Just add force-narrow NOT forceNarrow to your paper-drawer-panel and remove the javascript. Polymer javascript attributes in camelCase like forceNarrow will be matched to camel-case in HTML.
Using narrow=true won't work as this is the state of the drawer and will effectively hide the element forever.
In Polymer Starter Kit, inside app/scripts/app.js:
window.addEventListener('WebComponentsReady', function() {
document.querySelector('body').removeAttribute('unresolved');
// Ensure the drawer is hidden on desktop/tablet
var drawerPanel = document.querySelector('#paperDrawerPanel');
drawerPanel.forceNarrow = true;
});
The line drawerPanel.forceNarrow = true; forces the drawer panel to be narrow. You can comment out the line in order to get the appropriate behavior.
I believe this was included in the starter kit to demonstrate how to get the opposite behavior of always having a collapsible drawer.

Categories

Resources