Hexabase(ヘキサベース)は企業においても安心して利用できるBaaS(Backend as a Service)を提供しています。多くのBaaSがそうであるように、主にフロントエンド開発者に利用してもらいたいと考えています。そこで現在、TypeScript SDKの開発が進められています。
元々TypeScriptで作られていることもあって、Next.jsやVue.jsなどでimportして利用することができます。しかし、もっと普通のWebアプリケーションなどで使う際には、CDN経由で利用したいと考える方もいるでしょう。そこで、UMD版Hexabase JavaScript SDKを作成しました。
今回は、そのUMD版Hexabase JavaScript SDKを使ったTodoアプリのデモを紹介します。今回はタスクの表示と、編集機能を解説します。一覧の表示、タスクの追加と削除は以下を参照してください。
UMD版Hexabase JavaScript SDKを使ってTodoアプリを作る(タスク一覧表示・追加・削除) #JavaScript - Qiita
デモ
デモはこちらのURLで体験できます。
SDKの読み込み
SDKは下記URLで読み込めます。
<script src="https://cdn.jsdelivr.net/npm/@hexabase/hexabase-js@latest/dist/umd/hexabase.min.js"></script>
バージョン指定する場合は、以下のようになります。メジャーバージョンが上がらない限りはlatest指定をお勧めします。
<script src="https://cdn.jsdelivr.net/npm/@hexabase/hexabase-js@2.0.6/dist/umd/hexabase.min.js"></script>
モジュールとして使う場合には、以下のようになります。
<script type="module">
import hexabase from 'https://cdn.jsdelivr.net/npm/@hexabase/hexabase-js@latest/+esm'
</script>
SDKの初期化
SDKは以下のようコードで初期化します。これさえ終われば、後はTypeScriptと同じように使えます。
const { HexabaseClient } = hexabase;
const client = new HexabaseClient();
HTMLについて
HTMLはBootstrapを使って、以下のように作成しています。上半分が既存タスクの表示、下半分はタスクの追加・編集用フォームになっています。
<div class="container" style="padding-top: 1em;">
<div class="row justify-content-md-center">
<div class="col-10">
<div class="row justify-content-end">
<div class="col-5">
<button type="button" id="add" class="btn btn-primary">➕ 新しいタスク</button>
</div>
</div>
<table class="table">
<thead>
<tr>
<th scope="col">タスク</th>
<th scope="col">担当者名</th>
<th scope="col">カテゴリ</th>
<th scope="col">ステータス</th>
<th scope="col">アクション</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<form>
<div class="row g-3">
<input type="hidden" name="id" />
<div class="col">
<input type="text" class="form-control" name="Title" aria-describedby="emailHelp" placeholder="新しいタスク">
</div>
<div class="col">
<input type="text" class="form-control" name="Assignee" placeholder="担当者名">
</div>
<div class="col">
<select name="Category" class="form-control">
</select>
</div>
<div class="col">
<button type="submit" name="Button" id="button" class="btn btn-primary" disabled>追加</button>
</div>
</div>
</form>
<div class="row g-3" style="padding-top: 1em;">
<div class="col">
<div id="Status">
</div>
</div>
</div>
</div>
</div>
</div>
初期設定
まずコード内で使う変数、DOMを定義します。
// 認証用のメールアドレスとパスワード
const email = 'demo5@moongift.jp';
const password = 'K4c%j%vzR7sQKS$u&Uo%';
// Hexabaseのワークスペース、プロジェクト、ワークスペースのID
const workspaceId = '644f6e5ab30d853869ec919f';
const projectId = '650a30501222568b1ae7a2c2';
const datastoreId = '65895ba97b4300d37757d562';
// 複数の処理で使う変数用
const params = {
datastore: null, // データストア
items: [], // 既存タスク一覧
};
// DOM
const table = document.querySelector('.table tbody');
const form = document.querySelector('form');
const addButton = document.querySelector('#add');
初期表示処理
初期表示の処理は以下のようになります。初期設定、データの読み込み、そしてフォームへの値設定となります。
// 画面が読み込まれたときの処理
(async () => {
await init();
load();
await makeForm();
})();
初期設定
初期設定用の init
関数ではログインやワークスペース・プロジェクト・データストアの取得を行っています。
// 初期設定
const init = async () => {
// ログイン
const res = await client.login({email, password});
// ワークスペース・プロジェクト・データストアの取得
await client.setWorkspace(workspaceId);
const project = await client.currentWorkspace.project(projectId);
params.datastore = await project.datastore(datastoreId);
// 追加ボタンを押せるようにする
addButton.disabled = false;
};
データの読み込み
load
関数は既存のタスク一覧を読み込み、テーブルに表示します。
// 既存のアイテム一覧を取得する処理
const load = async () => {
const query = client.query(projectId);
const items = await query
.from(datastoreId)
.select('*');
params.items = items;
// 表示更新
showTable();
};
showTable
関数は、取得したアイテム一覧をテーブルに表示します。また、削除ボタンのイベントリスナーも設定しています。編集ボタンは .edit
で、クリックすると editItem
関数を呼び出します。
// タスク一覧の更新と、タスクへのアクション設定
const showTable = () => {
// params.itemsに沿って、表示を更新
table.innerHTML = params.items.map(item => `
<tr data-id="${item.id}">
<td>${item.get('Title')}</td>
<td>${item.get('Assignee')}</td>
<td>${item.get('Category').ja}</td>
<td>${item._status ? item._status.name : item.statusLabel}</td>
<td>
<span class="edit">📝</span>
<span class="delete">🗑️</span>
</td>
</tr>`).join('');
// 表示リセット
form.reset();
Status.innerHTML = '';
// 削除のイベントリスナー
table.querySelectorAll('.delete').forEach(dom => {
dom.addEventListener('click', deleteItem);
});
table.querySelectorAll('.edit').forEach(dom => {
dom.addEventListener('click', editItem);
});
};
フォームの作成
makeForm
関数は、フォームの select
タグに対して、Hexabaseで設定しているオプションを取得し、描画します。
ja
は日本語で、 en
に英語が設定されています。
// フォームの作成処理
const makeForm = async () => {
// ドロップダウンの項目を取得
const field = await params.datastore.field('Category');
// オプション項目を取得
const options = await field.options();
// HTMLに反映
const html = options.map(option => `
<option id="${option.id}">${option.value.ja}</option>
`);
document.querySelector('form [name="Category"]').innerHTML = html;
}
タスクの編集
既存タスクの編集アイコンをクリックすると editItem
関数が呼ばれます。これは、既存データをフォームに表示する処理です。ドロップダウンのoptionを選択状態にするところで多少工夫が必要です。
// 編集フォームの作成・項目を表示する処理
const editItem = async (e) => {
const id = e.target.closest('tr').getAttribute('data-id');
// 該当するアイテムを探す
const item = params.items.find(item => item.id === id);
// フォームの入力項目
const { elements } = form;
elements.id.value = id;
elements.Title.value = item.get('Title');
elements.Assignee.value = item.get('Assignee');
// カテゴリーのオプションを選択状態にする
const category = item.get('Category');
const field = await params.datastore.field('Category');
// オプション項目を取得
const options = await field.options();
const option = options.find(option => option.value.ja === category.ja);
elements.Category.options[option.id].selected = true;
elements.Button.innerText = '更新';
elements.Button.disabled = false;
};
タスクの更新
タスクの更新を行う処理です。id
の有無によって、新規作成と更新とを分けています。どちらも新しい値を set
メソッドで設定して、 save
メソッドで保存する流れは同じです。
document.querySelector('#button').onclick = async (e) => {
e.preventDefault();
// 新規保存と編集とを分ける
const { id } = form.elements;
const item = id.value === '' ?
await params.datastore.item() :
params.items.find(item => item.id === id.value);
// アイテムに値をセット
for (const input of Array.from(form.elements)) {
if (['Button', 'id'].indexOf(input.name) > -1) continue;
item.set(input.name, input.value);
}
// 保存
await item.save();
// 新規保存の場合は、一覧に追加
if (!id) {
params.items.push(item);
}
// 再描画
showTable();
};
まとめ
今回はUMD版Hexabase JavaScript SDKを使って、Todoアプリを作成するデモを紹介しました。UMD版Hexabase JavaScript SDKは、CDN経由で利用できるため、jQueryなど普通のWebアプリケーションでも利用できます。また、TypeScript SDKと同じように使えるため、TypeScript SDKを使っている方でも移行が容易です。
ぜひHexabaseを使ってWebアプリケーション開発を行ってください。