1
/
5

何かアプリを作ってみたいと思っても、いざとなるとアイデアが出てこない、、、。最初の一歩として、Monaca!ぜひチャレンジしてみてください。(後半)

作業依頼アプリを作ってみよう【その2:作業依頼の作成と一覧、コメント登録まで】

Monacaを使って何かアプリを作ってみたいと思っても、いざとなるとアイデアが出てこないかもしれません。また、最初から大きなアプリを作ろうと思うと、何から手を付けて良いのか分からないことでしょう。

そこで、この記事では手順を踏んで簡単なアプリを開発してみます。最初の一歩として、ぜひチャレンジしてみてください。

今回はNCMB(ニフクラmobile backend)と組み合わせて、作業依頼アプリを開発します。記事は全部で2回に分けており、後半となるこの記事では作業依頼の登録と一覧、作業割り当て、そしてコメント投稿機能を開発します。前半の記事はこちらです。

---アシアルでは、グローバルにご活躍いただくエンジニアを募集しております。---

フルスタック・フロントエンド
フルスタックエンジニア募集。ヨーロッパとのグローバルPJが進行中!
アシアルは、情報技術の力で、世の中の「できること」を増やすエキスパート集団です。 ビジネスの展望はあるのにシステムが追いつかず実現できない、そんな企業を、最先端の技術力とデザイン力、オーダーメイドの提案力でサポートし、ITプロジェクトを成功に導きます。 より効率的に、スピーディに、エンドユーザーのニーズに応えたいという開発者には、開発プラットフォーム「Monaca」をはじめとする、製品・サービスを提供します。 ITやプログラミングの力で、できることを増やしたいという学習者・問題解決能力を身に付けてほしいと願う教育機関へは、プログラミング教育を提供します。 アシアルは大きな会社ではありませんが、メンバー一人ひとりがクラフトマンシップを持ち、変化著しい社会の最前線で進化を続けています。私たちの力を提供することで、クライアントやユーザー、学習者の「できること」を増やし、社会の可能性を広げていきたいと思っています。 【自社開発ツール】 Monacaは、世界で25万人以上のエンジニアが使用するアプリ開発クラウドです。 OnsenUIは、100種類を超えるUIコンポーネントをオープンソースで提供。 【プログラミング教育(アシアル情報教育研究所)】 Asial(アシアル)では、これまでもコンピュータテクノロジーが持つ未来を創る力を信じ、技術の普及に努めてまりました。その経験やノウハウをもとに、先生とともに情報教育を通じて誰もが未来を創造できる社会を作ります。 学校現場で効果的かつスムーズに指導が実施できるよう、全国高等学校情報教育研究会や各自治体の教育委員会、先生方と連携して教材開発や教員向けの研修などを行っています。全国に先駆けてプログラミング教育を実施している和歌山県きのくにICT教育では、県立高校の約6000名の生徒がMonaca Educationでプログラミングを学んでいます。 【主要取引先】 株式会社朝日新聞社/株式会社アシックス/アライドテレシス株式会社/AGS株式会社/カシオ計算機株式会社/株式会社ジャパンネット銀行/株式会社世界文化社/株式会社テレビ朝日/株式会社日本経済新聞社/日本放送協会/日本ユニシス株式会社/株式会社日立製作所/フォスター電機株式会社/富士通株式会社/ブリヂストンソフトウェア株式会社/株式会社プロトコーポレーション/株式会社ベネッセi-キャリア/放送大学学園/マネックス証券株式会社/株式会社三井住友フィナンシャルグループ/楽天株式会社 (50音順) 【オフィス】 TOKYO:2-31-14 Yushima, Bunkyo-ku, Tokyo SAN FRANCISCO:201 Spear St. #1100 San Francisco, CA 94105 Budapest:1054 Budapest, Honvéd utca 8. 1. em. 2.
アシアル株式会社

作業依頼を作成する


のツールバーのプラスアイコンをタップすると遷移します (9〜11行目)。作業依頼を作成する画面はpages/new.html
です。この画面にはpages/home.html

<a href="/new/" class="link">
<i class="f7-icons">plus</i>
</a>

Copy

メソッドで行います (99〜133行目)。このメソッドは「依頼を登録する」ボタンを押した際に呼ばれます。作業依頼を作成する処理はpages/new.html
のsave

まず入力内容をオブジェクトにします (101行目)。

// 入力内容をシリアライズ(app.jsに定義)
const params = serializeForm(this.$el.find('form#task')[0]);

Copy

次にNCMBのクラス(DBでいうテーブル相当)を用意します。名前はTaskクラスとしています (103行目)。NCMBのデータストア機能の詳細については公式ドキュメントを参照してください。

// タスククラス(DBでいうテーブル相当)を用意
const Task = ncmb.DataStore('Task');

Copy

このTaskクラスのインスタンスを作ると、それがDBでいう行相当のオブジェクト(タスクオブジェクト)になります (106行目)。

// タスクオブジェクト(DBでいう行相当)を用意
const task = new Task();

Copy

メソッドを使って入力値を設定します (108行目)。そして、タスクオブジェクトのset

// 入力値を適用
for (const key in params) {
task.set(key, params[key]);
}

Copy

次にアクセス権限を設定します。これは申請者(ログインユーザ)は読み書き可能、adminグループに所属しているユーザも読み書き可能として設定します (111〜119行目)。ACLはAccess Control List (アクセス制御リスト) の略です。

// ACL(アクセス権限)を準備
const acl = new ncmb.Acl();
const user = ncmb.User.getCurrentUser();
// 申請者は読み書き可能
// adminグループのユーザの読み書き可能
acl
.setUserWriteAccess(user, true)
.setUserReadAccess(user, true)
.setRoleWriteAccess('admin', true)
.setRoleReadAccess('admin', true);

Copy

このACLと、申請者情報、ステータスを初期化して保存します (121〜127行目)。

// ACLと申請者、ステータスを初期化
task
.set('acl', acl)
.set('owner', user.displayName)
.set('status', '申請中');
// 保存
await task.save();

Copy

へ戻って、依頼登録完了した旨アラートを出します (128〜130行目)。保存処理が完了したら、前の画面pages/home.html

// 前の画面に戻る
$f7router.back();
// 完了のアラート
app.dialog.alert(依頼を登録しました);

Copy


依頼一覧画面の作成


を作成します。これは画面を表示したタイミングで、作業依頼の取得と表示を行います (42〜44行目)。次に依頼を一覧表示する画面pages/home.html

// 作業依頼の一覧を取得
const tasks = await getTasks();
// 一覧を表示
showTasks.bind(page.$el)(tasks);

Copy

getTasksはNCMBから依頼を取得する関数です (77〜83行目)。 include メソッドを使って承認者のデータも読み込みます。

// NCMBから作業一覧を取得する処理
const getTasks = async () => {
const Task = ncmb.DataStore('Task');
return await Task
.include('accept') // 承認者も読み込む
.fetchAll();
}

Copy

showTasksは受け取った一覧一覧のデータを描画する処理です (86〜96行目)。HTMLのテーブルタグに渡されたデータを流し込むだけです。

// 作業一覧を表示する処理
const showTasks = function(tasks) {
this.find('.tasks tbody').html(tasks.map(task => `
<tr data-objectId="${task.objectId}">
<td>${task.status}</td>
<td>${task.accept ? task.accept.displayName : '未定'}</td>
<td>${task.category}</td>
<td>${task.detail}</td>
<td>${task.priority}</td>
</tr>
`).join(''))
};

Copy

一覧を表示したら、各行をタップした際のイベントを設定します (47〜53行目)。タップされた作業依頼を特定し、それを編集画面に送ります。

// 表示した作業一覧にイベント設定
page.$el.find('.tasks tbody tr').on('click', e => {
// 選択された作業を取得
const objectId = $(e.target).parents('tr').data('objectId');
const task = tasks.filter(task => task.objectId === objectId)[0];
// 編集画面に移動
$f7router.navigate({name: 'Edit'}, {props: { task }});
});

Copy

作業編集画面の作成


では、前の画面(一覧画面)から受け取った作業依頼データを描画します。Framework7ではテンプレートに文字列リテラルが利用できるので、JavaScriptをそのまま書けます (40〜45行目)。編集画面pages/edit.html

<div class="item-content">
<div class="item-inner">
<div class="item-header">依頼者</div>
${task.owner}
</div>
</div>

Copy

そして作業担当者を割り当てる際には、Framework7の絞り込み機能付きのドロップダウンを利用します。

<a
class="item-link smart-select smart-select-init"
data-open-in="popup"
data-searchbar="true"
data-searchbar-placeholder="絞り込み"
>
<select name="worker" id="worker">
</select>
<div class="item-content">
<div class="item-inner">
<div class="item-title">作業担当者</div>
</div>
</div>
</a>

Copy

に対してユーザを追加していきます。JavaScript側ではユーザの一覧を取得し、このドロップダウン#worker

const users = await ncmb.User.fetchAll();
$('#worker').html(users.map(user => `
<option value="${user.objectId}">${user.displayName}</option>
`).join(''));

Copy


管理者とユーザでの表示の出し分け

作業者の割り当ては管理者しか行えません。作業担当者・依頼者は作業依頼の閲覧・ステータスの変更・コメントの追加のみ行います。CSSを使って権限による表示の出し分けをしましょう (148〜158行目)。

// ログインユーザを取得
const user = ncmb.User.getCurrentUser();
// 管理者であれば
if (user.get('admin')) {
// 作業者向けのUI項目を非表示に
$('.only-no-admin').hide();
} else {
// 管理者向けのUI項目を非表示に
$('.only-admin').hide();
// コメントを表示
showComment.bind(page.$el)(task.comments);
}

Copy

ここで出てきた showComment はコメントを表示する関数です。単純にHTMLを表示しているだけなので、下記のコードを参照してください (220〜234行目)。

// コメントを表示する処理です
const showComment = function(comments) {
if (!comments) return;
this.find('#comments').html(this.find('#comments').html() + comments.map(comment => `
<li>
<div href="#" class="item-content">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">${comment.displayName}</div>
</div>
<div class="item-text">${comment.comment}</div>
</div>
</div>
</li>
`).join(''))
};

Copy


情報の更新

更新ボタンを押したタイミングで save メソッドが実行されます。先程の作業依頼を登録する際とあまり変わりません (166〜198行目)。

まず入力内容をオブジェクト化します (168行目)。

// 入力内容をシリアライズ(app.jsに定義)
const params = serializeForm(this.$el.find('form#task')[0]);

Copy

作業担当者が設定したステータスをタスクオブジェクトにセットします (169行目)。

task.set('status', params.status);

Copy

次に管理者が作業担当者を割り当てた場合を想定し、ACLを作成します。この時のACLは、作業担当者に対して作業依頼データの読み書き権限を追加するものです (172〜184行目)。

// 作業者を特定
const worker = users.filter(u => u.objectId === params.worker)[0];
if (worker) {
// 現在のアクセス権限を取得
const acl = task.get('acl');
// 作業者の分を追加
acl[params.worker] = {
write: true,
read: true
};
task
.set('acl', acl)
.set('worker', params.worker)
.set('workerName', worker.displayName); // 作業者名を設定
}

Copy

そして管理者アカウントであれば、自分自身を承認者として設定します。また、作業依頼が申請中の状態であれば、作業中に変更します (186〜193行目)。

// 管理者だったら承認者として設定
const user = ncmb.User.getCurrentUser();
if (user.admin) {
task
.set('accept', user);
if (task.status === '申請中') {
task.set('status', '作業中');
}
}

Copy

後はタスクを更新し、クラウド側のデータに反映します (195行目)。

await task.update();

Copy

更新完了したら、前の画面に戻ります (197行目)。

// 前の画面に戻る
$f7router.back();

Copy

コメントを登録する

関数 (201〜217行目) を呼び出します。この処理では入力されたコメント内容と入力者(ログインユーザ)情報を、作業依頼データの comments フィールドに追加します。NCMBはRDBMSではないので、データを柔軟に管理できます。また、一つのデータ(今回は作業依頼データ)の中に入れることでネットワーク利用回数の低減が実現できます。コメントはコメント投稿ボタンを押した際にcomment

// コメント処理
const comment = async function() {
const comment_body = this.$el.find('#comment_body');
// コメントを作成
const comment = {
comment: comment_body.val(),
displayName: ncmb.User.getCurrentUser().displayName,
};
// 作業のcommentsに追加して更新
await task
.add('comments', comment)
.update();

// 入力を消す
comment_body.val('');
// コメントを追記
showComment.bind(this.$el)([comment]);
}

Copy


まとめ

今回の作業依頼アプリの内容は以上です。データの追加、更新そして検索はどのようなアプリでも必要とされる機能です。今回のアプリを参考に、ぜひ実装してみてください。他にもNCMBにはファイルを保存する機能やプッシュ通知機能があります。こちらもぜひ皆さんのアプリ開発に活かしてください。

Framework7とMonacaを組み合わせることで、多彩な機能を持ったUIのアプリを開発できるようになります。ぜひトライしてみてください。

アシアル株式会社's job postings

Weekly ranking

Show other rankings
If this story triggered your interest, go ahead and visit them to learn more