I am working on Angular 2 project with following file structure.
HeaderComponent.ts
AppComponent.ts
Page1Component.ts
Page2Component.ts
I have following template in my HeaderComponent.ts
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">WebSiteName</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li class="active"><a [routerLink]="['']">Home</a></li>
<li><a [routerLink]="['/page1']" >Page1</a></li>
<li><a [routerLink]="['/page2']">Page2</a></li>
</ul>
</div>
</div>
</nav>
with following routes in my AppComponent
#Component({
selector: 'my-app',
template: `
<my-header></my-header>
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES, HeaderComponent]
})
#Routes([
{path: '/', component: HomeComponent},
{path: '/page1', component: Page1Component}
{path: '/page2', component: Page2Component}
])
export class AppComponent {
ngAfterViewInit() {
//To show the active tab in navbar
$(".nav a").on("click", function () {
$(".nav").find(".active").removeClass("active");
$(this).parent().addClass("active");
});
}
}
and my Page1Component has following sample form
<section class="col-md-8 col-md-offset-2">
<form [ngFormModel]="myForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="firstName">First Name</label>
<input [ngFormControl]="myForm.find('firstName')" type="text" id="firstName" class="form-control">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input [ngFormControl]="myForm.find('lastName')" type="text" id="lastName" class="form-control">
</div>
<div class="form-group">
<label for="email">Mail</label>
<input [ngFormControl]="myForm.find('email')" type="email" id="email" class="form-control">
</div>
<div class="form-group">
<label for="password">Password</label>
<input [ngFormControl]="myForm.find('password')" type="password" id="password" class="form-control">
</div>
<button type="submit" class="btn btn-primary" [disabled]="!myForm.valid">Sign Up</button>
</form>
</section>
So when I click on Page1 routerLink in header <li><a [routerLink]="['/page1']">Page1</a></li>, it loads the Page1Component in <router-outlet></router-outlet>. I fill some details in form and when I click on Page1 routerLink again in header before submitting the form, I want Page1Component to reload so my form comes to initial state but it doesn't do anything on click. I tried to reset form in routerOnActivate() and routerCanDeactivate() but none of the functions being called. So basically, I want my component to load again when I click on [routerLink]
Please let me know if I can explain better.
You can take care of this scenario by using dummy route,
<a (click)="changeRoute(url)">
Add one dummy route to your router:
{ path: 'dummy', component: dummyComponent }
dummyComponent.ts
//Dummy component for route changes
#Component({
selector: 'dummy',
template: ''
})
export class dummyComponent{}
Now inside your component add changeRoute function:
changeRoute(url) {
this.router.navigateByUrl('/dummy', { skipLocationChange: true });
setTimeout(() => this.router.navigate(url));
}
// 'skipLocationChange' will avoid /dummy to go into history API
This will re render your component and rest all will be taken care by Angular.
You could use the (click) event an navigate in code to some dummy component and then again back to the previous component. There is a parameter in router.navigate() to skip history changes so the back button keeps working with this hack.
Another approach would be to remove the routerLink, and naviagate via code:
<a (click)="gotoPage1()">
Now gotoPage1 just appends a #X number to existing url
...
count: number = 2;
gotoPage1(){
count++;
return this.router.navigate(...'#'+count);
}
Related
I have a app.component.ts, which is my main component.
There is his app-routing.module.ts, which by default takes you to a "CalibrationComponent" page.
app.component.html
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-collapse">
<ul class="nav navbar-nav">
<li routerLinkActive="active"><a routerLink="auth">Authentification</a></li>
<li routerLinkActive="active"><a routerLink="appareils">Appareils</a></li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-xs-12">
<router-outlet></router-outlet>
</div>
</div>
</div>
My calibration.component.html looks like this:
<p> Calibration works !</p>
<!-- Modal -->
<ng-template #content >
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Profile update</h4>
</div>
<div class="modal-body">
<p> Header body</p>
</div>
<div class="modal-footer">
<p> Header footer</p>
</div>
</ng-template>
<div class="calibrationDiv" *ngIf="startCalibration" >
<input type="button" class="Calibration" id="Pt1">
<input type="button" class="Calibration" id="Pt2">
<input type="button" class="Calibration" id="Pt3">
<input type="button" class="Calibration" id="Pt4">
<input type="button" class="Calibration" id="Pt5">
<input type="button" class="Calibration" id="Pt6">
<input type="button" class="Calibration" id="Pt7">
<input type="button" class="Calibration" id="Pt8">
<input type="button" class="Calibration" id="Pt9">
</div>
And my calibration.component.ts looks like this:
import { Component, Input, ViewChild, AfterViewInit } from '#angular/core';
import { NgbModal, ModalDismissReasons } from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'app-calibration',
templateUrl: './calibration.component.html',
styleUrls: ['./calibration.component.scss']
})
export class CalibrationComponent implements AfterViewInit {
#Input() startCalibration: boolean = true;
#ViewChild("content") content: any;
constructor(private modalService: NgbModal) { }
ngAfterViewInit(): void {
this.modalService.open(this.content);
};
}
When I go to my Calibration component (this is the default route), my modal doesn't show up. Do you know why?
Thanks.
I fixed it.
I had the nodemodule bootstrap 3.7, which is not compatible with ng-bootstrap. I had to upgrade bootstrap to 4.0 and now everything works.
Thanks.
I have some html like this (I won't even bother to post the JS since it's an overcomplicated mess):
<html>
<body>
<div class="container">
<h3 class="text-center">Administration</h3>
</div>
<div class="form-inline text-center">
<div class="form-group">
<label>Managing Business</label>
<select ng-options="business.name for business in businesses" ng-model="managingBusiness" class="form-control restaurant-select"></select>
<label>Program</label>
<select ng-options="program.description for program in selectablePrograms" ng-model="managingProgram" class="form-control restaurant-select"></select>
</div>
</div>
<hr/>
<div class="col-md-2">
<ul class="nav nav-pills nav-stacked">
<li ng-class="{ active: isActive('/admin/overview')}">Overview</li>
<li ng-class="{ active: isActive('/admin/generators')}">Generators</li>
</ul>
</div>
<div class="col-md-10">
<div ng-include="'views/partials/admin/overview.html'" ng-show="isActive('/admin/overview')"></div>
<div ng-include="'views/partials/admin/generators.html'" ng-show="isActive('/admin/generators')"></div>
</div>
</body>
</html>
And the only js that matters is this:
$scope.isActive = function (viewLocation) {
return viewLocation === $location.path();
};
And the issue is that when the user selects a tab to change (overview/generators) than the entire page is reloaded. This is bad because I am trying to keep the state of the selected business at the top.
What am I doing wrong? Why is the page reloading without me running a reload command?
I created app with angularjs 1.5 component router, how could I let parent component pass values to child component inside and child component binds callbacks to the parent component like:
app.js
angular.module('newsApp',['ngComponentRouter'])
.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(true);
}])
.value('$routerRootComponent', 'myNews')
components.js
angular.module('newsApp')
.component('myNews', {
templateUrl: '/myNews.html',
controller: ['newsFactory',ShamraNewsCtrl],
$routeConfig: [
{path: '/', name: 'MyLatestNews', component: 'myLatestNews', useAsDefault: true},
{path: '/:category', name: 'MyNewsList', component: 'myNewsList'},
]
}).component('myLatestNews', {
templateUrl: '/latestNews.html',
controller: ['newsFactory', myLatestNewsCtrl],
}).component('myNewsList', {
templateUrl: '/newsList.html',
controller: ['newsFactory', myNewsListCtrl],
})
myNews.html
<div class="input-group">
<input type="text" class="form-control" ng-bind="$ctrl.query" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn search-btn btn-success" type="submit">
<i class="fa fa-search"></i>
</button>
</span>
</div>
<div>
<div class="sh-news-cat list-group">
<a ng-repeat="(key, catVal) in $ctrl.categories" class="list-group-item" ng-class="{active:$ctrl.select.selected == key}" ng-link="['MyNewsList', {category: key}]">
{{ catVal}}
<span ng-show="$ctrl.selected.spinner == key"><i class="fa-lg fa fa-spinner fa-spin"></i></span>
</a>
</div>
</div>
<div>
<ng-outlet></ng-outlet>
</div>
latestNews.html
<div class="last-news-container">
<div class="latest-news" ng-repeat="(key, newsList) in $ctrl.latestNews">
<h3 class="section-title">
{{ newsList.title}}
</h3>
<hr>
<div class="section-body">
<div class="news-item" ng-repeat="sectionList in newsList.result">
<div class="news-info">
<h3>{{ sectionList.title }}</h3>
<p>{{ sectionList.content }}</p>
</div>
</div>
</div>
<div class="more-news">
<a ng-link="['MyNewsList', {category: key}]" ng-hide="$ctrl.seemore"> see more ... </a>
</div>
</div>
</div>
so when I click on seeMore in latestNews.html I want to (sent to OR change) category value in myNews Component
and when use type in input box i need to pass this value to another component
How to create dropdown menu in AngularJs 2 Javascript?
I have watched alot of tutorials but there is only available for Typescript. i need it in Javascript. Please help.
(function(app) {
app.HeaderComponent = ng.core
.Component({
selector: 'header',
template:
`<nav class="navbar navbar-default">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="" class=" navbar-brand">
<span class="brandname">Slant<sub> AngulatJS</sub></span>
</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li class="dashboarddiv">
Dashboard
</li>
<li></li>
<li>
<div [hidden]="submitted">
<form (ngSubmit)="onSubmit()" #Header="ngForm">
<button type="submit" [disabled]="!Header.form.valid"><span class="glyphicon glyphicon-envelope"></span></button>
</form>
</div>
<div [hidden]="!submitted">
<button (click)="submitted=false"><span class="glyphicon glyphicon-envelope"></span></button>
<h2>You submitted</h2>
<div class="row">
<div class="col-xs-3">Name</div>
<div class="col-xs-9 pull-left">rrr</div>
</div>
<div class="row">
<div class="col-xs-3">Alter Ego</div>
<div class="col-xs-9 pull-left">r</div>
</div>
<div class="row">
<div class="col-xs-3">Power</div>
<div class="col-xs-9 pull-left">r</div>
</div>
</div>
</li>
</ul>
</div>
</nav>`
})
.Class({
constructor: function() {
this.submitted = false;
},
onSubmit: function() {
this.submitted = true;
},
});
})(window.app || (window.app = {}));
I have tried this. but it creates div hide and show. I want dropdown menu in navigation bar.
This is the result of this code
I'm working on one of my first projects in AngularJS, and I'm using ng-view with $routeProvider for my templating, but I've run into a small problem. On a few of my pages (landing, login, and registration) I don't want the navbar to show; but I want the navbar to show on all my other views. What are my options in fixing this problem using AngularJS?
The link below includes the index.html, login.html, and my $routeProvider
index.html
<body ng-app="hello">
<!-- FIXED NAVBAR -->
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">hello</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li>Add Group</li>
<li>Upload File</li>
<li class="active">Notifications</li>
</ul>
</div>
</div>
</div>
<div class="container">
<div ng-view></div>
</div>
</body>
login.html
<div class="container">
<form ng-controller="AdminUserCtrl" class="form-signin" role="form" method="post">
<h2 class="form-signin-heading">Please sign in</h2>
<input type="email" class="form-control" id="inputUsername" placeholder="Email address" ng-model="login.email" required autofocus>
<input type="password" class="form-control" id="inputPassword" placeholder="Password" ng-model="login.password" required>
<div class="checkbox">
<label>
<input type="checkbox" value="remember-me"> Remember Me
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" ng-click="logIn(login.email, login.password)">Sign In</button>
<p style="text-align: center; margin-top: 5px;"><a style="text-align: center;" href="#/register">Register A New Account</a></p>
</form>
$routeprovider
hello.config([ '$locationProvider', '$routeProvider',
function($location, $routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'views/login.html',
controller: 'AdminUserCtrl',
access: { requiredLogin: false}
}).
when('/feed', {
templateUrl: 'views/feed.html',
controller: 'FeedListCtrl',
access: { requiredLogin: true}
otherwise({
redirectTo: '/'
});
}]);
The hack I'm currently thinking of to fix this is taking out the html code for the navbar out of the index and only adding it in the pages I need it, but i was wondering if there is another fix?
The navigation bar and other components that are separate from ng-view should have their own controllers. You can communicate information to these controllers from controllers within the view using a service. Properties of this service can be bound to the navigation views and their display can be updated based on the values of the properties. For example.
app.factory("navBarService", function () {
return {show: true};
});
app.controller("NavBarController", function (navBarService) {
this.show = navBarService.show;
});
app.controller("SomeControllerYouRouteToController", function (navBarService) {
navBarService.show = false;
});