Wednesday 5 October 2016

Create a Angular2 Directive, focused directive which will change the focus of an element based on model value

In this post we are going to see how to create a directive in Angular2 Js, for that we are taking a valid sample which are used in real time scenario like focus directive  which is used to focus an element based on the value of model value, when the model changes the value will be 

for basic setup and structuring of angular2 application please refer this link 
https://angular2js.blogspot.in/2016/10/create-basic-structure-and-setup-for.html


After setup the basic structure here we are there to develop focused directive, what we are trying to do, we are trying to develop a directive like below. where we can changed the focus based on model value.







so now here we are going to develop the directive.  In the above two images we can see that the focus is changed from username to password.

import { Directive, ElementRef,Renderer,Input,AfterViewInit,
         HostListener,OnChanges,Output,EventEmitter } from '@angular/core';


@Directive({
    selector:'[focused]'    
})

export class FocusedDirective implements OnChanges , AfterViewInit{
    
    private istrigger = false;
    @Input('focused') isFocus:any;   
     @Output() focusedChange = new EventEmitter<any>(); 
    @Output() IsFocusChange = new EventEmitter();
    
    constructor(private ele:ElementRef,private render:Renderer){

    }

    @HostListener('blur',['$event.target'])
    onBlur(ele){      
        this.isFocus = false;  
        this.focusedChange.emit(this.isFocus);         
        this.IsFocusChange.next(this.isFocus);        
        this.istrigger = true;           
    }

    @HostListener('focus',['$event.target'])
    onFocus(ele){     
        if(!this.isFocus){
            this.focusedChange.emit(this.isFocus); 
            this.isFocus = true;  
            this.IsFocusChange.next(this.isFocus);         
        }
    }

    ngOnChanges(changes){
       if(this.isFocus){
            this.ele.nativeElement.focus();
            this.IsFocusChange.next(this.isFocus);
        }
        else{
            if(this.istrigger==false){
                this.ele.nativeElement.blur();
                this.IsFocusChange.next(this.isFocus);
                this.istrigger = true;
            }
            this.istrigger = false;
        }
    }
    
    ngAfterViewInit(){
        if(this.isFocus){
            this.ele.nativeElement.focus();            
        }
        else{
            this.ele.nativeElement.blur();           
        }
    }    

}

from above code you may wonder why this much of code , for a focus element, because we have handle all events changes through UI, Model, when you change the element focus that time also we are have to update the model sync with data

If you want only a update from Model to Directive then use the directive like as [directivename]="modelvalue", 
if you want a update from view to model and model to view in Two way binding then use like below [(directivename)]="modelvalue"

We are going to use above directive in our code , using the button click we are going to change the focus, and the same using mouse click on another element we can change the focus , this also update to model.



Now create a new component where we are going to use this directive name it as form.component,ts

import { Component, ViewEncapsulation } from '@angular/core';
    

    @Component({
        selector:'myform',
        templateUrl:'com/Forms/forms.html'
    })
    export class FormComponent{
        private userfocus:boolean;
        private passfocus:boolean;
        constructor(){
            this.userfocus = true;     
            this.passfocus = false;       
        }

        PasswordFocus(){
            this.userfocus=false;
            this.passfocus = true;            
        }

        UserNameFocus(){
            this.passfocus=false;
            this.userfocus=true;
        }

        focusChanged(value){
            console.log("focus is changed "+value);            
        }
    }



then create a forms.html to bind the template with the component.

<br/>
    <div class="container" style="width:400px">
        User Name : <input   [focused]="userfocus" type="text" 
                             class="form-control" 
                             placeholder="Please enter user name"  /> <br />
        Password  : <input [(focused)]="passfocus" 
                            (IsFocusChange)="focusChanged($event)" 
                            type="password" class="form-control" 
                            placeholder="Please enter password" /> <br/>
        <button type="submit" (click)="PasswordFocus()" 
                class="btn btn-lg btn-success btn-block">Password Focus</button>    
        <button type="submit" (click)="UserNameFocus()" 
                class="btn btn-lg btn-primary btn-block">Username Focus</button>
    </div>





,Now we are going to create a module using that we are bootstrap the component. 


app.module.ts

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    import { FocusedDirective } from './directives/onload.directive';
    import { FormComponent } from './Forms/form.component';
    
    


    @NgModule({
        imports: [BrowserModule,FormsModule],
        exports: [],
        declarations: [FormComponent,FocusedDirective],
        bootstrap:[FormComponent]
    })
    export class AppModule { 

    }




main.ts

    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
    import { AppModule } from './app.module';

    const platform = platformBrowserDynamic();

    let moduleref = platform.bootstrapModule(AppModule);

.

index.html

<body>
    <myform>Loading...</myform>
  </body>





Then now we are going to see the output












from this post you can learn how to create a focused directive which can be change through model property.






Sunday 2 October 2016

Create a directive in Angular2 framework ,focus-on-load directive which will focus the element on load

In this post we are going to see how to create a directive in Angular2 Js, for that we are taking a valid sample which are used in real time scenario like focus on load directive  which is used to focus an element on page load

for basic setup and structuring of angular2 application please refer this link 
https://angular2js.blogspot.in/2016/10/create-basic-structure-and-setup-for.html


After setup the basic structure here we are there to develop focus-on-load directive, what we are trying to do, we are trying to develop a directive like below.








Directive :

Here we are going to create a directive which is used to focus an element on page load or element load, the directive will be like focus-on-load in naming



   import { Directive, ElementRef,Renderer,Input,AfterViewInit } from '@angular/core';

   @Directive({
    selector:'[focus-on-load]'
  })

   export class FocusOnLoadDirective implements AfterViewInit{
   
    @Input('focus-on-load') Color:string;

    constructor(private ele:ElementRef,private render:Renderer){
        this.ele.nativeElement.focus();        
    }

    ngAfterViewInit(){
     if(this.Color)
     this.render.setElementStyle(this.ele.nativeElement,'border','1px solid '+this.Color);
    }

  }

Component :

To add the directive we are creating an form component which is used to create a login form, in which we are adding this directive in the user name text, on loading the form the username textbox is focused.

Create a component name form.component.ts



   import { Component, ViewEncapsulation } from '@angular/core';

    @Component({
        selector:'myform',
        templateUrl:'com/Forms/forms.html'
    })
    export class FormComponent{
        constructor(){
            
        }
    }



forms.html

Create a html named forms.html under the folder com/forms/forms.html


<br/>
    <div class="container" style="width:400px">
        User Name : <input   focus-on-load type="text" 
                             class="form-control" 
                             placeholder="Please enter user name"  /> <br />
        Password  : <input  type="password" class="form-control" 
                            placeholder="Please enter password" /> <br/>
        <button type="submit" class="btn btn-lg btn-success btn-block">Login</button>    
        <button type="submit" class="btn btn-lg btn-primary btn-block">Cancel</button>
    </div>



Module:

Add the component in the Module and bootstrap the component, finally add the code in the index.html

app.module.ts


    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';    
    import { FocusOnLoadDirective } from './directives/onload.directive';
    import { FormComponent } from './Forms/form.component';

    @NgModule({
        imports: [BrowserModule,FormsModule],
        exports: [],
        declarations: [FormComponent,FocusOnLoadDirective],
        bootstrap:[FormComponent]
    })
    export class AppModule { 

    }



main.ts


    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
    import { AppModule } from './app.module';    

    const platform = platformBrowserDynamic();

    let moduleref = platform.bootstrapModule(AppModule)



 index.html


<html>
  <head>
    <title>Angular QuickStart</title>
    <meta charset="UTF-8">
    <base href="http://localhost:3000/" target="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css">
    <link rel="stylesheet" href="style.css">

    <!-- 1. Load libraries -->
     <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>
    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
      
    <script src="lib/jquery.js"></script>
    <script src="node_modules/bootstrap/dist/js/bootstrap.js"></script>
  

    <!-- 2. Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    
    <script>
      System.import('com').catch(function(err){ 
          console.error(err); 
        });
    </script>

  </head>
  <!-- 3. Display the application -->
  <body>
    <myform>Loading...</myform>
  </body>
</html>






Output:
*******************




Here in this code we are enabling an parameter passing like below, passing a red color to the focus-on-load directive which changes the border color of the element  in which  focused is directive.placed



Sample code to change the border color:

  User Name : <input   focus-on-load="red" type="text" 
                             class="form-control" 
                             placeholder="Please enter user name"  /> <br />




Then output will be like below user name text border color changes to red color






From this post you can see how to create an directive in the Angular2 Framework., This directive can focus the element on the element load.





Create a sample Star Rating Component in Angular2 JS using Typescript

In this post we are going to see how to create a component in Angular2 Js, for that we are taking the a valid sample component which are used in real time scenario like star rating component which is used to rate a value in applications

for basic setup and structuring of angular2 application please refer this link https://angular2js.blogspot.in/2016/10/create-basic-structure-and-setup-for.html, After setup the basic structure here we are there to develop a star rating component, what we are trying to do, we are trying to develop a component like below.




 Rating control:
***********************



To do this first we have to create a component and then module , finally we have to import that module that't it

Steps to do:
*****************************************
1. Create a folder name editors under the com folder
2. Create a file named star.ts
3. Create a file named ratingcontrol.ts
4. Create a file named ratingcontrol.html
5. Create a file named editor.module.ts
6. Import this module
7. add the Star Component in the App.component
7. Bootstrap the App.Module



Star.ts

From this Code you may see what we are trying to do, we are creating a model for star component, based on which we are controlling the star rating component 

export class star {
    public filled:boolean;
}




ratingcontrol.ts

From this code you can see the full implementation of star rating component, where are trying to build a component like below, here we are declaring component in three kind of formats with simple implementation , in one tag we are passing value directly to the property, in another thing we are passing value to the control with the models, 

if you want to pass a value directly then pass it like         color="red"
if you want to pass a value from model then pass it like  [color]="color"
if you want to pass a model with two way then                  [(color)] ="color"

The star component have the following properties

ratingvalue : This is the actual value which represents the value of rating,This can acts as one-way and well as Two way 

max : This is the number representation of total number of stars to draw

color : This is the color of the Outline of the star

readonly: This property makes the component readonly, i.e user cant give rating, but in code you can change it

fillcolor  : This property is the color of the star, if you doesnt give this then gold is default color

OnRatingChanged : This is the callback event which can trigger when rating is changed ,this can be hooked in your applications , to get the notify when changes


<star-rating    [(ratingvalue)]="rating"  [max]="max" 
                [color]="starcolor"       [readonly]="readonly" 
                [fillcolor]="fillcolor"   (OnRatingChanged)="ratingChanged($event)" >
 </star-rating>


<star-rating    ratingvalue="4"     max="10" 
                color="gray"        fillcolor="orange" 
                readonly="false"    (OnRatingChanged)="ratingChanged($event)" >
</star-rating>

 <star-rating    ratingvalue="2"   max="5" color="green" fillcolor="green">
 </star-rating>

   import {    Component,ViewEncapsulation,Input,Output,
                    EventEmitter,ElementRef,OnInit,OnChanges,
                    DoCheck,Renderer,AfterViewInit,AfterViewChecked,
                    AfterContentInit,ViewChildren,ContentChildren,
                    ChangeDetectionStrategy, HostBinding 
                } from '@angular/core';

   import { star } from './star';

    @Component({
        selector:'star-rating',
        changeDetection:ChangeDetectionStrategy.OnPush,
        templateUrl:'com/editors/ratingcontrol.html',
        styles:[`

            .rating {
                unicode-bidi: bidi-override;              
                text-align: start; 
                display:inline-block;  
                direction:rtl;      
            }    
            .star{      
                color: gold;    
            }
            .rating > span {
                display: inline-block;
                position: relative;
                width: 0.9em;
                font-size:30px;
            }
            .rating:hover{
                cursor:pointer;
            }
            .rating > span:hover,
            .rating > span:hover ~ span {
                color: transparent;
            }
        .rating > span:hover:before,
        .rating > span:hover ~ span:before {
                content: "\\2605";
                position: absolute;
                left: 0;
                color: gold;
        }

        `],

        host:{    
        }

     })



   export class StarRatingComponent implements OnInit , 
                                                    OnChanges,
                                                    AfterViewInit,
                                                    AfterContentInit,
                                                    AfterViewChecked {

        @Input() ratingvalue:number;
        @Output() ratingvalueChange:EventEmitter<number> = new EventEmitter<number>();

        @Output() OnRatingChanged = new EventEmitter();

        @Input() max:number;

        @Input() readonly:boolean;

        @Input() starsize:number;

        @Input() color:string;

        @Input() fillcolor:string;

        @Output() OnMouseOver = new EventEmitter();

        @ViewChildren('starfilled') starChildren;

        public stars:star[];
        private ele:ElementRef;
        private render:Renderer;
        private changeElements:HTMLElement[]

        constructor(e1:ElementRef,render:Renderer){
            this.ele = e1;
            this.render = render;  
            this.fillcolor = "gold";    
        }

        public ngOnInit(){
        
        }

        public ngOnChanges(){ 
        if(this.readonly==undefined){
            this.readonly = false;
        }     
        if(typeof(this.readonly)=="string"){    
            this.readonly = (String(this.readonly)=="true");    
        }
        this.updateStars();
        }

        public ngAfterViewInit(){
        this.starChildren.changes.subscribe(changes=>
        {   
            this.changeElements = changes._results.map(
                (eleref)=> eleref.nativeElement
                );

            this.OnRatingChanged.next(
                {  ratingvalue:this.ratingvalue,
                    max:this.max,
                    Changedelements:this.changeElements
                });           
        });  
        }

        public OnMouseenter(evt){  
        this.OnMouseOver.next(evt);
        }

        public ngAfterViewChecked(){
            
        }

        public ngAfterContentInit(){
        
        }

        private updateStars(){
            this.stars = [];    
            var j = this.max - this.ratingvalue;

            for (var i = 1; i <= this.max; i++) {                                  
                    this.stars.push({ filled: i > j });         
                }
            this.render.setElementStyle(this.ele.nativeElement,'color',this.color);
        }

        private toggle(index){     
            if(this.readonly===false){
            this.ratingvalue =  (this.max - index);
            this.updateStars(); 
            this.ratingvalueChange.emit(this.ratingvalue);      
            }
        }


    }





ratingcontrol.html

From this you can see that the implementation of star component. create this html file and link it with component

<div class="rating">
    <span   *ngFor="let star of stars; let i=index" 
            [class.star]="star.filled" 
            (click)="toggle(i)">
        <span   #starfilled (mouseenter)="OnMouseenter($event)" 
                [style.color]="fillcolor" *ngIf="star.filled">
                    &#9733;
        </span>
        <span   (mouseenter)="OnMouseenter($event)" 
                *ngIf="!star.filled">
                    &#9734;
        </span>        
    </span>
</div>






editor.module.ts

From this code , you can see that the implementation of module for our star rating component

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { StarRatingComponent } from './ratingcontrol';

@NgModule({
    imports:[CommonModule],
    declarations:[StarRatingComponent],
    providers:[],
    exports:[StarRatingComponent]
})
export class EditorModule{

}





app.component.ts
After creating the module , we have to create a root component in which we are adding the star component,In this component we can see the implementation of star component in three different ways 

  import { Component, ViewEncapsulation } from '@angular/core';

  @Component({
    selector:'my-app',
    template:`
    <span style="font-size:18px;">Rajesh G an Architect :</span>  
    <star-rating    ratingvalue="4"     max="10" 
                    color="gray"        fillcolor="orange" 
                    readonly="false"    (OnRatingChanged)="ratingChanged($event)" >
    </star-rating>

    <br/>
    <span style="font-size:18px;">Tamil Movie rate it :</span>
    <star-rating    [(ratingvalue)]="rating"  [max]="max" 
                    [color]="starcolor"     [readonly]="readonly" 
                    [fillcolor]="fillcolor" (OnRatingChanged)="ratingChanged($event)" >
    </star-rating>

    <br/>
     <span style="font-size:18px;">Indian Cricket Team :</span>
    <star-rating    [(ratingvalue)]="rating2"   max="5" color="blue" fillcolor="blue">
    </star-rating>

    <br/>
     <span style="font-size:18px;">Microsoft Bug :</span>
    <star-rating    ratingvalue="2"   max="5" color="green" fillcolor="green">
    </star-rating>

    <div>
    <button type="button" class="btn btn-sm btn-success" (click)="PrintValue()">
        Print Values
    </button>
    </div>

    `,    
    encapsulation:ViewEncapsulation.None ,
    styles:[]  ,     
  })


  export class AppComponent{

    rating = 3;
    rating2 = 2;

    max = 5;
    starcolor="red";
    readonly = false;
    fillcolor="red";

    ratingChanged(value){
        console.log("OnRating change Callback");
        console.log(this.rating);
        console.log(value);
        console.log("");
    }

    PrintValue(){    
        console.log("Values of Ratings");
        console.log("Rating :" + this.rating);
        console.log("Rating1 :"+this.rating2);
        console.log("");
    }

  }





app.module.ts

From this code you can see the root component is bootstrapped and dependencies are injected

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    import { EditorModule  } from './editors/editor.module';
    import { AppComponent } from './app.component';


    @NgModule({
        imports: [BrowserModule,FormsModule,EditorModule],
        exports: [],
        declarations: [AppComponent],
        bootstrap:[AppComponent]
    })
    export class AppModule { 

    }




main.ts

Here we are bootstrapping the Appmodule

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
import { HelloModule } from './hello.module'

const platform = platformBrowserDynamic();

let moduleref = platform.bootstrapModule(AppModule);




index.html

Here in the index.html file we can see the my-app tag, which will trigger the app.component

<html>
  <head>
    <title>Angular QuickStart</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css">
    <link rel="stylesheet" href="style.css">

    <!-- 1. Load libraries -->
     <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>
    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
      
    <script src="lib/jquery.js"></script>
    <script src="node_modules/bootstrap/dist/js/bootstrap.js"></script>
  

    <!-- 2. Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    
    <script>
      System.import('com').catch(function(err){ 
          console.error(err); 
        });
    </script>

  </head>
  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>





Output:
************************







Output of a callback function where we are printing the values of rating control , when rating changes, in this function we can notice that the model also updated when we change the value, this is because of two way binding 












Callback console print values when value changes in the star rating component











From this post you can learn how to create a star rating component using Angular 2 and Typescript, and also you can learn how to inject that component in to the root module.