Google Wave API開発ガイド(前編)

プレビュー公開が始まったGoogle Wave「超」入門


株式会社鳥人間
郷田まり子
2009/10/1


投票Gadgetを作ってみた

 以下のサンプル「投票Gadget」は、Wave参加者が賛成/反対に票を投じるというものです。

 投じられた票をカウントし、投票した人のアイコンを並べます。後から気が変わったら票を入れ直すこともできます。

 

サンプルの「投票Gadget」
サンプルの「投票Gadget」

 ボタンを含んだテーブルと、Waveオブジェクトを使用したJavaScriptを含んだXMLを書きます。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="VoteGadget">
<Require feature="wave"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<table border="1" style="empty-cells:show;">
<!-- 投票ボタンの行 -->
<tr>
<td>賛成の人<input type="button" value="投票" onclick="vote(true)"/></td>
<td>反対の人<input type="button" value="投票" onclick="vote(false)"/></td>
<td>まだの人</td>
</tr>
<!-- 票数カウントの行 -->
<tr>
<td><span id="labelCountAgree"></span></td>
<td><span id="labelCountDisagree"></span></td>
<td id="labelCountNotyet"></td>
</tr>
<!-- 投票した人のアイコンを表示する行 -->
<tr>
<td id="agreeIcons"></td>
<td id="disagreeIcons"></td>
<td id="notyetIcons"></td>
</tr>
</table>

<script type="text/javascript">

var icons = {}; //ユーザーアイコンを保存しておくオブジェクト

// 初期化処理
function init(){
if (wave && wave.isInWaveContainer()) {
//State更新時の処理を登録
wave.setStateCallback(stateUpdated);
// 参加者の更新処理を登録
wave.setParticipantCallback(participantUpdated);
}
}

//初期化処理を登録する
gadgets.util.registerOnLoadHandler(init);

// 参加者情報が更新されたときの処理
function participantUpdated(){
var participants = wave.getParticipants(); // 参加者の配列を取得
for (var i = 0, l = participants.length; i < l; i++) {
var id = participants[i].getId();
// アイコンを更新、新しい参加者のアイコンは新たに生成する
var icon = icons[id] || document.createElement('IMG');
icon.src = participants[i].getThumbnailUrl();
// icons オブジェクトに登録
icons[id] = icon;
}
}

// 投票ボタンを押したときの処理
function vote(agree){
var state = wave.getState(); //Stateオブジェクトを取得
//Stateに、ユーザーIDをkey、賛否をvalueとして格納
state[wave.getViewer().getId()] = (agree) ? "agree" : "disagree";
//Stateの更新を送信
wave.getState().submitDelta(state);
}

//Stateが更新されたときの処理
function stateUpdated(){
var participants = wave.getParticipants(); // 参加者の配列を取得
var countAgree = 0;
var countDisagree = 0;

for (var i = 0, l = participants.length; i < l; i++) {
var id = participants[i].getId();
var icon = icons[id];

var cell;

//どのセルにアイコンを入れるかの判定、賛成者・反対者のカウント
if ('agree' == wave.getState().get(id)) {
cell = document.getElementById('agreeIcons');
countAgree++;
}else if ('disagree' == wave.getState().get(id)) {
cell = document.getElementById('disagreeIcons');
countDisagree++;
} else
cell = document.getElementById('notyetIcons');
cell.appendChild(icon); //アイコンを移動
}
// 賛成者・反対者の数を表示
document.getElementById('labelCountAgree').innerHTML= countAgree + '人';
document.getElementById('labelCountDisagree').innerHTML= countDisagree + '人';
}

</script>
]]>
</Content>
</Module>

 まず、init関数の中で、State更新時と参加者更新時それぞれのコールバック関数をセットします。

// 初期化処理
function init(){
    if (wave && wave.isInWaveContainer()) {
        //State更新時の処理を登録
        wave.setStateCallback(stateUpdated);
        // 参加者の更新処理を登録
        wave.setParticipantCallback(participantUpdated);
    }
}

 参加者に変更があったときは、参加者それぞれのアイコンを更新します。

// 参加者情報が更新されたときの処理
function participantUpdated(){
var participants = wave.getParticipants(); // 参加者の配列を取得
for (var i = 0, l = participants.length; i < l; i++) {
var id = participants[i].getId();
// アイコンを更新、新しい参加者のアイコンは新たに生成する
var icon = icons[id] || document.createElement('IMG');
icon.src = participants[i].getThumbnailUrl();
// icons オブジェクトに登録
icons[id] = icon;
}
}

 投票ボタンを押したときには、 vote関数を呼びます。ここでStateオブジェクトの更新を行っています。Stateオブジェクトには、投票した人のIDをキー、賛否を値として登録します。そして、submitDeltaメソッドによって、Stateオブジェクトを送信します。

    // 投票ボタンを押したときの処理
function vote(agree){
var state = wave.getState(); // State オブジェクトを取得
// State に、ユーザIDをkey、賛否をvalueとして格納
state[wave.getViewer().getId()] = (agree) ? "agree" : "disagree";
// State の更新を送信
wave.getState().submitDelta(state);
}

 参加者の誰かがStateの更新を行うと、それは参加者全員に通知されます。参加者全員のクライアントサイドで、stateUpdated関数が呼ばれ、その中で、Stateから値を取得して票をカウントし、アイコンをしかるべき場所に移動させ、表が更新されます。

// State が更新されたときの処理
function stateUpdated(){
var participants = wave.getParticipants(); // 参加者の配列を取得
var countAgree = 0;
var countDisagree = 0;

for (var i = 0, l = participants.length; i < l; i++) {
var id = participants[i].getId();
var icon = icons[id];

var cell;

//どのセルにアイコンを入れるかの判定、賛成者・反対者のカウント
if ('agree' == wave.getState().get(id)) {
cell = document.getElementById('agreeIcons');
countAgree++;
}
else if ('disagree' == wave.getState().get(id)) {
cell = document.getElementById('disagreeIcons');
countDisagree++;
} else
cell = document.getElementById('notyetIcons');

cell.appendChild(icon); //アイコンを移動
}
// 賛成者・反対者の数を表示
document.getElementById('labelCountAgree').innerHTML = countAgree + '人';
document.getElementById('labelCountDisagree').innerHTML = countDisagree + '人';
}

 これで、リアルタイム投票を行うGadgetができました。

 1つのWaveに同じ種類のGadgetを複数埋め込むこともできます。その場合、Stateはそれぞれ別個のものとなるので、議題ごとに投票Gadgetを埋め込んでオンライン会議もできます。

 次ページでは、Embed開発の基礎知識について解説します。

1-2-3-4

 INDEX
Google Wave API開発ガイド(前編)
プレビュー公開が始まったGoogle Wave「超」入門
  Page1
ついにプレビュー公開が始まった「Google Wave」とは
Google Waveって結局、何ができるの?
Waveの3つのカタチGadget、Robot、Embed
  Page2
Google Wave Gadget開発の基礎知識
Page3
投票Gadgetを作ってみた
  Page4
Google Wave Embed開発の基礎知識
今後次々と充実? Embed APIのこれから


リッチクライアント&帳票 全記事一覧へ



HTML5 + UX フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日 月間