2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UMD版Hexabase JavaScript SDKを使ってTodoアプリを作る(タスクの表示・編集)

Posted at

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で体験できます。

image.png

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アプリケーション開発を行ってください。

Hexabase | 新規事業向け開発・競争領域でのDX実現をサポート

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?