Now let’s start building our component

We will use some of the ionic inbuilt components to create our own custom reusable component. This component will look like a calendar we can slide, we can also select the month, year and date, and our component will emit the changes based on the selected date. Note this tutorial is meant to help you learn how to create your own custom reusable components for your ionic projects.

Let’s got to our home.component.ts and clear information we don’t need, your final home.component.ts file should look like this

<ion-header>

<ion-toolbar>

<ion-title>

Blank

</ion-title>

</ion-toolbar>

</ion-header>



<ion-content class="ion-padding">



</ion-content>

Let’s navigate to our src directory and create a shared module, that is where our reusable components will be created.

Now let’s add IonicModule to our shared.module.ts file, our module should look like this in the end.

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

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

import {IonicModule} from '@ionic/angular';



@NgModule({

declarations: [],

imports: [

CommonModule,

IonicModule

]

})

export class SharedModule { }

Create a component called kz-calendar in the shared module directory, add the KzCalendarComponent to the declarations and exports in the shared.module.ts file like this, that is if it has not been added to the declarations already.

declarations: [KzCalendarComponent],

exports: [

KzCalendarComponent

],

Now let’s go to the kz-calendar.component.ts and modify it.

Let’s add the following to the file

// this is the default date initializer

// it is an input because we allow it to accept changes from the user

@Input() kzDate: Date = new Date();

// this emit any changes to the selected date to the user

@Output() kzDateChange = new EventEmitter<Date>();

// this sets the maximum date for the calendar

@Input() maxDate: Date = new Date(2100, 1, 1);

// this set the minimum date for the calendar

@Input() minDate: Date = new Date() ;

// this is an array for the list of years

years: Array<any> = [];

// this holds the selected year

selectedYear: any;

// this holds the selected month

month: any;

// this holds the month count

monthCount = 0;

We will create an array for the list of days

// this holds the list of days

AllDays: string[] = [

'SUN',

'MON',

'TUES',

'WED',

'THURS',

'FRI',

'SAT'

];

Then another array for the list of months

// this holds the list of months

AllMonths: any[] = [

{

name: 'JANUARY'

},

{

name: 'FEBRUARY'

},

{

name: 'MARCH'

},

{

name: 'APRIL'

},

{

name: 'MAY'

},

{

name: 'JUNE'

},

{

name: 'JULY'

},

{

name: 'AUGUST'

},

{

name: 'SEPTEMBER'

},

{

name: 'OCTOBER'

},

{

name: 'NOVEMBER'

},

{

name: 'DECEMBER'

}

];

We will have another array which will hold all the dates for a selected month

// this holds all dates in a selected month

AllDates: Array<any> = [];

We will now add our slider configuration

// configuration for the slider for the dates

// the break points are meant for other screen sizes

slidesOpts = {

slidesPerView: 3,

spaceBetween: 5,

breakpoints: {

576: {

slidesPerView: 3,

spaceBetween: 5,

},

768: {

slidesPerView: 6,

spaceBetween: 5,

},

992: {

slidesPerView: 6,

spaceBetween: 5,

},

1200: {

slidesPerView: 9,

spaceBetween: 5,

},

}

};

Now let’s create a function called GetYears() that will generate all years between the minDate and the maxDate.

GetYears() {

for (let i = this.minDate.getFullYear(); i <= this.maxDate.getFullYear(); i++) {

this.years.push({year: i, selected: false});

}

}

Now we will create other functions that will get us the name of the selected month, the name of the selected day and the date

// get name of selected month

GetMonth(date: Date): any {

return this.AllMonths[date.getMonth()].name;

} // get the name of selected day

GetDay(date: Date): any {

return this.AllDays[date.getDay()];

} // get the date of the selected date

GetDate(date: Date): any {

return date.getDate();

}

We will create a function called DaysInMonth(year, month); to get all the days in a selected month and year.

private DaysInMonth(year, month): any {

const date = new Date(year, month, 1);

const days = [];

while (date.getMonth() === month) {

days.push({date: new Date(date)});

date.setDate(date.getDate() + 1);

}

return days;

}

Now we will create a function that uses the defaults we have initialize from the beginning of this tutorial called GetDefaultCalendar().

GetDefaultCalendar() {

this.AllDates = this.DaysInMonth(this.kzDate.getFullYear(), this.kzDate.getMonth());



this.AllMonths.forEach(u => u.selected = false);

this.AllMonths[this.kzDate.getMonth()].selected = true;

this.month = this.AllMonths[this.kzDate.getMonth()].name;

this.selectedYear = this.kzDate.getFullYear();

this.years.forEach(u => u.selected = false);

this.years.find(u => u.year === this.kzDate.getFullYear()).selected = true;

}

We will then create two functions called calendarMonthChange(event), calendarYearChange(event) which checks for the changes in month and year which will then trigger the GetDefaultCalendar() function.

calendarMonthChange(event) {

this.kzDate.setMonth(this.AllMonths.findIndex(u => u.name === event.detail.value));

this.GetDefaultCalendar();

}



calendarYearChange(event) {

this.kzDate = new Date(event.detail.value, this.kzDate.getMonth(), 1);

this.GetDefaultCalendar();

}

Then finally for the kz-calendar.component.ts file, we add the function called onCalendarChange(date, index: Element) which detects the change in selected date and applies the necessary CSS class then emits the selected value to the user.

onCalendarChange(date, index: Element) {

const allEle = document.getElementsByClassName('datec');

for (let i = 0; i < allEle.length; i++) {

allEle.item(i).classList.remove('selected');

}

index.classList.add('selected');

this.kzDateChange.emit(date);

}

Well, that is it for the kz-calendar.component.ts file. For the kz-calendar.component.html file paste the code below,

<div style="padding-left: 20px; margin-top: 20px">

<ion-grid>

<ion-row>

<ion-fab-button size="small" (click)="GetPreviousMonth()">

<ion-icon name="chevron-back-outline"></ion-icon>

</ion-fab-button>

<ion-select selectedText="{{month}}" (ionChange)="calendarMonthChange($event)" style="width: 140px">

<ion-select-option *ngFor="let month of AllMonths" value="{{month.name}}">{{month.name}}</ion-select-option>

</ion-select>

<ion-select selectedText="{{kzDate.getFullYear()}}" (ionChange)="calendarYearChange($event)">

<ion-select-option *ngFor="let year of years" value="{{year.year}}">{{year.year}}</ion-select-option>

</ion-select>

<ion-fab-button size="small" (click)="GetNextMonth()">

<ion-icon name="chevron-forward-outline"></ion-icon>

</ion-fab-button>

</ion-row>

<ion-row>

<ion-col>

<ion-slides pager="false" [options]="slidesOpts">

<ng-container *ngFor="let date of AllDates; let i = index">

<ion-slide *ngIf="minDate <= date.date && date.date <= maxDate">

<div #element class="datec" (click)="onCalendarChange(date.date, element)">

<h1>{{GetDate(date.date)}}</h1>

<small class="bottom">{{GetDay(date.date)}}</small>

</div>

</ion-slide>

</ng-container>

</ion-slides>

</ion-col>

</ion-row>

</ion-grid>

</div>

The code above uses <ion-fab-button> for the increment of the calendar month and year, <ion-select> for the listing of both the year and month, then <ion-slides> for the dates.

Paste the CSS below into your kz-calendar.component.scss

ion-slide{

//border: solid 1px grey;

}

.datec{

border-radius: 10px;

background-color: white;

width: 80%;

margin: 10px 10px 50px 10px;

font-family: 'Quicksand', sans-serif !important;

border: solid 0.5px grey;

}





.datec.selected{

background-color: blue !important;

color: white !important;

}



.datec .top{

display: block;

text-align: center !important;

padding-top: 5px;

padding-left: 5px;

padding-right: 5px;

font-weight: bold;

}



.datec .bottom{

display: block;

text-align: center !important;

padding-bottom: 15px;

padding-left: 10px;

padding-right: 10px;

margin-top: -10px;

font-weight: bold;

}

.datec h1{

display: block;

margin-top: -10px;

text-align: center !important;

font-size: 50px;

padding-top: 10px;

}



h4{

font-family: 'Quicksand', sans-serif !important;

}



.swiper-slide {



/* Center slide text vertically */

display: -webkit-box;

display: -ms-flexbox;

display: -webkit-flex;

display: flex;

-webkit-box-pack: center;

-ms-flex-pack: center;

-webkit-justify-content: center;

justify-content: center;

-webkit-box-align: center;

-ms-flex-align: center;

-webkit-align-items: center;

align-items: center;

}

Well that is it, you can get access to the full code on my ionic Github playground page https://github.com/kojo-io/kaziplayer

final results.

I am opened to suggestions and better ways to improve what I have done.

Thank you.