Web無料相談会2018冬
Web無料相談会2018冬
2018.05.01
#145
それいけ!フロントエンド

jQuery + Firebaseで投票システムを作ってみよう!

はっちゃん

ただいまご紹介に預かりました、はつしです。

今回は、みんな大好きjQueryとFirebaseで簡単な投票システムを作ってみましょう。

Firebaseの使い方は以前僕が書いた記事をご参照下さい。

データベースをセット

firebaseにログインして下記のように値をセットします。

ルールタブを押し、コードを以下のように書き換えます。

投票画面側

まずは、投票する側の画面を作成します。
いい感じにHTMLを組んで、jqueryとfirebaseを読み込みます。
firebase読み込みのコードは以下です。

<script src="https://www.gstatic.com/firebasejs/4.6.0/firebase.js"></script>

JSを書きます

以下のようにJSを書きます。

const TRANSITION_END = 'transitionend';

firebase.initializeApp({databaseURL: "https://blog-7c0b7.firebaseio.com"});

let database = firebase.database(); //firebase初期化
let refCount = database.ref('count');
let $post = $('.js-post');
let $count = $('.js-count');
let countObj = {
  'hatsushi': 0,
  'masakuni': 0,
  'tk': 0,
  'kaz': 0
};
let countStop = false;
let $layer = $('.js-layer');
let $layerLoading = $('.js-layer-loading');

/*
 * View
 * ・カウント表示
 */
let defRenderCount = (countObj) => {
  let $targetCountObj = $(`.js-count-${countObj.id}`);

  $targetCountObj.text(countObj.value);
};

let renderCount = (countObj) => {
  for (let key in countObj){
    if(parseInt($(`.js-count-${key}`).text(), 10) !== countObj[key]) {
      let $targetCountObj = $(`.js-count-${key}`);
      let $targetCountObjPost = $targetCountObj.closest('.js-post');

      $targetCountObj.text(countObj[key]);
    }
  }
};

let postActionCount = (initial, countVal) => {
  let arg = {};
  arg[initial] = countVal;
  show();
  refCount.update(arg).then((res)=>{
    setTimeout(() => {
      hide();
    }, 300);
  });
};

/*
 * クリックイベント
 * ・ボタンクリック
 * ・初期読み込み
 * ・pushイベント検知
 */
$post.on('click', (e) => {
  if (countStop) {
    return;
  }
  let initial = $(e.currentTarget).data('initial');
  countObj[initial] = countObj[initial] + 1;
  postActionCount(initial, countObj[initial]);
});

refCount.on("child_added", (snapshot) => {
  // データベースと同期
  countObj[snapshot.key] = snapshot.val();

  defRenderCount({
    id: snapshot.key,
    value: snapshot.val()
  });
});

refCount.on("value", (snapshot) => {
  let snapshotObj = snapshot.val();

  // データベースと同期
  for (let key in snapshotObj){
    countObj[key] = snapshotObj[key];
  }

  renderCount(snapshot.val());
});

/*
 * その他
 */
let show = () => {
  $layer.removeClass('dn');
  $layerLoading.removeClass('dn');
  $layer.addClass('is-show');
};

let hide = () => {
  $layer.removeClass('is-show').one(TRANSITION_END, () => {
    $layerLoading.addClass('dn');
    $layer.addClass('dn');
  });
};

 

See the Pen firebase vote screen by k_hatsushi (@hatsushi_kazuya) on CodePen.

画面を操作してみる

表示された画面で、ボタンを押すと、数字がカウントアップします。
firebaseの管理画面の方でも数字が書き換わります。

投票結果画面側

投票結果画面を作成します。
この画面は、更新された値を表示する画面になります。
投票画面同様にHTMLを組んでfirebaseライブラリーを読み込みます。

データベースの更新を検知

こちらではクリックイベントは存在せず、databaseの更新を監視します。

const TRANSITION_END = 'transitionend';

firebase.initializeApp({databaseURL: "https://blog-7c0b7.firebaseio.com"});

/*
 * 初期化
 */
let database = firebase.database();
let refCount = database.ref('count');
let $post = $('.js-post');
let countObj = {};
let $count = $('.js-count');
let countStop = false;
let $layer = $('.js-layer');
let $layerCountStop = $('.js-layer-count-stop');

/*
 * View
 * ・カウント表示
 */
let defRenderCount = (countObj) => {
  $(`.js-count-${countObj.id}`).text(countObj.value);
};

let renderCount = (countObj) => {
  for (let key in countObj){
    if(parseInt($(`.js-count-${key}`).text(), 10) !== countObj[key]) {
      $(`.js-count-${key}`).text(countObj[key]);
      let $targetCountObjPost = $(`.js-count-${key}`).closest('.js-post');
    }
  }
};

/*
 * クリックイベント
 * ・pushイベント検知
 */
refCount.on("child_added", (snapshot) => {
  // データベースと同期
  //countObj[snapshot.key] = snapshot.val();

  defRenderCount({
    id: snapshot.key,
    value: snapshot.val()
  });
});

refCount.on("value", (snapshot) => {
  renderCount(snapshot.val());
});

 

See the Pen firebase vote result screen by k_hatsushi (@hatsushi_kazuya) on CodePen.

リアルタイムに更新されているか確認してみる

それでは投票画面、投票結果画面、firebaseの管理画面を同時に開いてリアルタイム更新を確認してみましょう。

おお!動いてますね!

まとめ

いかがでしたか? Firebaseを使うと、サーバーの知識がなくても、jsだけで簡単にリアルタイムデータベースを使えちゃいます。

この機会に是非お試しあれ。