0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NCMBとMonaca、Framework7を使ってカレンダーアプリを作る(その1:画面の説明とSDKの導入)

Posted at

NCMBとMonacaを使ってカレンダーアプリを作ります。予定を登録したり、Framework7のカレンダーコンポーネントを使って予定を表示できるというアプリです。

まず最初の記事では画面の説明とSDKの導入までを進めます。

コードについて

今回のコードはNCMBMania/monaca-calendar-appにアップロードしてあります。実装時の参考にしてください。

利用技術について

今回は次のような組み合わせになっています。

  • Monaca
  • Framework7
  • moment.js(Dateオブジェクト操作用)
  • NCMB JavaScript SDK

仕様について

今回はID/パスワード認証を利用しています。カレンダー表示についてはFramework7のCalendar / Datepicker | Framework7 Documentationを利用しています。また、Framework7はVanilla JSで、VueやReactなどのUIフレームワークは利用していません。

利用する機能について

カレンダーアプリで利用するNCMBの機能は次の通りです。

  • 会員管理
    • ID/パスワード認証
  • データストア
    • 予定の登録・更新・削除
    • 予定の検索

画面について

今回は以下の3つの画面があります。

www/pages/login.html

image.png

ログイン画面です。ID/パスワードを使って認証します。今回はユーザー登録とログイン画面を兼ねています。

<div class="block-title">ユーザーIDとパスワードを入力してください</div>
<form id="login">
	<div class="list no-hairlines-md">
		<ul>
			<li>
				<div class="item-content item-input">
					<div class="item-inner">
						<div class="item-title item-label">ユーザーID</div>
						<div class="item-input-wrap">
							<input type="text" name="userName" placeholder="お名前" value="goofmint" required/>
						</div>
					</div>
				</div>
			</li>
			<li>
				<div class="item-content item-input">
					<div class="item-inner">
						<div class="item-title item-label">パスワード</div>
						<div class="item-input-wrap">
							<input type="password" name="password" placeholder="パスワード" value="goofmint" required/>
						</div>
					</div>
				</div>
			</li>
		</ul>
	</div>
	<div class="block block-strong">
		<p class="row">
			<a href="#" @click=${login} class="col button">ログイン or ユーザー登録</a>
		</p>
	</div>
</form>

www/pages/calendar.html

0409 localhost - 1120115748.jpg

カレンダー画面です。NCMBのデータストアから予定を取得して、画面にドット表示で反映させます。日付を選択すると、該当日の予定を一覧表示します。

<div id="calendar"></div>
<div class="block-title">
	${ selectedDate.value ? moment(selectedDate.value).format('YYYY年MM月DD日') : "日付を選択してください"}
</div>
<div class="list media-list chevron-center">
	${ selectedDate.value === null || schedules.value.length === 0 ?
		$h`<div class="block">予定はありません</div>` :
		$h`<ul>
			${ schedules.value
				.filter(schedule => moment(schedule.startDate.iso).format('YYYY-MM-DD') === moment(selectedDate.value).format('YYYY-MM-DD'))
				.map(schedule => $h`
				<li>
					<a href="/form/${schedule.objectId}/" class="item-link item-content">
						<div class="item-inner">
							<div class="item-title-row">
								<div class="item-title">${schedule.title}</div>
								<div class="item-after">
									${moment(schedule.startDate.iso).format('HH:mm')}〜${moment(schedule.endDate.iso).format('HH:mm')}
								</div>
							</div>
							<div class="item-text">
								${schedule.body}
							</div>
						</div>
					</a>
				</li>
			`)}
		</ul>`
	}
</div>

www/pages/form.html

0409 localhost - 1120120122.jpg

予定を登録・更新または削除する画面です。日時の入力はFramework7のカレンダーコンポーネントを利用しています。

<div class="list no-hairlines-md">
	<form id="schedule">
		<ul>
			<li class="item-content item-input">
				<div class="item-inner">
					<div class="item-input-wrap">
						<input type="text" id="startDate" name="startDate" @change=${setEndDate} placeholder="日時" value="${targetDate}" />
						<span class="input-clear-button"></span>
					</div>
				</div>
			</li>
			<li class="item-content item-input">
				<div class="item-inner">
					<div class="item-input-wrap">
						<input type="text" id="endDate" name="endDate" placeholder="終了日時" />
						<span class="input-clear-button"></span>
					</div>
				</div>
			</li>
			<li class="item-content item-input">
				<div class="item-inner">
					<div class="item-input-wrap">
						<input type="text" name="title" placeholder="タイトル" value="${schedule.title}" />
						<span class="input-clear-button"></span>
					</div>
				</div>
			</li>
			<li class="item-content item-input">
				<div class="item-inner">
					<div class="item-input-wrap">
						<textarea class="resizable" name="body">${schedule.body}</textarea>
						<span class="input-clear-button"></span>
					</div>
				</div>
			</li>
		</ul>
		<div class="block block-strong">
			<p class="row">
				<a href="#" @click=${saveSchedule} class="col button">保存</a>
			</p>
			${ schedule.objectId ?
				$h`<p class="row">
						<a href="#" @click=${deleteSchedule} class="col button">削除</a>
					</p>`
				: ''
			}
		</div>
	</form>
</div>

SDKのインストール

今回はMonacaのJS/CSSコンポーネントの追加と削除より、NCMBを追加します。アプリのテンプレートはFramework7のJavaScript版(VueやReactではなく)を選択しています。

NCMBのAPIキーを取得

mBaaSでサーバー開発不要! | ニフクラ mobile backendにてアプリを作成し、アプリケーションキーとクライアントキーを作成します。

js/config.jsonの作成

js/config.jsonを作成し、その中に先ほど取得したNCMBのAPIキーを設定します。内容は次のようになります。

{
	"applicationKey": "YOUR_APPLICATION_KEY",
	"clientKey": "YOUR_CLIENT_KEY"
}

初期化

初期化は js/app.js にて行います。config.jsonを読み込む関係上、非同期処理内にて行います。cordovaの有無(アプリまたはプレビューの違いを検知)によって初期化時のイベント処理を変えています。

// NCMBの初期化用
const event = window.cordova ? 'deviceready' : 'DOMContentLoaded';
document.addEventListener(event, async (e) => {
	// この中に処理を書きます
});

config.jsonの内容を読み込んで、NCMBとFramework7の初期化を行います。

window.config = await (await fetch('./js/config.json')).json();
window.ncmb = new NCMB(config.applicationKey, config.clientKey);
window.app = new Framework7({
	name: 'My App', // App name
	theme: 'auto', // Automatic theme detection
	el: '#app', // App root element
	// App store
	store: store,
	// App routes
	routes: routes,
});

これでNCMBの初期化が完了します。

ルーティング設定

今回はチャット画面、ログイン画面の2つがあります。これを js/routes.js に定義します。

const routes = [
  {
    path: '/',
    url: './index.html',
  },
  // カレンダー画面
  {
    path: '/home/',
    componentUrl: './pages/calendar.html',
    beforeEnter,
  },
  // ログイン画面
  {
    path: '/login/',
    componentUrl: './pages/login.html',
  },
  // 予定追加・更新画面
  {
    path: '/form/:id/',
    componentUrl: './pages/form.html',
  },
  // Default route (404 page). MUST BE THE LAST
  {
    path: '(.*)',
    url: './pages/404.html',
  },
];

認証していない場合の判定処理

上記のルーティングで beforeEnter を指定しています。ここで、カレンダー画面を表示する前に、認証状態を確認します。そしてログインしていない場合には、ログイン画面に遷移します。

// routes.jsに記述
const beforeEnter = async ({resolve, reject, router}) => {
  // 現在ログインしているユーザー情報を取得
  const currentUser = ncmb.User.getCurrentUser();
  // 認証していない場合はnullになる
  if (!currentUser) {
    // rejectを実行
    reject();
    // 認証画面に遷移
    router.navigate('/login/');
    // 処理完了
    return;
  }
  try {
    // データストアにダミーアクセス
    await ncmb.DataStore('Hello').fetch();
    // アクセスできればresolveを実行(元々指定されている画面を表示)
    resolve();
  } catch (e) {
    // 駄目だった場合は認証情報を削除
    localStorage.removeItem("NCMB/"+ncmb.apikey+"/currentUser");
    // rejectを実行
    reject();
    // 認証画面に遷移
    router.navigate('/login/');
  }  
};

まとめ

今回はカレンダーアプリの仕様と画面、NCMBの初期化までを解説しました。次はログイン処理を実装します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?