Saturday, 24 February 2018

How to Implement Pull To Refresh functionality in Ionic 2 and ionic 3

Ionic Framework Comes with a ion-refresher Component that makes it easy for developers to implement pull to refresh content functionality in your ionic application. Pull to Refresh can be used to refresh the already existing items or to add more items to the already existing items like timeline. In this example we will see how to implement pull to refresh functionality which adds an country name to the list every time the list is pulled. This tutorial assumes that you already have the project setup and running.

Create a countrylist page.

Execute below command in your projects command prompt to add countrylist page to your project "pages" folder in "src" directory.


  ionic generate page countrylist
this will generate contrylist folder in your project's src/pages folder. Note : import the countrylist page in to your app module and add it to the declarations and entryComponents, if your cli does not create an "countrylist.module.ts" file in your new page file (ie in countrylist folder). the "app.module.ts" should look something like this after countrylist page is imported.

Modify app.module.ts file

app.module.ts



import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { ListPage } from '../pages/list/list';
import { CountrylistPage } from '../pages/countrylist/countrylist';

import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

@NgModule({
  declarations: [
    MyApp,
    HomePage,
    ListPage,
    CountrylistPage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp)

  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage,
    ListPage,
    CountrylistPage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler},

  ]
})
export class AppModule {}


That is all for the app.module file your app should run fine now.

Modify countrylist.html template

Copy and paste the below give code just below the opening content tag ie, ion-content.

countrylist.html


  <ion-refresher (ionRefresh)="doRefresh($event)">
        <ion-refresher-content
        pullingIcon="md-arrow-dropdown"
        pullingText="Pull to refresh"
        refreshingSpinner="crescent"
        refreshingText="Refreshing...">
      </ion-refresher-content>
      </ion-refresher>

above code provide you with all the Customizing options to modify the ui of Refresher Content or you can use the default ui by simply using the below given code.

   <ion-refresher (ionRefresh)="doRefresh($event)">
    <ion-refresher-content></ion-refresher-content>
  </ion-refresher>

Now that the UI part is complete, lets head to the countrylist.ts file to implement the ion-refresher functionality.

Modify countrylist.ts file as shown below.

Copy and Paste the below given code in to your countrylist.ts file.

countrylist.ts


    import { Component } from '@angular/core';
    import { IonicPage, NavController, NavParams } from 'ionic-angular';

    /**
    * Generated class for the CountrylistPage page.
    *
    * See https://ionicframework.com/docs/components/#navigation for more info on
    * Ionic pages and navigation.
    */

    @IonicPage()
    @Component({
    selector: 'page-countrylist',
    templateUrl: 'countrylist.html',
    })
    export class CountrylistPage {
    countryList:any;
    moreCountries:any;
    countryCount = 0;
    constructor(public navCtrl: NavController, public navParams: NavParams) {
        this.countryList = [];
    }

    ionViewDidLoad() {
        console.log('ionViewDidLoad CountrylistPage');
        this.moreCountries=["Afghanistan","Albania","Algeria","Andorra","Angola","Anguilla","Antigua & Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia & Herzegovina","Botswana","Brazil","British Virgin Islands","Brunei","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Cape Verde","Cayman Islands","Chad","Chile","China","Colombia","Congo","Cook Islands","Costa Rica","Cote D Ivoire","Croatia","Cruise Ship","Cuba","Cyprus","Czech Republic","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea","Estonia","Ethiopia","Falkland Islands","Faroe Islands","Fiji","Finland","France","French Polynesia","French West Indies","Gabon","Gambia","Georgia","Germany","Ghana","Gibraltar","Greece","Greenland","Grenada","Guam","Guatemala","Guernsey","Guinea","Guinea Bissau","Guyana","Haiti","Honduras","Hong Kong","Hungary","Iceland","India","Indonesia","Iran","Iraq","Ireland","Isle of Man","Israel","Italy","Jamaica","Japan","Jersey","Jordan","Kazakhstan","Kenya","Kuwait","Kyrgyz Republic","Laos","Latvia","Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg","Macau","Macedonia","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Mauritania","Mauritius","Mexico","Moldova","Monaco","Mongolia","Montenegro","Montserrat","Morocco","Mozambique","Namibia","Nepal","Netherlands","Netherlands Antilles","New Caledonia","New Zealand","Nicaragua","Niger","Nigeria","Norway","Oman","Pakistan","Palestine","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Poland","Portugal","Puerto Rico","Qatar","Reunion","Romania","Russia","Rwanda","Saint Pierre & Miquelon","Samoa","San Marino","Satellite","Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore","Slovakia","Slovenia","South Africa","South Korea","Spain","Sri Lanka","St Kitts & Nevis","St Lucia","St Vincent","St. Lucia","Sudan","Suriname","Swaziland","Sweden","Switzerland","Syria","Taiwan","Tajikistan","Tanzania","Thailand","Timor L'Este","Togo","Tonga","Trinidad & Tobago","Tunisia","Turkey","Turkmenistan","Turks & Caicos","Uganda","Ukraine","United Arab Emirates","United Kingdom","Uruguay","Uzbekistan","Venezuela","Vietnam","Virgin Islands (US)","Yemen","Zambia","Zimbabwe"]
    }

    doRefresh(refresher) {
        console.log('Begin async operation', refresher);

        this.countryList.push(this.moreCountries[this.countryCount])
        this.countryCount = this.countryCount + 1;

        setTimeout(() => {
        console.log('Async operation has ended');
        refresher.complete();
        }, 100);
    }

    }

What the above code does is, when ever you pull the page down it triggers the ionRefresh event, which intern calls the doRefresh function. the doRefresh function then checks the countryCount and pushes the country from moreCountries array to countryList array, which gets updated in the ionic content view. refresh.complete() completes/stops the refresh process. we have set a timeout here to make sure that the spinner spins until the content is updated. it may help someone, so i'm posting the full html code below. feel free to comment below

full countrylist.html template code


<ion-header>

  
  <ion-navbar>
    
          <button ion-button menuToggle>
              <ion-icon name="menu"></ion-icon>
            </button>
          <ion-title>Countries</ion-title>
    
        </ion-navbar>

</ion-header>


<ion-content padding>

  <ion-refresher (ionRefresh)="doRefresh($event)">
    <ion-refresher-content
    pullingIcon="md-arrow-dropdown"
    pullingText="Pull to refresh"
    refreshingSpinner="crescent"
    refreshingText="Refreshing...">
  </ion-refresher-content>
  </ion-refresher>

  <ion-list no-lines>
    <ion-item *ngFor="let item of countryList" style="font-weight: 600;font-family: roboto;">
      {{item}}
    </ion-item>
  </ion-list>


<div *ngIf="countryList.length == 0" style="height: 100%;position: relative;top: 45%;text-align: center;">
    <div style="font-size: 20px;text-align: center;color: #90949c;">Pull to fetch Countries</div>
</div>
</ion-content>

Friday, 16 February 2018

Creating an Intro Slider in Ionic 2 and ionic 3 Application

Every Mobile Application needs an intro slides to notify user about the features of the app they have installed. Intro slides gives the users the much needed information about the app, a tutorials on the welcome screen. Ionic Framework Provides developers with a component called ion-slides which makes it easy to create an intro slider for your ionic application.

Create an Intro Page

Execute below command in your projects command prompt to add intro page to your project "pages" folder in "src" directory.


  ionic generate page intro
this will generate intro folder in your project's src/pages folder.
Note : import the intro page in to your app module and add it to the declarations and entryComponents, if your cli does not create an "intro.module.ts" file in your new page file (ie in intro folder). the "app.module.ts" should look something like this after intro page is imported.

Modify app.module.ts file

app.module.ts


import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { ListPage } from '../pages/list/list';
import { IntroPage } from '../pages/intro/intro';

import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

@NgModule({
  declarations: [
    MyApp,
    HomePage,
    ListPage,
    IntroPage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp)

  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage,
    ListPage,
    IntroPage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler},

  ]
})
export class AppModule {}

Now, that's out of or way, let's head forward and modify our intro template page.

Change intro.html file as given below

Copy and Paste the below html code in your intro.html file.

intro.html


    <ion-content padding>
  <ion-slides (ionSlideDidChange)="slideChanged()"> 
    <ion-slide *ngFor="let item of IntroInfo">
      <img class="imageStyle" src="{{item.image}}"/>    
      <h1>{{item.subject}}</h1>
      <p *ngIf="item.description">{{item.description}}</p>
      <button *ngIf="item.buttontext" ion-button color="light">{{item.buttontext}}</button>
    </ion-slide>

  </ion-slides>
</ion-content>  

ionSlideDidChange event call the slideChanged method when ever the slide is changed. ngIf condition for button is, that it will be only viewable when ther's a buttontext key in the list item. now lets check the ts file for the corresponding intro.html file.

Modify intro.ts file as shown below.

Copy and Paste the below ts code in your intro.ts file.

intro.ts


  import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { ViewChild } from '@angular/core';
import { Slides } from 'ionic-angular';

/**
 * Generated class for the IntroPage page.
 *
 * See https://ionicframework.com/docs/components/#navigation for more info on
 * Ionic pages and navigation.
 */

@IonicPage()
@Component({
  selector: 'page-intro',
  templateUrl: 'intro.html',
})
export class IntroPage {
  @ViewChild(Slides) slides: Slides;
  public IntroInfo:any;

  constructor(public navCtrl: NavController, public navParams: NavParams) {
     this.IntroInfo = [{image:"assets/welcome.png",subject:"MyWeather",description:"Get all the weather information in one place."},
                       {image:"assets/sunny.png",subject:"Its hot Today!",description:"Whether it's hot.."},
                       {image:"assets/freezing.png",subject:"climate is freezing, isn'nt it!",description:"whether it's freezing.."},
                       {image:"assets/continue.png",subject:"Get Started..",buttontext:"Continue"}]
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad IntroPage');
  }

    // Below function when executed starts autoplay of the slides.

  autoSlideStart(){
    this.slides.startAutoplay()
  }

   // Below function when executed stops autoplay of the slides.

  autoSlideStop(){
    this.slides.stopAutoplay()
  }
    // Below function when executed Traverse to a specified slide given.

  goToSlide() {
    this.slides.slideTo(2, 500, true);  // where 2 is the index, 500 is speed and true is Whether or not to run ionSlideWillChange/ionSlideDidChange events when the slide is changed.
  }

    // Below function when executed will Traverse to Next slide.

  goToNSlide(){
    this.slides.slideNext(500, false)     // where 500 is speed and false is Whether or not to run ionSlideWillChange/ionSlideDidChange events when the slide is changed.
  }

    // Below function when executed will Traverse to previous slide.

  goToPSlide(){
    this.slides.slidePrev(500, false)     // where 500 is speed and false is Whether or not to run ionSlideWillChange/ionSlideDidChange events when the slide is changed.
  }

    // Below function Get's the index of the active slide.

  slideChanged() {
    let currentIndex = this.slides.getActiveIndex();
    console.log('Current index is', currentIndex);
  }

    // Below function Get's the index of the previous slide.

  getBeforeIndex(){
    let previousIndex = this.slides.getPreviousIndex();
    console.log('Previous index is', previousIndex);
  }

    // Below function Get whether or not the current slide is the first slide.

  isSlideFirst(){
    let firstSlide = this.slides.isBeginning()
    console.log('Current slide is the first slide', firstSlide);
  }

    // Below function Get's whether or not the current slide is the last slide.

  isSlideEnd(){ 
    let endSlide = this.slides.isEnd()
    console.log('Current slide is the last slide', endSlide);
  }

  // Below function gets the total number of slides.

  slideLength(){   
    let endSlide = this.slides.length();
    console.log('Number of slides are : ', endSlide);
  }

  // Below function when set to true the user will not be able to swipe to the next slide. Set to false to unlock this behaviour.

  lockNextSlide(){
    let shouldLockSwipeToNext = true; //  shouldLockSwipeToNext can be either true/false
    let lockNSlide = this.slides.lockSwipeToNext(shouldLockSwipeToNext);
    console.log('Number of slides are : ', lockNSlide); 
  }

  // Below function when set to true the user will not be able to swipe to the previous slide. Set to false to unlock this behaviour.

  lockPrevSlide(){
    let shouldLockSwipeToPrev = false; //  shouldLockSwipeToPrev can be either true/false
    let lockNSlide = this.slides.lockSwipeToPrev(shouldLockSwipeToPrev);
    console.log('Number of slides are : ', lockNSlide); 
  }

  // Below function when set to true user's can not swipe in either direction on slide. False allows swiping in both directions.

  lockAllSlide(){
    let shouldLockSwipes = true; //  shouldLockSwipes can be either true/false
    let lockNSlide = this.slides.lockSwipes(shouldLockSwipes);
    console.log('Number of slides are : ', lockNSlide); 
  }

  // Below function when executed update's the slides structure. Call this if you’ve added or removed child slides.

  updateTheSlides(){
    this.slides.update()
  }
  

}

the above ts file contains all the methods, ionic slides provide to us. their use and functionality is written as comments above the respective functions. thats it, if you like you can adjust the slide image width with the below class.

styling the slides

Copy and Paste the below css code to your Components .scss file.

intro.scss


 page-intro {
   .imageStyle{
       width:50%;
   }
}

that's it, now save the changes and restart the server to view the intro slides in action.

Tuesday, 6 February 2018

How to implement Gestures in ionic 2 and ionic 3

Gestures on a phone can be very useful, when implementing functionality for images like pinch to zoom, long press to get more options regarding image editing. They can be used further more for different purposes like swipe to delete an item etc. In this post we are going to see how to implement Gestures in ionic framework. We will see how to use gestures like press, pan, tap and swipe. This tutorial assumes you already have the ionic project up and running. Now generate a new page named "gesture" with the following command.

  ionic generate page gesture

Copy and Paste the html code to your Components .html file.

  <ion-header>

  <ion-navbar>
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>Gesture</ion-title>
  </ion-navbar>

</ion-header>


<ion-content padding>
 
  <ion-card (tap)="tapEvent($event)" class="cardStyle">
    <ion-item>
      Tapped: {{tap}} times
    </ion-item>
  </ion-card>

  <ion-card (press)="pressEvent($event)"  class="cardStyle">
    <ion-item>
      Pressed: {{press}} times
    </ion-item>
  </ion-card>

  <ion-card (pan)="panEvent($event)"  >
    <ion-item [ngStyle]="calculateStyle()">
      Panned: {{pan}} times <br>
      Panning: {{panDirection}}
    </ion-item>
  </ion-card>

  <ion-card (swipe)="swipeEvent($event)" (tap)="changeColor()" class="cardStyle">
    <ion-item id="swipeItem" >
      Swiped: {{swipe}} times
    </ion-item>
  </ion-card>

</ion-content>

In the above code we have defined cards individually for every event with their corresponding function calls.
Copy and Paste the below ts code to your Components .ts file.

  import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';

/**
 * Generated class for the GesturePage page.
 *
 * See https://ionicframework.com/docs/components/#navigation for more info on
 * Ionic pages and navigation.
 */

@IonicPage()
@Component({
  selector: 'page-gesture',
  templateUrl: 'gesture.html',
})
export class GesturePage {

  public press: number = 0;
  public pan: number = 0;
  public swipe: number = 0;
  public tap: number = 0;
  public pinch: number = 0;
  public panDirection:string = "";
  public bgHorz:   number = 0 ;
  public lastBgH:  number = 0 ;
  public bgVert:   number = 0 ;
  public lastBgV:  number = 0 ;

  constructor(public navCtrl: NavController, public navParams: NavParams) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad GesturePage');
  }


// function to call when item is pressed.

  pressEvent(e) { 
    this.press++;
  }

// function to call when item is panned.

  panEvent(e) {
    console.log(e.additionalEvent+"||"+e.direction)
    console.log(e.deltaX +"||"+e.deltaY)
    this.pan++
    if(e.direction == 1){
      this.panDirection = "None";
    }else if(e.direction == 2){
      this.panDirection ="Left";    
    }else if(e.direction == 4){
      this.panDirection = "Right";    
    }else if(e.direction == 6){
      this.panDirection = "HORIZONTAL";    
    }else if(e.direction == 8){
      this.panDirection = "Up";     
    }else if(e.direction == 16){
      this.panDirection = "Down";     
    }else if(e.direction == 24){
      this.panDirection = "VERTICAL";     
    }else{
      this.panDirection = "ALL";
    }

   // logic to pan image

    var stepH = e.deltaX /10 ;
    var stepV = e.deltaY /10 ;

    this.bgHorz = this.bgHorz + (this.lastBgH - stepH) ;
    if (this.bgHorz < 0) {
       this.bgHorz = 0 ;
    } else {
       if (this.bgHorz > 100)
          this.bgHorz = 100 ;
    }

    this.bgVert = this.bgVert + (this.lastBgV - stepV) ;
    if (this.bgVert < 0) {
       this.bgVert = 0 ;
    } else {
       if (this.bgVert > 100)
          this.bgVert = 100 ;
    }

    this.calculateStyle()

  }

// function to call when item panning is ended.

  panEnd($event){
    //events  pan, panstart, panmove, panend, pancancel, panleft, panright, panup, pandown
    console.log("Panning Ended")
  }


// function to calculate the position of image when it is panned.

  calculateStyle() {
    var style = {
        backgroundImage : 'url("../assets/ionicFramework.png")',
        backgroundPositionX : this.bgHorz+'%',
        backgroundPositionY : this.bgVert+'%',
        backgroundRepeat: 'no-repeat',
        height:"200px"
    } ;
    return style ;
 }


// function to call when item is swiped.

  swipeEvent(e) {
    this.swipe++
    console.log('' + e.direction);
    // Swipe Direction "DIRECTION_LEFT"
    if(e.direction == 2){
      document.getElementById("swipeItem").style.backgroundColor = "#ff0026db"
      document.getElementById("swipeItem").style.color = "white"
    }
    // Swipe Direction "DIRECTION_RIGHT"
    if(e.direction == 4){
      document.getElementById("swipeItem").style.backgroundColor = "#189666"
      document.getElementById("swipeItem").style.color = "white"
      
    }

  /** --Direction for swip event--

      DIRECTION_NONE         1
      DIRECTION_LEFT         2
      DIRECTION_RIGHT        4
      DIRECTION_UP           8
      DIRECTION_DOWN         16
      DIRECTION_HORIZONTAL   6
      DIRECTION_VERTICAL     24
      DIRECTION_ALL          30

     --Direction for swip event-- **/
  }

// function to call when item is tapped.

  tapEvent(e) {
    this.tap++
  }


// function to call when qwiped item is tapped.

  changeColor(){
    document.getElementById("swipeItem").style.backgroundColor = "white"
    document.getElementById("swipeItem").style.color = "black"
    
  }

}

Now run the project to check the events in action. feel free to comment below for any queries.