概要
トップページと同様にお問合せページをIonicで再現します。
Contactコンポーネントを作成し、バリデーションを実装します。
完成イメージ
この時点ではタブがないため、
ionic serve
でchrome ブラウザから確認できる状態です。
Contact画面作成
同様にContactページを作成していきます。
Contactページ
contactページ作成に必要なファイルをコマンドで作成します。
作業フォルダにいることを確認して実行します。
ionic generate page contact
src/にcontactフォルダとファイルが追加されました。
フォームを作成していきます。
HTMLとIonicコンポーネントを使っていきます。
見た目
contact.page.html
まず見た目だけ作ります。
<ion-header>
<ion-toolbar>
<ion-title>contact</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<div id="container">
<strong>お問い合わせ</strong>
<form id="form">
<p>お名前</p>
<ion-item lines="full">
<ion-input type="text" placeholder="お名前"></ion-input>
</ion-item>
<span class="error">
お名前は必須です。
</span>
<p>Email</p>
<ion-item lines="full">
<ion-input type="email" placeholder="Email"></ion-input>
</ion-item>
<span class="error">
emailは必須かつemailの形式で入力してください。
</span>
<p>お問い合わせ内容</p>
<ion-item>
<ion-textarea placeholder="お問い合わせ内容"></ion-textarea>
</ion-item>
<span class="error">
お問い合わせ内容は必須かつ1文字以上10文字以下で入力してください。
</span>
<ion-button type="submit">送信</ion-button>
</form>
</div>
</ion-content>
contact.page.scss
ion-content {
--ion-background-color: white;
}
ion-item {
--background: rgb(204, 204, 204);
color: black;
}
ion-input {
color: black;
}
#container {
padding-top: 1em;
padding-left: 3em;
padding-right: 3em;
display: flex;
background-color: white;
align-items: center;
justify-content: center;
flex-direction: column;
}
#container strong {
color: black;
}
#container p {
color: black;
text-align: left;
width: 100%;
}
#container ion-textarea {
min-height: 80px;
}
#container ion-button {
color: black;
width: 100%;
--border-radius: 0;
--background: rgb(204, 204, 204);
margin-top: 20px;
}
#form {
width: 100%;
}
.error {
color: red;
}
確認
タブがないので実機やエミュレータでは遷移ができず問い合わせページがまだ見れないためionic serve
で起動してhttp://localhost:8100/contact を確認します。
このような感じになっています。
機能
まず、フォームをグループとして管理できるようにionicFormという名前をつけます。
- <form id="form">
+ <form id="form" [formGroup]="ionicForm">
バリデーショーンはReactiveFormsModuleとFormsModuleを使います。
contact.moudle.tsを開いてReactiveFormsModuleを追加します。
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
- import { FormsModule } from '@angular/forms';
+ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { ContactPageRoutingModule } from './contact-routing.module';
import { ContactPage } from './contact.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ContactPageRoutingModule,
+ ReactiveFormsModule
],
declarations: [ContactPage]
})
export class ContactPageModule {}
contact.page.tsを開いてFormGroup, FormBuilder, Validatorsを追加します。
コンポーネントの中でFormBuilderクラスの機能を利用することができようにするため、コンストラクター引数としてFormBuilderクラスのインスタンスを渡します。
ngOnInit()(コンポーネントが初期化されたときに呼び出される)にモジュールを使ってバリデーションを作成します。
import { Component, OnInit } from '@angular/core';
+ import { FormGroup, FormBuilder, Validators } from '@angular/forms';
@Component({
selector: 'app-contact',
templateUrl: './contact.page.html',
styleUrls: ['./contact.page.scss'],
})
export class ContactPage implements OnInit {
+ ionicForm: FormGroup;
- constructor() { }
+ constructor(public formBuilder: FormBuilder) { }
ngOnInit() {
+ this.ionicForm = this.formBuilder.group({
+ name: ['', [Validators.required]],
+ email: [
+ '',
+ [
+ Validators.required,
+ Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,3}$'),
+ ],
+ ],
+ content: [
+ '',
+ [
+ Validators.required,
+ Validators.minLength(1),
+ Validators.maxLength(10),
+ ],
+ ],
+ });
}
}
this.ionicForm = this.formBuilder.group({
name: ['', [Validators.required]],
email: [
'',
[
Validators.required,
Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,3}$'),
],
],
content: [
'',
[
Validators.required,
Validators.minLength(1),
Validators.maxLength(10),
],
],
});
すると、ionicForm
の部分でvariableのinitの注意が出ます。tsconfig.jsonを開いて注意を消す設定をします。
"compilerOptions": {
+ "strictPropertyInitialization": false,
htmlに戻ってcontrollerNameを追加していきます。
<ion-item lines="full">
- <ion-input type="text" placeholder="お名前"></ion-input>
+ <ion-input formControlName="name" type="text" placeholder="お名前"></ion-input>
</ion-item>
<span class="error">
お名前は必須です。
</span>
<p>Email</p>
<ion-item lines="full">
- <ion-input type="email" placeholder="Email"></ion-input>
+ <ion-input formControlName="email" type="email" placeholder="Email"></ion-input>
</ion-item>
<span class="error">
emailは必須かつemailの形式で入力してください。
</span>
<p>お問い合わせ内容</p>
<ion-item>
- <ion-textarea placeholder="お問い合わせ内容"></ion-textarea>
+ <ion-textarea formControlName="content" placeholder="お問い合わせ内容"></ion-textarea>
</ion-item>
Anglurの構文を使ってバリデーションメッセージの表示・非表示を動的にできるようにします。
またformタグにサブミットハンドラーを追加します。
<ion-header>
<ion-toolbar>
<ion-title>contact</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<div id="container">
<strong>お問い合わせ</strong>
- <form id="form" [formGroup]="ionicForm">
+ <form id="form" [formGroup]="ionicForm" (ngSubmit)="submitForm()">
<p>お名前</p>
<ion-item lines="full">
<ion-input formControlName="name" type="text" placeholder="お名前"></ion-input>
</ion-item>
- <span class="error">
+ <span class="error" *ngIf="isSubmitted && errorControl['name'].errors?.['required']">
お名前は必須です。
</span>
<p>Email</p>
<ion-item lines="full">
<ion-input formControlName="email" type="email" placeholder="Email"></ion-input>
</ion-item>
- <span class="error">
+ <span class="error" *ngIf="isSubmitted && (errorControl['email'].errors?.['required'] ||errorControl['email'].errors?.['pattern'])">
emailは必須かつemailの形式で入力してください。
</span>
<p>お問い合わせ内容</p>
<ion-item>
<ion-textarea formControlName="content" placeholder="お問い合わせ内容"></ion-textarea>
</ion-item>
- <span class="error">
+ <span class="error" *ngIf="isSubmitted && (errorControl['content'].errors?.['required'] ||errorControl['content'].errors?.['min'] ||errorControl['content'].errors?.['max'] )">
お問い合わせ内容は必須かつ1文字以上10文字以下で入力してください。
</span>
<ion-button type="submit">送信</ion-button>
</form>
</div>
</ion-content>
<form id="form" [formGroup]="ionicForm" (ngSubmit)="submitForm()">
<p>お名前</p>
<ion-item lines="full">
<ion-input formControlName="name" type="text" placeholder="お名前"></ion-input>
</ion-item>
<span class="error" *ngIf="isSubmitted && errorControl['name'].errors?.['required']">
お名前は必須です。
</span>
<p>Email</p>
<ion-item lines="full">
<ion-input formControlName="email" type="email" placeholder="Email"></ion-input>
</ion-item>
<span class="error"
*ngIf="isSubmitted && (errorControl['email'].errors?.['required'] ||errorControl['email'].errors?.['pattern'])">
emailは必須かつemailの形式で入力してください。
</span>
<p>お問い合わせ内容</p>
<ion-item>
<ion-textarea formControlName="content" placeholder="お問い合わせ内容"></ion-textarea>
</ion-item>
<span class="error" *ngIf="isSubmitted && (errorControl['content'].errors?.['required'] ||errorControl['content'].errors?.['min'] ||errorControl['content'].errors?.['max'] )">文字以下で入力してください。
</span>
<ion-button type="submit">送信</ion-button>
</form>
SubmitForm()を作成し、制御していきます。
一旦、バリデーションがすべてスルーだったらコンソールに値が表示されるようにします。
またget errorControl()を使って、Angulerの特定のフォームコントロールエラーメッセージを返します。
isSubmittedは初期値はfalseにし、送信が押されたら、trueとなるようにしています。
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
@Component({
selector: 'app-contact',
templateUrl: './contact.page.html',
styleUrls: ['./contact.page.scss'],
})
export class ContactPage implements OnInit {
+ isSubmitted = false;
ionicForm: FormGroup;
constructor(public formBuilder: FormBuilder) { }
ngOnInit() {
this.ionicForm = this.formBuilder.group({
name: ['', [Validators.required]],
email: [
'',
[
Validators.required,
Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,3}$'),
],
],
content: [
'',
[
Validators.required,
Validators.minLength(1),
Validators.maxLength(10),
],
],
});
}
+ submitForm() {
+ this.isSubmitted = true;
+ if (!this.ionicForm.valid) {
+ return;
+ }
+ let data = this.ionicForm.value;
+ console.log(data);
+ }
+ get errorControl() {
+ return this.ionicForm.controls;
+ }
}
submitForm() {
this.isSubmitted = true;
if (!this.ionicForm.valid) {
return;
}
let data = this.ionicForm.value;
console.log(data);
}
get errorControl() {
return this.ionicForm.controls;
}
ionic serve
で確認し、バリデーションが想定どおり動いていて、
適切な値が入った状態でボタンクリックするとコンソールに値が表示されていることを確認します。
API連携
console.log(data)
を削除してAPI連携のコードを追加します。
submitForm() {
this.isSubmitted = true;
if (!this.ionicForm.valid) {
return;
}
let data = this.ionicForm.value;
+ const api_url = 'apiのURL';
+ fetch(api_url, {
+ method: 'post',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ body: encodeURI(
+ `name=${data.name}&email=${data.email}&body=${data.body}`
+ ),
+ })
+ .then((response) => response.json())
+ .then((result) => alert(result.message))
+ .catch((error) => alert(error.message));
}
const api_url = 'apiのURL';
fetch(api_url, {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: encodeURI(
`name=${data.name}&email=${data.email}&body=${data.body}`
),
})
.then((response) => response.json())
.then((result) => alert(result.message))
.catch((error) => alert(error.message));