この記事では、kintone(キントーン)をデータベースとして利用したモバイルアプリを作成していきます。
キントーンにてサンプルアプリの一つとして提供されている「院内掲示板アプリ」をベースとしてiOS/Androidの掲示板アプリを作ります。
前回記事では、下の機能を実装していきました。
- アプリへのログイン機能
- スレッド一覧画面
- スレッド一覧の取得
- 新規スレッドの登録
今回の後編記事では、次の機能を作成していきます。
- スレッド詳細画面の作成
- スレッドのコメントの取得
- スレッドの添付ファイルの取得
- スレッドのコメントの登録
プロジェクトのソースコードは、GitHubに配置しています。
https://github.com/monaca-samples/kintone-bbs
スレッド一覧からの画面遷移
スレッド一覧画面でスレッドをタップしたら、スレッド詳細画面に遷移します。
これは www/pages/threads.html
に定義しています。
// スレッド一覧をタップした際のイベント
const click = (record) => {
// スレッド詳細画面に遷移
$f7router.navigate(/threads/${record.$id.value}
, {
props: {
record,
},
});
}
スレッド詳細画面
スレッド詳細画面では、前の画面から送られてきたスレッドの詳細を表示します。
また、そのスレッドに投稿されたコメントを表示します。
ファイル www/pages/thread.html
に、次のようにコーディングしています。
<div class="page-content">
<div class="list media-list">
<ul>
<li>
<div class="item-content">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">${record.title.value}</div>
<div class="item-after">${record.pubDate.value}</div>
</div>
<div class="item-subtitle">${record.level.value}</div>
<div class="item-text">${showText(record.body.value)}</div>
</div>
</div>
</li>
<li>
${attachments.map(a => $h`
<div class="item-content">
<div class="item-inner">
<img src="${a}" width="100%" />
</div>
</div>
`)}
</li>
</ul>
</div>
<div class="block-title">コメント</div>
<div class="list media-list">
<ul>
${comments.map(c => $h`
<li>
<div class="item-content">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">${c.creator.name}</div>
<div class="item-after">${dayjs(c.createdAt).format('MM月DD日 HH:mm')}</div>
</div>
<div class="item-text">${c.text}</div>
</div>
</div>
</li>
`)}
</ul>
</div>
<div class="list inset">
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<textarea id="text" class="resizable"></textarea><br />
<button class="button" @click=${addComment}>コメントする</button>
</div>
</div>
</li>
</ul>
</div>
</div>
コメントの取得
続いてコメントの取得処理です。
コメントの取得は、スレッド詳細画面を表示したタイミングで、kinotoneへアクセスし取得しています。
下のコードの「initView( )」にて「getCommnets( )」を実行し、コメント取得しています。
// ファイル: www/pages/thread.html
export default (props, { $f7, $f7router, $update, $onMounted }) => {
const { record } = props; // 前の画面から送られてくるスレッドデータ
let comments = []; // コメント一覧用
let attachments = []; // 添付ファイル用
// 画面をマウントした際に実行されるイベント
$onMounted(async () => {
initView(); // 初期表示用
getAttachments(); // 添付ファイルの取得
});
// 初期表示用関数
const initView = async () => {
// コメントの取得
const res = await getComments({
app: KINTONE_APP_ID,
record: record.$id.value,
});
// コメントを変数に入れる
comments = res.data.comments;
// 画面更新
$update();
};
}
getComments
関数は、ファイル js/app.js
にあります。
この関数では、kintoneのレコードコメント一括取得APIである次のURLにGETメソッドで
アクセスしています。
https://(サブドメイン名).cybozu.com/k/v1/record/comments.json
// ファイル: www/js/app.js
// コメント取得用関数
const getComments = (params) => {
const options = {
method: 'get',
params,
};
return sendRequest(/record/comments.json
, options);
}
添付ファイルの取得
次は、添付ファイルを取得する処理についてです。
getAttachments
関数でファイルの取得をしています。
(このアプリ扱う添付ファイルは、画像としています。)
// 添付ファイルの取得
const getAttachments = async () => {
if (record.attachment.value.length === 0) return;
try {
// 添付ファイルのダウンロード
const promises = record.attachment.value.map(a => downloadFile(a.fileKey));
const response = await Promise.all(promises);
attachments = response.map(res => URL.createObjectURL(res.data));
$update();
} catch (e) {
console.log(e);
}
}
downloadFile
関数は、 js/app.js
にて定義されています。
次のkintoneのファイルダウンロードAPIを呼び出して実装しています。
https://(サブドメイン名).cybozu.com/k/v1/file.json
// ファイル: www/js/app.js
// ファイルダウンロード用
const downloadFile = (fileKey) => {
const options = {
method: 'get',
params: {
fileKey
}
};
return sendRequest('/file.json', options, 'json', 'blob');
}
ダウンロードした内容は Blob
型になっています。
HTMLでBlob形式の画像を表示するため、
URL.createObjectURL
を使って blob:〜
形式に変換しています。
また、このファイルを表示する際には index.html
のCSP設定を、次のように変更する必要があり、少し注意が必要です。
<!-- 最後に blob: を追加します-->
<meta http-equiv="Content-Security-Policy" content="default-src * "self" "unsafe-inline" "unsafe-eval" data: gap: content: blob:">
ファイルの表示は、テンプレートの attachments
にて処理しています。
//ファイル: www/pages/thread.html
<li>
${attachments.map(a => $h`
<div class="item-content">
<div class="item-inner">
<img src="${a}" width="100%" />
</div>
</div>
`)}
</li>
コメントの登録
新しいコメントを入力しコメントボタンが押されたら、 addComment
関数が呼ばれます。
この関数では、kintoneへコメントを登録します。
また、コメントの登録後に、
いま登録したコメントを含めて、全体のコメントの再取得を行うために initView
関数を呼び出します。
// ファイル: www/pages/thread.html
// コメントを登録するイベント
const addComment = async () => {
// 入力値の取得
const text = $("#text").val();
// コメント投稿
await postComment({
app: KINTONE_APP_ID,
record: record.$id.value,
comment: {
text,
}
});
// 画面を表示し直し
initView();
};
postComment
関数は、 js/app.js
にあります。
kintoneのレコードコメント投稿APIを利用しています。
POSTメソッドで、次のURLにアクセスしています。
https://(サブドメイン名).cybozu.com/k/v1/record/comment.json
// ファイル: www/js/app.js
// コメント登録用関数
const postComment = (data) => {
const options = {
method: 'post',
data,
};
return sendRequest(/record/comment.json
, options);
};
登録したコメントは、kintoneでも確認できます。
まとめ
今回のサンプルアプリでは、ファイル www/js/app.js に、kintoneへアクセスする共通処理をまとめています。
この共通処理を再利用することにより、Monaca上でkintone連携アプリを開発することもスムーズにできるかと思います。
JavaScriptとHTMLを利用して、カスタマイズしたkintoneモバイルアプリを開発することが可能ですので、ぜひMonacaをお試しいただければと思います。