Ionic 4.1 Hydrogen New Features | How to Implement? Example Tutorial

After the big release of Ionic 4.0, the team has come up with another update Ionic 4.1 named Hydrogen cool 😛 In this update, they have fixed some bugs from the previous version and also introduced some new features. New features seem like a cherry on top as these are mostly related to UI point…

By.

•

min read

After the big release of Ionic 4.0, the team has come up with another update Ionic 4.1 named Hydrogen cool 😛 In this update, they have fixed some bugs from the previous version and also introduced some new features.

New features seem like a cherry on top as these are mostly related to UI point to view. Here is the list of four features( with working examples ) added in Ionic 4.1 (Hydrogen)

– Intermediate Checkbox
– Skeleton Text Update
– CSS Display Utilities
– Select Component with compareWith

Gotta catch ’em all!

Update your current Ionic CLI version( Current is  )

1) Intermediate Checkbox

Ionic has added a new state to checkbox which usually has two states checked/ unchecked, now we have 50-50 means some are checked and some are unchecked. In that case, there will be a – sign to indicate only some of the checkboxes are checked.

This is not so useful for single checkbox, but when we have a group or list of checkboxes, this can be helpful.

home.page.html

<ion-content>
  <ion-list>
    <ion-item>
      <ion-checkbox
        slot="start"
        [(ngModel)]="masterCheck"
        [indeterminate]="isIndeterminate"
        (ionChange)="checkMaster()"
      ></ion-checkbox>
      <ion-label><strong>Select All</strong></ion-label>
    </ion-item>
    <ion-item *ngFor="let item of dummyData">
      <ion-checkbox
        slot="start"
        [(ngModel)]="item.isChecked"
        (ionChange)="checkEvent()"
      ></ion-checkbox>
      <ion-label>{{ item.name }}</ion-label>
    </ion-item>
  </ion-list>
</ion-content>

home.page.ts

import { Component } from "@angular/core";

@Component({
  selector: "app-home",
  templateUrl: "home.page.html",
  styleUrls: ["home.page.scss"]
})
export class HomePage {
  isIndeterminate = false;
  masterCheck = false;

  dummyData = [
    {
      id: "01",
      isChecked: false,
      name: "Rod Hand"
    },
    {
      id: "02",
      isChecked: false,
      name: "Rod Rolfson DVM"
    },
    {
      id: "03",
      isChecked: false,
      name: "Curt McKenzie"
    },
    {
      id: "04",
      isChecked: false,
      name: "Juliet Bogisich"
    },
    {
      id: "05",
      isChecked: false,
      name: "Clifton Rowe"
    }
  ];

  constructor() {}

  checkMaster() {
    this.dummyData.map(obj => {
      obj.isChecked = this.masterCheck;
    });
  }

  checkEvent() {
    const totalItems = this.dummyData.length;
    let checked = 0;
    this.dummyData.map(obj => {
      if (obj.isChecked) checked++;
    });
    if (checked > 0 && checked < totalItems) {
      this.isIndeterminate = true;
      this.masterCheck = false;
    } else if (checked == totalItems) {
      this.masterCheck = true;
      this.isIndeterminate = false;
    } else {
      this.isIndeterminate = false;
      this.masterCheck = false;
    }
  }

  arrayOne(n: number): any[] {
    return Array(n);
  }
}

 

2) Animated Content Loading Placeholder AKA Skeleton Text Update

In many applications like Facebook and Instagram, you may have noticed a preloader animated wavy animations of content format, Yes! now we have a similar thing in Ionic 4.1

home.page.html

isLoaded is a flag to check if data is loaded, ion-skeleton-text element with animated class is used to show skeleton placeholder anywhere. In ion-avatar & ion-thumbnail it will shape accordingly.

<ion-content>

  <ng-container *ngIf="isLoaded; else elseTemplate">
    
      <ion-item *ngFor="let item of dummyData">
          <ion-avatar slot="start">
            <img src="{{item.avatar}}" alt="" srcset="">
          </ion-avatar>
          <ion-label>
            <h2>{{item.name}}</h2>
            <p>{{item.address}}</p>
          </ion-label>
        </ion-item>

  </ng-container>

  <ng-template #elseTemplate>

    <ion-item *ngFor="let item of arrayOne(18)">
      <ion-avatar slot="start">
        <ion-skeleton-text animated></ion-skeleton-text>
      </ion-avatar>
      <ion-label>
        <h2><ion-skeleton-text animated style="width: 100px;"></ion-skeleton-text></h2>
        <p><ion-skeleton-text animated style="width: 180px;"></ion-skeleton-text></p>
      </ion-label>
    </ion-item>

  </ng-template>
  
</ion-content>

home.page.ts

A bit of dummy data to replicate server-side behavior.

import { Component } from "@angular/core";

@Component({
  selector: "app-home",
  templateUrl: "home.page.html",
  styleUrls: ["home.page.scss"]
})
export class HomePage {
  isLoaded = false;

  dummyData = [
    {
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/pechkinator/128.jpg",
      name:"Rod Hand",
      address:"Lake Micheleshire, LA 52889-8814"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/ostirbu/128.jpg",
      name:"Rod Rolfson DVM",
      address:"Delmerchester, OR 94420"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/jay_wilburn/128.jpg",
      name:"Curt McKenzie",
      address:"North Margaretview, MI 77699-4658"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/primozcigler/128.jpg",
      name:"Juliet Bogisich",
      address:"North Margaretview, MI 77699-4658"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/juangomezw/128.jpg",
      name:"Clifton Rowe",
      address:"North Margaretview, MI 77699-4658"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/dzantievm/128.jpg",
      name:"Vivianne Keebler",
      address:"United States of America"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/gcmorley/128.jpg",
      name:"Joshua Feest",
      address:"North Margaretview, MI 77699-4658"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/jay_wilburn/128.jpg",
      name:"Curt McKenzie",
      address:"North Margaretview, MI 77699-4658"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/primozcigler/128.jpg",
      name:"Juliet Bogisich",
      address:"North Margaretview, MI 77699-4658"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/juangomezw/128.jpg",
      name:"Clifton Rowe",
      address:"North Margaretview, MI 77699-4658"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/dzantievm/128.jpg",
      name:"Vivianne Keebler",
      address:"United States of America"
    },{
      avatar:"https://s3.amazonaws.com/uifaces/faces/twitter/gcmorley/128.jpg",
      name:"Joshua Feest",
      address:"North Margaretview, MI 77699-4658"
    }
  ];

  constructor() {
    setTimeout(() => {
      this.isLoaded = true;
    }, 3000);
  }

  arrayOne(n: number): any[] {
    return Array(n);
  }
}

 

 

3) CSS Display Utilities

Make things show/hide now become easier in Ionic 4.1 with ion-hide class or ion-hide-{breakpoint}-{dir} based on screen sizes. To use this class just add

@import '~@ionic/angular/css/display.css';

at the end of the global.scss file

Already added is latest versions

If you check this file (display.css) you will find media query based classes

    .ion-hide {
      display: none !important
    }

    .ion-hide-up {
      display: none !important
    }

    @media (max-width: 575px) {
      .ion-hide-down { display: none !important }
    }

    @media (min-width: 576px) {
      .ion-hide-sm-up { display: none !important }
    }

    @media (max-width: 767px) {
      .ion-hide-sm-down { display: none !important }
    }

    @media (min-width: 768px) {
      .ion-hide-md-up { display: none !important }
    }

    @media (max-width: 991px) {
      .ion-hide-md-down { display: none !important }
    }

    @media (min-width: 992px) {
      .ion-hide-lg-up { display: none !important }
    }

    @media (max-width: 1199px) {
      .ion-hide-lg-down { display: none !important }
    }

    @media (min-width: 1200px) {
      .ion-hide-xl-up { display: none !important }
    }

    .ion-hide-xl-down { display: none !important }

 

4) Select Component with compareWith

Ionic has added back compareWith property to ion-select in the Ionic latest release. compareWith was available in Ionic 3 to compare a particular option in ion-select, which was possible only through a strict ===  comparison on the object.

Below is the example with Single and Multiple option selection

  <ion-list>
    <ion-item>
      <ion-label>Users(Single)</ion-label>
      <ion-select [(ngModel)]="selectedSingleEmployee" [compareWith]="compareFn" (ionChange)="singleChange()">
        <ion-select-option *ngFor="let user of users" [value]="user">{{user.first + ' ' + user.last}}
        </ion-select-option>
      </ion-select>
    </ion-item>
  </ion-list>

  <ion-list>
    <ion-item>
      <ion-label>Users(Multi)</ion-label>
      <ion-select multiple="true" [(ngModel)]="selectedMultipleEmployee" [compareWith]="compareFn"
        (ionChange)="multiChange()">
        <ion-select-option *ngFor="let user of users" [value]="user">{{user.first + ' ' + user.last}}
        </ion-select-option>
      </ion-select>
    </ion-item>
  </ion-list>
import { Component } from '@angular/core';


export interface User {
  id: number;
  first: string;
  last: string;
}

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  selectedSingleEmployee:any;
  selectedMultipleEmployee:any;

  users: any[] = [
    {
      id: 1,
      first: 'Alice',
      last: 'Smith',
    },
    {
      id: 2,
      first: 'Bob',
      last: 'Davis',
    },
    {
      id: 3,
      first: 'Charlie',
      last: 'Rosenburg',
    }
  ];

  constructor(){
    this.selectedSingleEmployee = [{
      id: 2,
      first: 'Bob',
      last: 'Davis',
    }];
    this.selectedMultipleEmployee = [{
      id: 2,
      first: 'Bob',
      last: 'Davis',
    },
    {
      id: 3,
      first: 'Charlie',
      last: 'Rosenburg',
    }]
  }

  compareFn(e1: User, e2: User): boolean {
    return e1 && e2 ? e1.id === e2.id : e1 === e2;
  }


  singleChange(){ 
    console.log(this.selectedSingleEmployee);
  };
  multiChange(){ 
    console.table(this.selectedMultipleEmployee);
  };

}

 

Leave a Reply

Your email address will not be published. Required fields are marked *