Best practice displaying menu and toolbar in Angular2 - javascript

I have a webapplication where a user can log into his account. When the user is logged in now the sidenav(menu) and toolbar appears. But when the user isn't logged in (maybe he is going to login or registrate) the toolbar and sidenav should be not visible.
What is the best practice to do that in Angular2(version: 2.1.0 and angular/router version: 3.1.0)
I tried to disable the toolbar and sidenav with ngIf but It doesn't really work and I think it is not a clean solution.
Then I thought about two <router-outlet>. One for the routing when the user is logged in and one when the user is not logged in. Is this the right way to solve my problem? If yes, how does it work?
Here my app.component.html where I define my toolbar, sidenav and the <router-outlet>:
<md-sidenav-layout class="{{themeService.ActualTheme}}" fullscreen>
<div *ngIf="menuToolbarConfigService.ActualPage !== 'landing' && menuToolbarConfigService.ActualPage !== 'register'">
<md-sidenav #sidenav mode="{{menuToolbarConfigService.setSideNav(sidenav)}}">
<div>
<div class="sidenav-header">
<div class="logo-circle">
<span class="logo">GT</span>
</div>
<span class="user-name">Nico</span>
<span class="open-tasks">Offene Tasks: 4</span>
</div>
<md-list>
<div [ngClass]="{'highlight': menuToolbarConfigService.ActualPage === 'start'}" class="nav-list-item">
<md-list-item>
<md-icon>assignment</md-icon> Taskboard
</md-list-item>
</div>
<div [ngClass]="{'highlight': menuToolbarConfigService.ActualPage === 'groups'}" class="nav-list-item">
<md-list-item>
<md-icon>group</md-icon> Gruppen
</md-list-item>
</div>
<div [ngClass]="{'highlight': menuToolbarConfigService.ActualPage === 'user'}" class="nav-list-item">
<md-list-item>
<md-icon>account_circle</md-icon> Benutzer
</md-list-item>
</div>
<div [ngClass]="{'highlight': menuToolbarConfigService.ActualPage === 'user'}" class="nav-list-item">
<md-list-item>
<md-icon>search</md-icon> Taskbrowser
</md-list-item>
</div>
</md-list>
</div>
</md-sidenav>
</div>
<md-toolbar color="primary">
<span *ngIf="menuToolbarConfigService.ShowMenuIcon" (click)="sidenav.open();" class="menu-icon"><md-icon>menu</md-icon></span>
<span class="app-title">GroupTasking</span>
<!-- This fills the remaining space of the current row -->
<span class="example-fill-remaining-space"></span>
</md-toolbar>
<router-outlet></router-outlet>
</md-sidenav-layout>
Thank you in advance!

Related

Alpinejs is not working for Modal only for Sidebar Menu

I am building a site with Laravel, tailwind css and alpinejs. I have a mobile navigation which is a offcanvas sidebar and a modal shopping cart. The responsive mobile menu works fine but I can not figure out why the modal is not showing:
Layout.blade.php which blade components are placed in :
<body class="bg-[#F8F3F0]" >
<div x-data="{ open: false, opencart: false }" #keydown.window.escape="open = false">
<x-home.cart />
<x-home.mobilenav />
<div class="w-full hexnoisegrad h-[700px]">
...
<x-home.nav />
...
In the home.nav component we have buttons that trigger the menu and modal:
...
<button type="button"
class=" ..."
#click="open = true">
<span class="sr-only">Open sidebar</span>
<x-icon.menu />
</button>
<button type="button"
class=" ..."
#click="opencart = true">
<span class="sr-only">Open Cart</span>
<x-icon.bag/>
</button>
In the home.mobilenav component we have:
<div dir="rtl" x-show="open" class="fixed inset-0 flex z-40 lg:hidden"
x-description="Off-canvas menu for mobile, show/hide based on off-canvas menu state." x-ref="dialog"
aria-modal="true">
...
And finally in the home.cart (modal) component we have:
<div x-data="{ opencart: false }" #keydown.window.escape="opencart = false" x-show="opencart" class="fixed z-10 inset-0 overflow-y-auto" x-ref="dialog" aria-modal="true">
...
I don't know why but Menu works fine and Modal (Shopping Cart) is not!
I think somehow it can not access "opencart" to check for the x-show.
If I change the x-data of cart component to:
x-data="{ opencart: true}"
Modal will open correctly for the first time but after closing the button won't make it appear again.
I Also have drop downs that are working fine with alpine.
Very sorry for long post and taking your time.
Thanks in advance.
Alpinejs documentation indicates
Properties defined in an x-data directive are available to all element children. ref
That implies a parent/child relation between the elements holding x-data and x-show.
So try adding a wrapper div to hold x-data only.
<div x-data="{ opencart: false }">
<div #keydown.window.escape="opencart = false" x-show="opencart" class="fixed z-10 inset-0 overflow-y-auto" x-ref="dialog" aria-modal="true">
...
</div>

cannot get the calendar datepicker to popup - Framework7

I'm making a small app for first time making use of HTML, Javascript and Framework7.
I've installed framework7 and have made the directory and installation of the basic starter
template of files for a blank project...Currently using 'npm start' server, and it returns the default homepage content on the browser. so that's OK...
Right now I only want the 'Calendar/Datepicker' to function. I've gotten the date field to display. But when I try to click it and get the calendar to show, like it does in Framework7 documentation https://v3.framework7.io/docs/calendar.html ,
Nothing comes up. I've now tried multiple times have done just as the guide asked, and there is no response. Is there something extra that I need?
Thanks for any advise.
I've included parts of the code below:
app.js :
import $ from 'dom7'; import Framework7 from 'framework7/bundle';
// Import F7 Styles
import 'framework7/framework7-bundle.css';
// Import Icons and App Custom Styles
import '../css/icons.css'; import '../css/app.css';
// Import Routes
import routes from './routes.js';
// Import Store
import store from './store.js';
// Import main app component
import App from '../app.f7';
var app = new Framework7({
name: 'WeatherStationDat', // App name
theme: 'auto', // Automatic theme detection
el: '#app', // App root element
component: App, // App main component
// App store
store: store,
// App routes
routes: routes,
});
//HERE
var calendar = app.calendar.create({
inputEl: "#calendarinput"
});
home.f7 :
<template>
<div class="page" data-name="home">
<!-- Top Navbar -->
<div class="navbar navbar-large">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a href="#" class="link icon-only panel-open" data-panel="left">
<i class="icon f7-icons if-not-md">menu</i>
<i class="icon material-icons if-md">menu</i>
</a>
</div>
<div class="title sliding">WeatherStationDat</div>
<div class="right">
<a href="#" class="link icon-only panel-open" data-panel="right">
<i class="icon f7-icons if-not-md">menu</i>
<i class="icon material-icons if-md">menu</i>
</a>
</div>
<div class="title-large">
<div class="title-large-text">WeatherStationDat</div>
</div>
</div>
</div>
<!-- Toolbar-->
<div class="toolbar toolbar-bottom">
<div class="toolbar-inner">
Left Link
Right Link
</div>
</div>
<!-- Scrollable page content-->
<div class="page-content">
<div class="block block-strong">
<p>Here is your blank Framework7 app. Let's see what we have here.</p>
</div>
<div class="block block-strong">
<p>enter date</p>
<div class="list no-hairlines-md">
<ul>
<li>
<div class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<!-- HERE -->
<input type="text" placeholder="Your birth date" readonly="readonly" id="calendarinput"/>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script>
export default () => {
return $render;
}
</script>
Ok I figured out a way to get it to work. found out how to do it while debugging another field. I had assumed that because 'var app = new Framework7' code was present in app.js, that's where to put the calendar.create() code. But actually when that code is put in section of home.f7 file, inside 'export default' and 'on pageInit', the
calendar pops up.
notice, $f7.calendar.create() is used in this file, not app.calendar.create(). there actually was one documentation that showed that being done, but I missed it before.
The home.f7 file is used here; I tried putting below script code in app.js
but there was no response from the calendar field.
This is the HTTP that goes in the content section of the home.f7 page:
<!--CALENDAR-->
<div class="block block-strong">
<p>ENTER DATE</p>
<div class="list no-hairlines-md">
<ul>
<li>
<div class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<input type="text" placeholder="Enter date of record" readonly="readonly" id="calendarinput"/>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
At the end of the file there is a section, This code goes in there:
<script>
export default (props, { $, $f7, $on }) => {
$on('pageInit', () => {
let calendarDefault;
calendarDefault = $f7.calendar.create({
inputEl: '#calendarinput',
});
})
return $render;
}
</script>

Auto scroll to bottom with ng-repeat in Ionic

I have a problem that become a realy nightmare. I build a mobile chat app with Ionic, Angular and Firebase. The message exchange works well, but i have problem with auto scroll do bottom when received new messages, i try use $ionicScrollDelegate, scroll-glue Directive, Jquery function and nothing works.
Page chat
<div ng-controller="ChatController as chatCtrl" id="chats_page" class="upage-content vertical-col left hidden has-subheader">
<div class="bar bar-subheader subheader-chat">
<h2 class="title">{{chatCtrl.status}}</h2>
</div>
<div class="" data-uib="layout/row" data-ver="0" id="chatBox">
<ion-content id="autoscroll" class="widget uib_w_92 d-margins topbar" data-uib="ionic/list" data-ver="0" delegate-handle="mainScroll">
<ion-list scroll-glue>
<ion-item ng-repeat="msg in chatCtrl.messages" class="item widget uib_w_93 chat-cliente item-text-wrap" data-uib="ionic/list_item" data-ver="0" ng-class="chatCtrl.getRole(msg.role)">{{msg.text}}<a class="chat-time">{{msg.time}}</a>
</ion-item>
</ion-list>
</ion-content>
</div>
<div class="bar bar-footer footer-chat" >
<i class="placeholder-icon "></i>
<textarea type="text" name="msg" placeholder="Digite sua mensagem..." class="chat-text" ng-disabled="chatCtrl.msgText()" ng-model="myMsg" ></textarea>
<button class="button ion-paper-airplane btn-chat-send" ng-click="chatCtrl.sendMsg(myMsg)" ng-disabled="chatCtrl.msgText()" id='btn_send_chat'></button>
</div>
</div>
And piece of ChatController
angular.module('myApp')
.controller("ChatController", ['User','FireBaseApp','$firebase','$ionicLoading','$timeout','$ionicPlatform','$location','$ionicHistory','$timeout','$ionicPopup','$ionicScrollDelegate','$scope',function(User, FireBaseApp ,$firebase, $ionicLoading,$timeout,$ionicPlatform,$location,$ionicHistory,$timeout,$ionicPopup,$ionicScrollDelegate,$scope){
var self = this;
... pieces of code ...
self.sendMsg = function(msg){
$scope.myMsg = null;
$ionicScrollDelegate.scrollBottom();
}
You can use.
$ionicScrollDelegate.scrollBottom(true);
Example on codepen
After a year i found a solution: Separate my app in angular template and finally scrollglue works.

ngClick on mdListItem and secondary button

I use angular-material (1.0.7) on my project and I would like to create a clickable list (copied from the official doc) with secondary button.
The main issue is the list-item clickable event is also fired when I click on secondary button. In the doc, they show a dialog with targetEvent but it is not what I try to do.
There is my code:
<md-list-item class="md-2-line" ng-repeat="tag in tagsCtrl.showedTags|orderBy:'title'" ng-click="tagsCtrl.navigate(tag)">
<ng-md-icon icon="label"></ng-md-icon>
<div class="md-list-item-text">
<h3>{{ tag.title }}</h3>
<p>{{ tag.slug }}</p>
</div>
<span class="md-secondary" ng-show="tag.onProcess">
<md-progress-circular md-mode="indeterminate" md-diameter="24"></md-progress-circular>
</span>
<span class="md-secondary" ng-hide="tag.onProcess">
<md-button class=" md-icon-button md-hue-3" ng-click="tagsCtrl.editTag(tag, $event)" aria-label="Edit tag">
<ng-md-icon icon="create"></ng-md-icon>
</md-button>
<md-button class=" md-icon-button md-hue-3" ng-click="tagsCtrl.deleteTag(tag)" aria-label="Delete tag">
<ng-md-icon icon="delete"></ng-md-icon>
</md-button>
</span>
</md-list-item>
The navigation function is not a dialog.
Do you know how I can fix this?
I don't know if I understood it right, but you should stop the propagation of the event from bubbling to its parent (in this case from the md-button to the md-list-item)
Check more documentation here jQuery event.stopPropagation() Method
So where you have:
ng-click="tagsCtrl.editTag(tag, $event)"
ng-click="tagsCtrl.deleteTag(tag)"
you can replace with
ng-click="tagsCtrl.editTag(tag, $event) && $event.stopPropagation()"
ng-click="tagsCtrl.deleteTag(tag) && $event.stopPropagation()"

angular material dialog opened on ng-repeat element

I have an array of elements used with ng-repeat. Each element contains md-card directive with ng-click directive that call a function that open angular material dialog window.
After dialog opening my scroll go to the top. But it happens only once after reloading page. Same behavior when I use $mdDialog.hide(result) in dialog controller.
here my html.
<div layout="row" ng-if="!isLoading" ng-repeat="booking in calendarCtrl.currentBookings | orderBy:'start'">
<div class="time" flex="15" layout="column" layout-align="start end">
<span ng-bind="::booking.start"></span>
<span ng-bind="::calendarCtrl.calculateEndTime(booking.start,booking.time)"></span>
</div>
<md-card flex ng-click="calendarCtrl.openDialog(booking,$event)">
<md-card-header>
<md-card-avatar>
<img ng-src="imgs/logo.png" class="md-user-avatar" alt="img"/>
</md-card-avatar>
<md-card-header-text layout="row">
<span flex class="md-title" ng-bind="::booking.client"></span>
<span ng-if="!booking.confirmed" class="isUnread"></span>
</md-card-header-text>
</md-card-header>
<div class="service" layout="column">
<span class="md-body-1">
<span ng-if="booking.phone" ng-bind="::booking.phone"></span>
<span ng-if="booking.phone && booking.email"> | </span>
<span ng-if="booking.email" ng-bind="::booking.email"></span>
</span>
<span ng-style="calendarCtrl.setColor(booking.reservationTypeName,0.5)">
<span class="circle" ng-style="calendarCtrl.setColor(booking.reservationTypeName,1)"></span>
<span class="text" ng-bind="booking.reservationTypeName"></span>
</span>
</div>
<div ng-if="calendarCtrl.checkComment(booking.comment)">
<hr/>
<md-card-content>
<div class="description">
<p ng-bind="::booking.comment"></p>
</div>
</md-card-content>
</div>
</md-card>
</div>
and function calendarCtrl.openDialog(booking,$event)
function openDialog(booking,event){
dialogService.openDialog(booking,event,self.reservationTypes.get(booking.reservationTypeName))
.then(function(answer) {
console.log(`You confirm booking with id: ${answer.id}`);
console.log(answer)
}, function() {
console.log('You close the dialog.');
});
}
and dialogService.openDialog function
function openDialog(booking,event,color){
return $mdDialog.show({
templateUrl: 'dialog/dialog.html',
controller: 'dialogController',
controllerAs: 'dialogCtrl',
parent: angular.element(document.body),
targetEvent: event,
clickOutsideToClose:true,
locals:{
booking:booking,
color:color
}
})
}
Please help.

Categories

Resources