Categories
Angular Material

Angular Material — Snackbar and Sort Header

Angular Material is a popular UI framework based on Material Design for Angular.

In this article, we’ll look at how to use Angular Material into our Angular project.

Snackbar

A snackbar is a container for notification.

The MatSnackBar service can be used to add it.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatButtonModule } from '@angular/material/button';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSnackBarModule,
    MatButtonModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';

@Component({
  selector: 'snack-bar-component-example-snack',
  template: 'pizza party',
  styles: [`
    .example-pizza-party {
      color: hotpink;
    }
  `],
})
export class PizzaPartyComponent { }

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  durationInSeconds = 5;

  constructor(private _snackBar: MatSnackBar) { }

  openSnackBar() {
    this._snackBar.openFromComponent(PizzaPartyComponent, {
      duration: this.durationInSeconds * 1000,
    });
  }
}

app.component.html

<div>
  <button mat-stroked-button (click)="openSnackBar()">
    Pizza party
  </button>
</div>

We add the MatSnackbarModule to let us add the snackbar.

Then in app.component.ts , we inject the MatSnackBar service into AppComponent to let us call the openFromComponent method with a component with the snackbar content.

The duration is in milliseconds.

In the template, we have a button to open the snackbar by calling the openSnackBar method.

Sort Header

We can add the sort header component to let us sort state and display tabular data.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSortModule } from '@angular/material/sort';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSortModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';
import { Sort } from '@angular/material/sort';

interface Dessert {
  name: string,
  calories: number,
  fat: number
}

const compare = (a: number | string, b: number | string, isAsc: boolean) => {
  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  desserts: Dessert[] = [
    { name: 'Frozen yogurt', calories: 159, fat: 6 },
    { name: 'Ice cream sandwich', calories: 237, fat: 4 },
    { name: 'Eclair', calories: 262, fat: 16, },
    { name: 'Cupcake', calories: 305, fat: 4, },
    { name: 'Gingerbread', calories: 356, fat: 16 },
  ];

  sortedData: Dessert[];

  constructor() {
    this.sortedData = this.desserts.slice();
  }

  sortData(sort: Sort) {
    const data = this.desserts.slice();
    if (!sort.active || sort.direction === '') {
      this.sortedData = data;
      return;
    }

    this.sortedData = data.sort((a, b) => {
      const isAsc = sort.direction === 'asc';
      switch (sort.active) {
        case 'name': return compare(a.name, b.name, isAsc);
        case 'calories': return compare(a.calories, b.calories, isAsc);
        case 'fat': return compare(a.fat, b.fat, isAsc);
        default: return 0;
      }
    });
  }
}

app.component.html

<div>
  <table matSort (matSortChange)="sortData($event)">
    <tr>
      <th mat-sort-header="name">Dessert (100g)</th>
      <th mat-sort-header="calories">Calories</th>
      <th mat-sort-header="fat">Fat (g)</th>
    </tr>

    <tr *ngFor="let dessert of sortedData">
      <td>{{dessert.name}}</td>
      <td>{{dessert.calories}}</td>
      <td>{{dessert.fat}}</td>
    </tr>
  </table>
</div>

We add the MatSortModule so that we can use the matSort directive into the table element.

Then we can click on the table header to sort the columns.

When we click on the header, the matSortChange event is emitted.

When it’s emitted, sortData is called.

Then, in app.component.ts , we call sort on the data and call our compare function to do the sorting.

Conclusion

We can add a snackbar and a sort header to sort table columns with Angular Material.

Categories
Angular Material

Angular Material — Sidenavs, Side Toggles, and Sliders

Angular Material is a popular UI framework based on Material Design for Angular.

In this article, we’ll look at how to use Angular Material into our Angular project.

Sidenav

Angular comes with a sidenav component.

We can add it by writing:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatButtonModule } from '@angular/material/button';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSidenavModule,
    MatButtonModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.module.html

<div>
  <mat-drawer-container class="example-container" autosize>
    <mat-drawer #drawer class="example-sidenav" mode="side">
      <p>Auto-resizing sidenav</p>
      <p *ngIf="showFiller">Lorem, ipsum dolor sit amet consectetur.</p>
      <button (click)="showFiller = !showFiller" mat-raised-button>
        Toggle extra text
      </button>
    </mat-drawer>

    <div class="example-sidenav-content">
      <button type="button" mat-button (click)="drawer.toggle()">
        Toggle sidenav
      </button>
    </div>
  </mat-drawer-container>
</div>

app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  showFiller = false;
}

styles.css

.example-container {
  height: 100vh;
}

We add the sidenav with the mat-drawer-container as its container.

mat-drawer is the sidenav drawer.

The Toggle sidenav button shows the drawer.

The Toggle extra text button closes the drawer.

The filler text display is controlled by showFiller .

drawer.toggle() lets us toggle the drawer.

Slide Toggles

We can add a toggle with the mat-slide-toggle component.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSlideToggleModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<div>
  <mat-slide-toggle color="red" [checked]="true" [disabled]="false">
    Slide me!
  </mat-slide-toggle>
</div>

We add the MatSlideToggleModule into our module so that we can add the mat-slide-toggle component into the template.

checked sets the checked state.

disabled makes it disabled if it’s true .

color sets the color.

Slider

We can add a slider with the mat-slider component.

For example, we can write:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSliderModule } from '@angular/material/slider';
import { MatCardModule } from '@angular/material/card';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSliderModule,
    MatCardModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<div>
  <mat-card class="example-result-card">
    <mat-card-content>
      <mat-slider min="1" max="5" step="0.5" value="1.5"></mat-slider>
    </mat-card-content>
  </mat-card>
</div>

Adding the MatSliderModule lets us add the mat-slider to our template.

min has the minimum allowed value.

max has the maximum allowed value.

step has the interval we can set.

value is the value of the slider.

Conclusion

We can add sidenavs, slide toggles, and sliders into our Angular app with Angular Material.

Categories
JavaScript Basics

Highlights of JavaScript — Constructor Methods and Getting URLs

To learn JavaScript, we must learn the basics.

In this article, we’ll look at the most basic parts of the JavaScript language.

Constructor Methods

We can add methods to constructors or classes.

For example, we can write:

class Plan {
  constructor(name, price, space, pages) {
    this.name = name;
    this.price = price;
    this.space = space;
    this.pages = pages;
  }

  calcAnnualPrice() {
    return this.price * 12;
  }
}

We add the calcAnnualPrice method to return the value of this.price * 12 .

this is the class instance, which is the object that’s created and returned when we invoke the Plan class.

So we get the price property from the object we create from the class and multiply it by 12.

To invoke the constructor and call the method on the created object, we can write:

const plan = new Plan('basic', 3, 100, 10)
console.log(plan.calcAnnualPrice())

We invoke the Plan constructor with the new keyword.

Then we call calcAnnualPrice on the plan object to get the annual price.

The class syntax is just syntactic sugar on top of prototype inheritance.

The calcAnnualPrice method is just a property of the Plan ‘s prototype property.

The prototype is the prototype of the Plan class, which is the object that it inherits from.

If we log the value of Plan.prototype.calcAnnualPrice :

console.log(Plan.prototype.calcAnnualPrice)

we see the code of the calcAnnualPrice method logged.

Checking for Properties and Methods

To check if a property or method is actually in the object itself rather than its prototype, we can use the hasOwnProperty method.

For example, if we created an object from the Plan class:

const plan = new Plan('basic', 3, 100, 10)

Then we can call hasOwnProperty by writing:

console.log(plan.hasOwnProperty('name'))

Then we should see true logged since name is a property of the plan object itself.

The hasOwnProperty method comes from Object.prototype , which is a property of almost all JavaScript objects.

If we want to list an object’s properties, we can write:

for (const prop in plan) {
  if (plan.hasOwnProperty(prop)) {
    console.log(prop);
  }
}

We loop through the plan ‘s property keys with the for-in loop.

The for-in loop loops through all then properties and its prototypes, so we have to use the hasOwnProperty method to check if a property is actually in the plan object itself.

prop is the property name itself.

Therefore, we should see:

name
price
space
pages

logged.

Getting the URL

We can get and set the URL of the page with JavaScript.

To get the URL, we can use the window.location.href property.

If we type that into the browser dev console, we should get the full URL of the page.

window.location.hostname has the hostname which is the first part of the URL.

For example, if we have the URL“https://jsfiddle.net/09t6La27/10/" , then window.location.hostname returns “jsfiddle.net” .

window.location.hash returns the part of the URL after the # sign.

For example, if we have http://example.com/#foo , window.location.hash returns “#foo” .

Conclusion

We can add methods to constructors or classes.

Also, we can get parts of a URL with the window.location object.

Categories
JavaScript Basics

Highlights of JavaScript — Objects and Constructors

To learn JavaScript, we must learn the basics.

In this article, we’ll look at the most basic parts of the JavaScript language.

Objects

We need objects to store values other than primitive values like numbers, strings, booleans, etc.

It servers as a container for all the items we want to store.

For example, we can define an object by writing:

const plan = {
  name: "Basic",
  price: 3,
  space: 100,
  transfer: 1000,
  pages: 10
};

We created the plan object with various properties.

name , price , space , transfer , and pages are property names.

The expressions after the colon are their values.

Properties are separated by a comma.

To access a property, we can write:

plan.name

plan.name ‘s value should be 'Basic' .

We can assign properties with different values.

For example, we can write:

plan.name = 'Deluxe';

Then name property’s new value is 'Deluxe' .

We can assign values with any data type with the assignment operator.

To check if a property is in an object, we can use the in operator.

For example, if we have:

'name' in plan

then that should return true since name is a property of plan .

But if we have:

'foo' in plan

then that returns false since foo isn’t a property of plan .

We need the property name in quotes since the left operand is a string.

Object Methods

Objects can have methods.

For example, we can write:

const plan = {
  name: "Basic",
  price: 3,
  space: 100,
  transfer: 1000,
  pages: 10,
  calcAnnualPrice() {
    return this.price * 12;
  }
};

to add the calcAnnualPrice method into the plan object.

this is the object itself, so this.price * 12 returns the value of the price property multiplied by 12.

Constructors

We can create objects with the same structure with constructors.

They’re the templates for objects.

To create a constructor, we can write:

function Plan(name, price, space, pages) {
  this.name = name;
  this.price = price;
  this.space = space;
  this.pages = pages;
}

We created the Plan constructor that takes the name , price , space , and pages parameters.

Then we assign them to properties of this with the same name.

When we invoke the constructor, this will be returned with all the properties we assigned.

To invoke it, we can write:

const plan = new Plan('basic', 3, 100, 10)

We use the new keyword to call the constructor and create the object.

The value of plan is:

{
  name: "basic"
  pages: 10
  price: 3
  space: 100
}

A better way to write the constructor is to use the class syntax.

For example, we can write:

class Plan {
  constructor(name, price, space, pages) {
    this.name = name;
    this.price = price;
    this.space = space;
    this.pages = pages;
  }
}

The constructor method is the same as the constructor function we have before.

It just looks different. This is the preferred way to create constructors since it’s consistent with other popular object-oriented languages.

Conclusion

We can create objects to store more than one piece of data in a container.

To create objects with the same structure, we can create constructors.

Categories
JavaScript Basics

Highlights of JavaScript — Selecting Elements and the DOM

To learn JavaScript, we must learn the basics.

In this article, we’ll look at the most basic parts of the JavaScript language.

Target All Elements by Tag Name with querySelectorAll

The document.querySelectorAll method lets us get all the elements with the given selector.

So to get all the elements with the given tag name, we can write the following HTML:

<p>foo.</p>
<p>bar.</p>
<p>baz.</p>

Then we can get all of them and style them by writing:

const pars = document.querySelectorAll('p')
for (const p of pars) {
  p.style.fontFamily = "Verdana, Geneva, sans-serif";
}

We get all the p elements with document.querySelectorAll .

Then we loop through each item with the for-of loop and set the style.fontFamily property to set the font family.

Target Some Elements by Tag Name

We can target some elements by tag name with the document.querySelectorAll method since it takes any selector string as an argument.

For example, if we have the following HTML table:

<table>
  <tr>
    <td>foo</td>
    <td>bar</td>
    <td>baz</td>
  </tr>
</table>

and we want to get all the td elements in the table, we can write:

const tds = document.querySelectorAll('table td')
for (const t of tds) {
  t.style.backgroundColor = "pink";
}

We get the td elements within the table element with the table td selector.

Then we loop through the td elements and set the backgroundColor to 'pink' .

The DOM

The DOM stands for Document Object Model. It’s the way that browsers represent the HTML elements with JavaScript.

HTML elements are organized in a tree structure in the DOM.

Each level is indicated by the indentation.

For example, if we have:

<html>

  <head>
    <title>
      Simple document
    </title>
  </head>

  <body>
    <p>
      hello world
    </p>
  </body>

</html>

Then the html element is the root of the tree.

The head and body are at the 2nd level.

The title and p elements are at the 3rd level.

The topmost element is the document object.

Therefore html element is the parent of the head and body elements.

The title element is the child of the head element.

And the p element is the child of the body element.

We can find child elements with the DOM methods that we used before like querySelector , querySelectorAll , getElementById and getElementByTagName .

For example, if we have the following HTML:

<html>

<head>
    <title>
      Simple document
    </title>
  </head>

  <body>
    <div id="weather">
      <p>Today is sunny.</p>
      <p>Yesterday is rainy.</p>
    </div>
    <div id="density">
      <p>City is crowded.</p>
      <p>Desert is sparse.</p>
    </div>
  </body>
</html>

Then if we want to get the ‘Today is sunny’ text, we can write:

const sunny = document.querySelector('#weather p');
console.log(sunny.innerHTML)

We use the #weather p selector with the querySelector method to get the first p element from the div with the ID weather .

Then we get its content with the innerHTML property.

Conclusion

We can get the elements with the document methods.

HTML elements are modeled in the browser with the DOM.