I am building a sample project named : Tennis Club Management using Angular 10. In this i have app component and dashboard component. In app.component.html, i have created login which takes 2 inputs username and password and contains login button. Now on login button click , it should validate the fields and navigate it to dashboard.html.
Below are the code files and screenshots
app.component.html
<div class="backgroundDiv">
<!-- <div>-->
<!-- <img class="img-fluid backgroundimage" src="https://rrtennis.co.uk/wp-content/uploads/2017/04/Restyled-Logo-2-SD-small.png" alt="Tennis Logo">-->
<!-- </div>-->
<div class="text-center">
<img class="rounded mx-auto d-block" src="https://rrtennis.co.uk/wp-content/uploads/2017/04/Restyled-Logo-2-SD-small.png" alt="Tennis Logo">
<div class="text-center">
<table class="table table-borderless">
<tr><h6>Admin Login</h6></tr>
<tbody>
<tr>
<th class="col-xs-5">Username</th>
<td class="col-xs-5"><input type="text" #username></td>
</tr>
<tr>
<th class="col-xs-5">Password</th>
<td class="col-xs-5"><input type="password" #password></td>
</tr>
<tr>
<td class="col-xs-5"><button class="btn btn-primary" (click)="validateLogin(username.value,password.value)">Login</button></td>
<td class="col-xs-5"><label class="forgot-password">Forgot Password ?</label></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- https://www.usta.com/content/dam/usta/Articles/article-primary/18309_C_NY_20_USTA_ZoomBackgroundsVisitOrlando_3.jpg -->
<!-- https://i.pinimg.com/originals/81/23/d4/8123d454ca0cc8f36d311cebbd5d3922.png -->
app.component.ts
import {Component} from '#angular/core';
import {Router} from '#angular/router';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Tennis-Angular';
constructor(private router: Router) {}
// tslint:disable-next-line:typedef
validateLogin(username: string, password: string) {
if (username === 'mohit' && password === 'sharma') {
// alert('Login Successful !');
this.router.navigate(['../dashboard']);
} else if (username === '' && password === '') {
alert('Email and Password cannot be blank !');
} else if (username === '') {
alert('Email cannot be blank !');
} else if (password === '') {
alert('Password cannot be blank !');
} else {
alert('Incorrect Email or Password !');
}
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import {FormsModule} from '#angular/forms';
import { DashboardComponent } from './dashboard/dashboard.component';
import {RouterModule, Routes} from '#angular/router';
const appRoutes: Routes = [
{path: 'dashboard', component: DashboardComponent}
];
#NgModule({
declarations: [
AppComponent,
DashboardComponent
],
imports: [
BrowserModule,
NgbModule,
FormsModule,
RouterModule.forRoot(appRoutes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.css
.backgroundDiv {
background: url('https://www.usta.com/content/dam/usta/Articles/article-primary/18309_C_NY_20_USTA_ZoomBackgroundsVisitOrlando_3.jpg') no-repeat center center fixed;
position: fixed;
top: 0;
left: 0;
min-width: 100%;
min-height: 100%;
opacity: 0.80;
}
.table {
display: block;
margin: 0 auto;
height: auto;
width: 25%;
background-color: white;
/*margin-top: 15%;*/
text-align: center;
}
.btn-primary {
margin-left: 20%;
margin-top: 10%;
}
.forgot-password {
margin-top: 8%;
}
img {
margin: 0 auto;
height: auto;
position: relative;
margin-top: 5%;
margin-left: 50%;
max-width: 25%;
height: auto;
}
tbody {
background-color: white;
}
h6 {
margin-left: 100%;
width: 150%;
margin-top: 5%;
color: mediumseagreen;
text-shadow: mediumseagreen;
}
dashboard.component.html
<p>dashboard works!</p>
Screenshots
Home Page Login
Note : The problem is after login , the URL shows the navigation route(path), but the page is not getting displayed. Any solution please ?
There is no <router-outlet></router-outlet> in you app.component.html.
I would suggest create a login component and move your app component code to login component and have alone on your app.component.html.
So whenever you change route your previous component HTML won't render.
Related
I need help expanding a table. For example, when I click on the full-screen icon the table covers the whole page. I'm trying to do this way but it's not working, I didn't get any errors, but the script is working because is changing the class name.
These are the codes. The card.component.html file is the model that complements the dashboard.component.html. The
card.component.ts has the full-screen code, and dashboard.component.html has the table.
File card.component.html
<div class="card {{ fullCard }} {{ cardLoad }}" [#cardClose]="cardClose"
[ngClass]="cardClass">
<div class="card-header" *ngIf="title">
<h5>{{ title }}</h5>
<span *ngIf="!classHeader">{{ headerContent }}</span>
<span *ngIf="classHeader">
<ng-content select=".code-header"></ng-content>
</span>
<div class="card-header-right">
<ul class="list-unstyled card-option">
<li *ngIf="!isCardToggled" (click)="this.isCardToggled=
!this.isCardToggled"><i class="icofont icofont-simple-left"></i></li>
<li *ngIf="isCardToggled" (click)="this.isCardToggled=
!this.isCardToggled"><i class="icofont icofont-simple-right"></i></li>
<li *ngIf="isCardToggled"><i class="icofont icofont-maximize {{
fullCardIcon }} full-card" (click)="fullScreen($event)"></i></li>
<li *ngIf="isCardToggled"><i class="icofont icofont-minus minimize-card"
appCardToggleEvent (click)="toggleCard($event)"></i></li>
</ul>
</div>
</div>
<div [#cardToggle]="cardToggle">
<div class="card-body" [ngClass]="blockClass">
<ng-content></ng-content>
</div>
</div>
<div class="card-loader" *ngIf="loadCard"><i class="icofont icofont-refresh
rotate-refresh"></i></div>
</div>
File card.component.ts
import { Component, OnInit, Input, ViewEncapsulation } from '#angular/core';
import {cardToggle, cardClose} from './card-animation';
#Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.scss'],
animations: [cardToggle, cardClose],
encapsulation: ViewEncapsulation.None
})
export class CardComponent implements OnInit {
#Input() headerContent: string;
#Input() title: string;
#Input() blockClass: string;
#Input() cardClass: string;
#Input() classHeader = false;
cardToggle = 'expanded';
cardClose = 'open';
fullCard: string;
fullCardIcon: string;
loadCard = false;
isCardToggled = false;
cardLoad: string;
constructor() { }
ngOnInit(): void {
}
toggleCard(event: any) {
this.cardToggle = this.cardToggle === 'collapsed' ? 'expanded' : 'collapsed';
}
closeCard(event: any) {
this.cardClose = this.cardClose === 'closed' ? 'open' : 'closed';
}
fullScreen(event: any) {
this.fullCard = this.fullCard === 'full-card' ? '' : 'full-card';
this.fullCardIcon = this.fullCardIcon === 'icofont-resize' ? '' : 'icofont-resize';
}
appCardRefresh() {
this.loadCard = true;
this.cardLoad = 'card-load';
setTimeout( () => {
this.cardLoad = '';
this.loadCard = false;
}, 3000);
}
}
File dashboard.component.html
<div class="col-md-12 col-xl-8 left">
<app-card [title]="'Squads Information'"
[cardClass]="'project-task'" [blockClass]="'p-b-10'">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Squad</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="task-contain">
<h6 class="bg-c-blue d-inline-block text-center">A</h6>
<p class="d-inline-block m-l-60 table-text">AG Technology I</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<app-card>
</div
File styles.scss
.pcoded {
.card {
&.full-card {
position: fixed;
top: 80px;
z-index: 99999;
box-shadow: none;
right: 0;
border-radius: 0;
border: 1px solid #ddd;
width: calc(100vw - 287px);
height: calc(100vh - 80px);
&.card-load {
position: fixed;
}
}
&.card-load {
position: relative;
overflow: hidden;
.card-loader {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
background-color: rgba(255, 255, 255, 0.7);
z-index: 999;
i {
margin: 0 auto;
color: #ab7967;
font-size: 20px;
}
}
}
}
&[vertical-nav-type="expanded"] .card.full-card {
width: calc(100vw - 287px);
}
&[vertical-nav-type="collapsed"] .card.full-card {
width: calc(100vw - 97px);
}
&[vertical-nav-type="offcanvas"] .card.full-card {
width: 100vw;
}
}
How to change this template driven form to Reactive form? I want to change this template driven form to reactive form. What changes shall I do to change it to Reactive form? The code is complete no other modification is required? Can someone please help me with this, I am attaching all the required codes. What things we should keep in mind while changing to reactive form, also why reactive form is preferred over template driven form?
HTML code
<html>
<body>
<nav>
<div class = "navbar-header">
Image Change on clicking Enter in TextBox
<input class = "col" type = "text" readonly value ="{{imgNumber}}/3 {{cityImageId}}">
</div>
</nav>
<div class = "textarea" contenteditable #scrollDiv [scrollTop]="scrollDiv.scrollHeight" wrap="hard">
<img contenteditable="false" [src]="imagePath" width = "1090px" height = "440"/>
</div>
<form>
<div>
<input type = "text" class="col2" [(ngModel)]="pincode" (keyup.enter)="generatecityDetailArray()" maxlength="6" [ngModelOptions]="{standalone: true}"/>
</div>
</form>
<div>
<input type = "label" class = "col3" value = "Pin Code" readonly />
</div>
</body>
</html>
CSS code
nav {
background-color:black;
border : 0;
}
.navbar-header{
text-align: center;
}
.navbar-header{
color:white;
}
.col{
margin-left: 950px;
text-align: right;
border : 0;
background-color:rgb(160,0,0);
}
.textarea{
overflow: scroll;
height: 400px;
width:1090px;
background-color:white;
margin-left: 100px;
margin-top: 50px;
object-fit: none;
object-position: 1000px 200px;
}
.col2{
width:230px;
height: 30px;
margin-top: 20px;
margin-left: 950px;
}
.col3{
width:230px;
height: 30px;
margin-top: 20px;
margin-left: 950px;
}
TypeScript Code
import { Component, OnInit } from '#angular/core';
import { CityClassificationService } from 'src/app/service/city-classification.service';
#Component({
selector: 'app-city-classification',
templateUrl: './city-classification.component.html',
styleUrls: ['./city-classification.component.css']
})
export class CityClassificationComponent implements OnInit {
imgNumber : number =-1;
cityImageId : number = -1;
imagePath : string ='';
pincode:string='';
curImageNumber:number=0;
imageDetails:{imageName:string,cityImageId:number,imgNumber:number}[]=[];
cityDetailArray :{ pincode : string; cityImageId : number; imgNumber:number;}[] = [];
constructor(private cityService:CityClassificationService) { }
ngOnInit(): void {
this.imageDetails=this.cityService.getImageObject();
this.getNextImage(this.imageDetails[this.curImageNumber]);
}
getNextImage(imageObj:{imageName:string,cityImageId:number,imgNumber:number}):void{
this.imgNumber= imageObj.imgNumber;this.imagePath=`assets/images/${imageObj.imageName}.png`;this.cityImageId=imageObj.cityImageId;
}
generatecityDetailArray():void{
if(this.pincode=='' || this.pincode.toString().length>6){alert('Enter Valid PinCode');return;};
this.cityDetailArray.push(
{pincode:this.pincode, cityImageId:this.cityImageId, imgNumber:this.imgNumber}
);
this.pincode='';
this.curImageNumber++;
if(this.curImageNumber==this.imageDetails.length){this.submitForm();return;}
this.getNextImage(this.imageDetails[this.curImageNumber]);
}
submitForm(){
//TODO here....
this.cityService.getAPi(this.cityDetailArray);
}
}
Model class
export class CityClassification{
pinCode : string;
cityImageId : number;
imgNumber:number;
constructor(pinCode : string, cityImageId : number,imgNumber:number){
this.pinCode = pinCode;
this.cityImageId = cityImageId;
this.imgNumber = imgNumber;
}
}
Service class
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class CityClassificationService {
imageDetails:{imageName:string,cityImageId:number,imgNumber:number}[]=[
{imageName:'Ghazipur1',cityImageId:101,imgNumber:1},
{imageName:'Nashik2',cityImageId:102,imgNumber:2},
{imageName:'Noida3',cityImageId:103,imgNumber:3}
]
constructor() { }
getAPi(formBody:any){
//API TO SUBMIT FORM.....
console.log('INSIDE SERvice.......',formBody);
}
getImageObject():any{
//API HERE TO GET IMAGE
return this.imageDetails;
}
}
here is a simple code snippet for you,
Lets say you have component name as AppComponent,
import { Component } from '#angular/core';
import {
FormBuilder,
FormGroup,
FormControl,
Validators
} from '#angular/forms';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'stackoverflow-examples';
declare MultipleSelect: any;
textInputForm: FormGroup;
get textInputControl() {
return this.textInputForm.get('textInputControl') as FormControl;
}
constructor(
private fb: FormBuilder
) {
this.textInputForm = new FormGroup(
{
textInputControl: new FormControl('', [Validators.maxLength(6)])
}
);
}
ngOnInit() {
}
onClick(): void{
// Just to show you that form can read the values,
console.log(this.textInputForm.getRawValue());
}
}
Your Html can look like this below,
<form>
<label>
Input Name:
<input type="text" class="col2" [formControl]="textInputControl" maxLength="6"/>
</label>
</form>
<button (click)="onClick()">Click</button>
<div class="panel-body rc-bl rc-br">
<form ngForm class="form-group">
<div style="position: relative; overflow: hidden; width: 100%; margin: 0px 0px 0px 0px;">
<!-- Col 1 start -->
<div style="display: inline-block; width: 130px; margin: 0px 0px 0px 0px; vertical-align: middle;" class="labelRed12">
<label for="wslr_name">Wholesaler:</label>
</div>
<!-- Col 2 start -->
<div style="display: inline-block; margin: 0px 0px 0px 0px; vertical-align: middle">
<select style="width: 250px;" id="wslr_name" name="wslr_name" [(ngModel)]="Group.wslr_name" (change)=wslrSelect(Group.wslr_name)>
<option *ngFor="let c of wslrList.result">{{c.A}}</option>
</select>
</div>
This is the HTML file in Angular. I need dropdown list based on filtering.
If I give "A" in the search box, I should get all the data starting with "A" only.
There is an NPM-PACKAGE called ng2-search-filter, this will definitely help you.
You should install the package -> npm i ng2-search-filter --save
Import the module in app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app';
import { Ng2SearchPipeModule } from 'ng2-search-filter'; // <-- HERE
#NgModule({
imports: [BrowserModule, Ng2SearchPipeModule], // <-- HERE
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
Then you should create a search field:
<input type="text" [(ngModel)]="searchText">
in your component.ts file declare the searchText variable as public.
<option *ngFor="let c of wslrList.result | filter: searchText">{{c.A}}</option>
when typing something in the search field you should see your dropdown being filter by the typed letter/number (anything typed).
HTML
<div class="nav--small nodeLevel newColor" id="rowItem-{{i}}" *ngFor="let root of rootzTemplates; let i=index" (click)="nodeClickLevel1(root,i)">
<p style="padding: 19px 1px;color: #fff; text-align: center;">
{{root}}
</p>
</div>
CSS
.activeColor {
background-color: grey;
}
JavaScript
constructor(private el: ElementRef) { }
nodeClickLevel1(root, id){
this.myTag = this.el.nativeElement.querySelector("#rowItem-" + id);
this.myTag.classList.remove('activeColor');
this.myTag.classList.add('activeColor');
}
Now div is dynamic, say number of div element is 6, on click event i have to change particular clicked div background-color to grey and rest of color should remain same.
Now if I click on div say 2, only 2nd div has highlight with grey color, rest of the color should remain same and vice versa.
Change your function like this
nodeClickLevel1(root, id){
this.myTag = root
}
change your template code like this
[class.newColor]="root === myTag"
Hope it will solve your problem.
Your code can be much simpler, no need for troublesome ElementRef, no need for index ids, etc.
So here is the code:
//our root app component
import { Component, NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
#Component({
selector: 'my-app',
// templateUrl: "app.html",
template: `
<div class="nav--small nodeLevel newColor" [class.activeColor]="root === myTag" *ngFor="let root of rootzTemplates" (click)="nodeClickLevel1(root)">
<p style="padding: 19px 1px;color: #fff; text-align: center;">{{root}}</p>
</div>
`,
})
export class App {
name: string;
constructor() { }
protected myTag:any;
public rootzTemplates: any[] = ["first", "2nd", "3rd"];
nodeClickLevel1(root){
this.myTag = root;
}
}
#NgModule({
imports: [BrowserModule],
declarations: [App],
bootstrap: [App],
})
export class AppModule {}
and css:
.activeColor {
background-color: grey !important;
}
.nav--small{
background-color: black;
}
Here is the working PLNKR link:
http://plnkr.co/edit/oRZa3E5WtYpusKHd
How do I move my html section from app.compontent.ts to a seperate html documenet? It wont work to just att the html code into the generated class app.component.ts.
Also I would like to move the css section as well to seperate css document.
If someone could help me or point me to the right direction I would be greatfull
import { Component } from '#angular/core';
import { Hero } from './hero';
import { HeroService } from './hero.service';
import { OnInit } from '#angular/core';
#Component({
selector: 'app-root',
template: `
<h1>{{title}}</h1>
<button> my Button </button>
<h2 pButton type="button" icon="fa-check" iconPos="right">My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span>{{hero.name}}
</li>
</ul>
<hero-detail [hero]="selectedHero"></hero-detail>
`,
styles: [`
.selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.heroes li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
`],
providers: [HeroService]
})
export class AppComponent implements OnInit{
title = 'Tour of Heroes';
heroes: Hero[];
selectedHero: Hero;
constructor(private heroService: HeroService){
}
getHeroes(): void{
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}
onSelect(hero: Hero): void{
this.selectedHero = hero;
}
ngOnInit(): void{
this.getHeroes();
}
}
Make use of templateUrl instead of template in Component Decorator
templateUrl - url to an external file containing a template for the
view
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
Add all the code to app.component.html
create separate html and css example : home.component.html and home.component.css
in component.ts file add below code
import { Component, OnInit, TemplateRef } from '#angular/core';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
You can add the html code in a separate html file for example: app.component.html
Copy the template without the inside the app.component.html .
Later in your #Component make the below changes:
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
})