キャンペーンなど当選者の抽選をする時、エクセルで関数を作っていた方々に朗報です!それkintoneで楽にできるのでは?ということで、抽選カスタマイズの実装方法を紹介します。
応募者データをkintoneに溜めて、抽選します。抽選結果は2パターンでお知らせするように工夫します!
レコードは全件取得するように実装しているので、応募者数が多くなっても大丈夫です。(一人1回応募が前提)
- SweetAlertでポップアップ
- 電光掲示板風に表示
デモ環境で実際に動作を確認できます。
https://dev-demo.cybozu.com/k/297/
ログイン情報は
cybozu developer networkデモ環境
で確認してください。
- 抽選への応募者データを集めるkintoneアプリの作成
- SweetAlertでポップアップカスタマイズ
- 電光掲示板風カスタマイズ
kintoneのアプリ作成
固定リンクがコピーされました
応募者データを溜めるための抽選アプリをkintoneで作成します。
-
以下のフィールドがある「抽選」アプリを作成してください。アプリの作成方法は
こちらのヘルプ
を参照してください。
フィールドタイプ |
フィールド名 |
フィールドコード |
文字列(1行) |
名前 |
name |
文字列(1行) |
コメント |
comment |
-
サンプルのデータを数件登録しておきましょう。
JavaScript/CSSカスタマイズ
固定リンクがコピーされました
それではここからカスタマイズをしていきます。これから実装するJavaScriptとCSSファイル以外にも、3つのライブラリ(
Cybozu CDN
)を使うので、まずはそれらを「アプリの設定画面 > JavaScript / CSSでカスタマイズ」に設置します。
- jQuery
- https://js.cybozu.com/jquery/3.2.1/jquery.min.js
- SweetAlert 2
- https://js.cybozu.com/sweetalert2/v7.3.5/sweetalert2.min.js
- https://js.cybozu.com/sweetalert2/v7.3.5/sweetalert2.min.css
- Font Awesome
- https://js.cybozu.com/font-awesome/v4.7.0/css/font-awesome.min.css
以下のようにJavaScriptファイルとCSSファイルを分けて設置してください。(random_lottery.jsとrandom_lottery.cssはのちほど設置します)
ここまで下準備ができたら、本題の抽選カスタマイズに移ります。今回は2ステップあるので、順に見ていきましょう!サンプルコードのポイント解説については、次の「サンプルコード解説」で記載しています。
Step1. SweetAlertでポップアップ
固定リンクがコピーされました
まず1つ目は、抽選結果をSweetAlertでポップアップ表示をします。
以下のJavaScriptとCSSファイルを「アプリの設定 > JavaScript/CSSカスタマイズ」にアップロードして保存してください。
random_lottery.js
一覧画面にある抽選ボタンをクリックした際、作成した抽選ロジックに基づいて抽選し、SweetAlertでポップアップ表示するためのJavaScriptファイルです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
/*
* Random lottery sample program
* Copyright (c) 2018 Cybozu
*
* Licensed under the MIT License
*/
jQuery.noConflict();
(($) => {
'use strict';
// レコード一覧イベントを取得
kintone.events.on('app.record.index.show', (event) => {
// ボタン増殖防止
if (document.getElementById('lottery-button') !== null) {
return;
}
// 抽選ボタン作成
const menu = kintone.app.getHeaderMenuSpaceElement();
const $lotteryButton = $('<button class="lottery-button" id="lottery-button" title="抽選"><i class="fa fa-gift" aria-hidden="true"></i></button>');
// ボタンクリック時の操作
$lotteryButton.click(() => {
// レコード全件取得
const fetchRecords = (appId, opt_offset, opt_limit, opt_records) => {
const offset = opt_offset || 0;
const limit = opt_limit || 100;
let allRecords = opt_records || [];
const params = {
app: appId,
query: 'order by レコード番号 asc limit ' + limit + ' offset ' + offset
};
return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then((resp) => {
allRecords = allRecords.concat(resp.records);
if (resp.records.length === limit) {
return fetchRecords(appId, offset + limit, limit, allRecords);
}
return allRecords;
});
};
// 抽選実行
return fetchRecords(kintone.app.getId()).then((allRecords) => {
// 抽選ロジック作成
const num = allRecords.length;
const rand = Math.floor(Math.random() * num);
const name = allRecords[rand].name.value;
// SweetAlertで当選者表示
return swal({
title: name + 'さん当選です!😆',
text: 'おめでとうございます☆*:.。. o(≧▽≦)o .。.:*☆',
timer: 3000,
showConfirmButton: false
});
});
});
$(menu).append($lotteryButton);
});
})(jQuery);
|
random_lottery.css
抽選ボタン要素用のCSSファイルです。ボタン自体は、Font Awesomeを使ってkintoneの標準的なボタンと見た目を同一にしています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/*
* Random lottery sample program
* Copyright (c) 2018 Cybozu
*
* Licensed under the MIT License
*/
/** 抽選ボタン **/
.lottery-button {
/* color: #a8a8a8; */
color: #f5a1dc;
font-size: 32px;
display: inline-block;
padding: 0 16px;
height: 48px;
border: 1px solid #e3e7e8;
background-color: #f7f9fa;
text-align: center;
}
/** 抽選ボタンホバー時 **/
.lottery-button:hover {
/* color: #3498db; */
color: #f33bb6;
}
|
ピンクの抽選ボタンをクリックしてみてください。ポップアップ表示がされたでしょうか?
Step2. 電光掲示板風カスタマイズ
固定リンクがコピーされました
2つ目は、SweetAlert表示の後に、電光掲示板も加える工夫をします。今回はCSSのアニメーションを使って実装しています。
下のファイルを、Step1で作成したJavaScriptとCSSファイルに上書きして保存してください。
random_lottery.js
SweetAlert表示の後に、電光掲示板が入り込んでくるようにするJavaScriptファイルです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
/*
* Random lottery sample program
* Copyright (c) 2018 Cybozu
*
* Licensed under the MIT License
*/
jQuery.noConflict();
(($) => {
'use strict';
// レコード一覧イベントを取得
kintone.events.on('app.record.index.show', (event) => {
// ボタン増殖防止
if (document.getElementById('lottery-button') !== null) {
return;
}
// 抽選ボタン作成
const menu = kintone.app.getHeaderMenuSpaceElement();
const $lotteryButton = $('<button class="lottery-button" id="lottery-button" title="抽選"><i class="fa fa-gift" aria-hidden="true"></i></button>');
// ボタンクリック時の操作
$lotteryButton.click(() => {
// レコード全件取得
const fetchRecords = (appId, opt_offset, opt_limit, opt_records) => {
const offset = opt_offset || 0;
const limit = opt_limit || 100;
let allRecords = opt_records || [];
const params = {
app: appId,
query: 'order by レコード番号 asc limit ' + limit + ' offset ' + offset
};
return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then((resp) => {
allRecords = allRecords.concat(resp.records);
if (resp.records.length === limit) {
return fetchRecords(appId, offset + limit, limit, allRecords);
}
return allRecords;
});
};
// 抽選実行
return fetchRecords(kintone.app.getId()).then((allRecords) => {
// 抽選ロジック作成
const num = allRecords.length;
const rand = Math.floor(Math.random() * num);
const name = allRecords[rand].name.value;
// SweetAlertで当選者表示
return swal({
title: name + 'さん当選です!😆',
text: 'おめでとうございます☆*:.。. o(≧▽≦)o .。.:*☆',
timer: 3000,
showConfirmButton: false
}).then(() => {
// marqueeで当選者表示
const headerSpace = kintone.app.getHeaderSpaceElement();
const $boardDiv = $('<div id="board" class="board"></div>');
const $boardDivInner = $('<div id="board-inner" class="board-inner"></div>');
$boardDivInner.html(name + 'さん当選です!おめでとうございます☆*:.。. o(≧▽≦)o .。.:*☆');
headerSpace.innerHTML = null;
$boardDiv.append($boardDivInner);
$(headerSpace).append($boardDiv);
});
});
});
$(menu).append($lotteryButton);
});
})(jQuery);
|
random_lottery.css
電光掲示板の要素用のCSSファイルです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
/*
* Random lottery sample program
* Copyright (c) 2018 Cybozu
*
* Licensed under the MIT License
*/
/** 抽選ボタン **/
.lottery-button {
/* color: #a8a8a8; */
color: #f5a1dc;
font-size: 32px;
display: inline-block;
padding: 0 16px;
height: 48px;
border: 1px solid #e3e7e8;
background-color: #f7f9fa;
text-align: center;
}
/** 抽選ボタンホバー時 **/
.lottery-button:hover {
/* color: #3498db; */
color: #f33bb6;
}
/** マーキーさせたい部分 */
.board {
width: 100%;
height: 55px;
text-align: center;
font-size: 40px;
font-weight: bold;
background-image: radial-gradient(#0C94F5 10%, transparent 20%), radial-gradient(#F5C20C 10%, transparent 20%);
background-color: #fcfcfc;
background-size: 20px 20px;
background-position: 0 0, 10px 10px;
overflow: hidden; /* スクロールバーが出ないように */
position: relative; /* マーキーの内容部分の位置の基準になるように */
}
/* マーキーの内容部分の高さ確保 */
.board::after {
content: "";
white-space: nowrap;
display: inline-block;
}
/* マーキーさせたい部分(内側) */
.board > .board-inner {
position: absolute;
top: 0;
white-space: nowrap;
animation-name: marquee;
animation-timing-function: linear;
animation-duration: 20s;
animation-iteration-count: infinite;
}
/* マウスオーバーでマーキーストップ */
.board > .board-inner:hover {
animation-play-state: paused;
cursor: default;
}
/** マーキーアニメーション */
@keyframes marquee {
0% { left: 100%; transform: translate(0); }
100% { left: 0; transform: translate(-100%); }
}
|
ピンクの抽選ボタンクリックでポップアップ表示の後に、電光掲示板が現れたら成功です!
カスタマイズのポイントを解説します。
Promiseを使ってレコードの全件取得
固定リンクがコピーされました
kintone REST APIにおけるGETメソッドの一括取得は、500件までという制限があるので、レコード全件取得できるように処理を回す必要があります。
ここでは「
offsetの制限値を考慮したkintoneのレコード一括取得について
」を参考に、Promiseを用いて全件取得できるようにします。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// レコード全件取得
const fetchRecords = (appId, opt_offset, opt_limit, opt_records) => {
const offset = opt_offset || 0;
const limit = opt_limit || 100;
let allRecords = opt_records || [];
const params = {
app: appId,
query: 'order by レコード番号 asc limit ' + limit + ' offset ' + offset
};
return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', params).then((resp) => {
allRecords = allRecords.concat(resp.records);
if (resp.records.length === limit) {
return fetchRecords(appId, offset + limit, limit, allRecords);
}
return allRecords;
});
};
// 抽選実行 以下省略
// return fetchRecords(kintone.app.getId()).then((allRecords) => {
|
ランダムに抽選を行うロジックの作成
固定リンクがコピーされました
Math.random()関数
と
Math.floor()関数
を用いて、乱数を作成して抽選します。
1
2
3
4
|
// 抽選ロジック作成
const num = allRecords.length;
const rand = Math.floor(Math.random() * num);
const name = allRecords[rand].name.value;
|
Promiseを使えるようにSweetAlert 2を利用
固定リンクがコピーされました
SweetAlert 2以前だとPromiseをうまく扱えないので、今回はPromise内でも使えるように最新のSweetAlert 2を利用します。
1
2
3
4
5
6
7
8
9
|
// SweetAlert2で当選者表示
return swal({
title: name + 'さん当選です!😆',
text: 'おめでとうございます☆*:.。. o(≧▽≦)o .。.:*☆',
timer: 3000,
showConfirmButton: false
}).then(() => {
// 省略
});
|
マーキー表示用に工夫
固定リンクがコピーされました
電光掲示板風な見た目を作る(マーキー表示)ためにCSSでアニメーションをつけます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
/** マーキーさせたい部分 */
.board {
width: 100%;
height: 55px;
text-align: center;
font-size: 40px;
font-weight: bold;
background-image: radial-gradient(#0C94F5 10%, transparent 20%), radial-gradient(#F5C20C 10%, transparent 20%);
background-color: #fcfcfc;
background-size: 20px 20px;
background-position: 0 0, 10px 10px;
overflow: hidden; /* スクロールバーが出ないように */
position: relative; /* マーキーの内容部分の位置の基準になるように */
}
/* マーキーの内容部分の高さ確保 */
.board::after {
content: "";
white-space: nowrap;
display: inline-block;
}
/* マーキーさせたい部分(内側) */
.board > .board-inner {
position: absolute;
top: 0;
white-space: nowrap;
animation-name: marquee;
animation-timing-function: linear;
animation-duration: 20s;
animation-iteration-count: infinite;
}
/* マウスオーバーでマーキーストップ */
.board > .board-inner:hover {
animation-play-state: paused;
cursor: default;
}
/** マーキーアニメーション */
@keyframes marquee {
0% { left: 100%; transform: translate(0); }
100% { left: 0; transform: translate(-100%); }
}
|
イベントなどの抽選でご活用いただけるとうれしいです。ぜひCSSをいじりながら、自分好みの抽選アプリを作ってみてください!
- 画面を更新すると電光掲示板の表示を停止できます。更新しない限りは、常に流れている状態になります。