ラベル JSONP の投稿を表示しています。 すべての投稿を表示
ラベル JSONP の投稿を表示しています。 すべての投稿を表示

2010年6月19日土曜日

ATNDから自分の参加するイベント一覧を取得してみた

私はATND というサービスをよく利用します。
このサイトは、イベントの参加登録ができるサイトで、よくIT系のイベントが登録されています。

ATNDはAPIが公開されており、APIを使って自由に検索ができるようになっています。
http://api.atnd.org/

そこで、私自身が参加しようとして登録してあるイベント一覧をこのブログに載せるガジェットを作ってみました。

とりあえず、自分自身が参加登録している一覧を取得するには下記のURLを使用します。
http://api.atnd.org/events/?user_id={個人のID}

私の場合はIDが21348なので
http://api.atnd.org/events/?user_id=21348
となります。

今回はjavascriptで全て実装したいので、jsonp形式でレスポンスをうけとります。
http://api.atnd.org/events/?user_id=21348&count=5&callback=atndCallback&format=jsonp


JSONPについては以前紹介した物がありますので、そちらを参照ください。
JSONPの使い方

作成したガジェット自体は、右の"参加予定のイベント"がそれになります!
javascriptだけで、これだけできるのでやっぱりjavascriptは便利です!
知っておいて損はないなー

・ガジェットのソース
var atndEdit = function() {
 //jsonp
 var url = 'http://api.atnd.org/events/?user_id=21348&count=5&callback=atndCallback&format=jsonp';
 var ele = document.createElement('script');
 ele.type = 'text/javascript';
 ele.src = url;
 document.body.appendChild(ele);
 //今日の日付作製
 var nowDate = new Date();
 var month = (nowDate.getMonth() + 1);
 month = month.length === 2 ? month : '0' + month;
 var day = nowDate.getDate();
 day = day.length === 2 ? day : '0' + day;
 var nowStrDate = nowDate.getFullYear() + month + day;
 //出力先
 var output = document.getElementById('atnd-div');
 var count = 0;
 return {
  disp : function(events) {
   var eventDate = events.ended_at.substring(0, 10).replace(/-/g, '');
   if(eventDate < nowStrDate) {
    if(count == 0) {
     output.innerHTML = '参加予定のイベントはありません';
    }
    return;
   }
   count++;
   var title = events.title;
   var url = 'http://atnd.org/events/' + events.event_id;
   var start = events.ended_at.substring(0, 10);

   var ele = document.createElement('a');
   ele.href = url;
   ele.target = '_blank';
   ele.innerHTML = title;

   var date = document.createElement('span');
   date.innerHTML = '・' + start + '';
   output.appendChild(date);
   output.appendChild(document.createElement('br'));
   output.appendChild(ele);
   output.appendChild(document.createElement('br'));
  }
 };
}();
function atndCallback(data) {
 var events = data.events;
 for(var i = 0; i < events.length; i++) {
  var eventDate = events[i].ended_at.substring(0, 10).replace(/-/g, '');
   atndEdit.disp(events[i]);
 }
}

2010年2月25日木曜日

Googleカレンダーの直近スケジュールを表示させる

GoogleカレンダーにIT関連イベントを登録しているのですが、このデータをブログのサイドに表示させたかったので作ってみました。
実際に作成したものは、このブログのサイドに表示させています。

■データ取得方法
まずは、Googleカレンダーからカレンダー情報をJSONP形式で取得します。
JSONP形式のデータを取得するためには、下記URLで実現できます。
http://www.google.com/calendar/feeds/bosh0h7tg9ddmhav7a537bguh4%40group.calendar.google.com/public/full?alt=json-in-script&callback=insertCalendar

もし、自分のカレンダーで試したいのであればURLを下記のようにしてください
"http://www.google.com/calendar/feeds/" + GoogleカレンダーURL + "/public/full?alt=json-in-script&callback=insertCalendar"

これで、JSONP形式でレスポンスを得ることができました。
callback関数名はパラメータに渡したinsertCalendarになります!

ここまでくればあとちょっと!

日付順で取得したいので
"orderby=starttime&sortorder=ascending"をパラメータに追加!

未来の予定が欲しいので
"futureevents=true"をパラメータに追加!

最大件数は7件がいいので
"max-results=7"をパラメータに追加!

これでURLが完成!
http://www.google.com/calendar/feeds/bosh0h7tg9ddmhav7a537bguh4%40group.calendar.google.com/public/full?alt=json-in-script&callback=insertCalendar&orderby=starttime&max-results=7&singleevents=true&sortorder=ascending&futureevents=true

ちなみに参考API
http://code.google.com/intl/ja/apis/gdata/docs/json.html

■データ表示
前回のJSONPの使い方で紹介した方法を使い表示部分の実装していきます。

コールバック関数名がinsertCalendarなので、この関数名で実装します。
今回、このブログでは下記のソースを使用しています。

var edit = function() {
// ① scriptタグを出力し、サーバから取得できる下記文字列をHTML上に展開させる
// insertCalendar({jsonデータ});
var url = 'http://www.google.com/calendar/feeds/bosh0h7tg9ddmhav7a537bguh4%40group.calendar.google.com/public/full?alt=json-in-script&callback=insertCalendar&orderby=starttime&max-results=7&singleevents=true&sortorder=ascending&futureevents=true';
var ele = document.createElement('script');
ele.type = 'text/javascript';
ele.src = url;
document.body.appendChild(ele);
// 文字列を出力する場所を取得
var output = document.getElementById('ak-javascript');
return {
disp : function(events) {
// ③ 1個のイベント情報を表示様に整形して行く
var title = events.title.$t;
var content = events.content.$t;
var start = events.gd$when[0].startTime;
var link;
if(content) {
var contents = content.split('\n');
for(var i = 0; i < contents.length; i++) {
var con = contents[i];
if(con.indexOf("http",0) == 0) {
link = con;
break;
}
}
}
var ele;
if(link) {
ele = document.createElement('a');
ele.href = link;
ele.target = '_blank';
ele.innerHTML = title;
} else {
ele = document.createElement('span');
ele.innerHTML = title;
}
var date = document.createElement('span');
date.innerHTML = '・' + start + '';
// ④ HTML上に出力する
output.appendChild(date);
output.appendChild(document.createElement('br'));
output.appendChild(ele);
output.appendChild(document.createElement('br'));
}
};
}();
// ② コールバック関数
function insertCalendar(data) {
var feed = data.feed;
if(!feed) {
return;
}
var events = feed.entry;
for(var i = 0; i < events.length; i++) {
edit.disp(events[i]);
}
}

■解説
ソースの①~④までが順番に呼ばれます。
①にて、scriptタグをHTML上に出力すると、urlに書かれている場所からデータをダウンロードします。
ダウンロードしたデータにはinsertCalendarを実行するように記述されたデータが返されるため、②の関数が実行されます。
②の関数の実行時に渡されるjsonデータを分解し、1個ずつの登録データに分けて出力処理を行います。
③にて、データの整形を行っています。今回はカレンダーに登録されている詳細情報からURLを抽出して、リンクをつけるように整形しています。
最後に、④にてHTML上に出力を行っています。

以上の流れで、このブログ上にGoogleカレンダーから取得したイベントデータが表示されています。

JSONPを使うことによって、このように別のサーバからデータを取得することができます。
そして、アイデア次第でいろんな便利な事ができます!
ぜひ試してみてください!

JSONPの使い方

JavaScriptで別のドメインのデータを取得したいとすると、クロスドメイン問題にぶつかると思います。
この問題を解決するためには、JSONP(JSON with paddingの略)というモノを使用することになると思います。
他にも方法はありますが、きっとこれが一番簡単なのではないでしょうか?

実際の使い方を書きます
下記URLにアクセスすると、
http://always.ddo.jp/blog/jsonp/test.jsonp

test( { "name" : "hoge", "age" : "100" } );
このような文字列が返却されます。

この文字列をよく見ると、
javascriptのtest関数に'{ "name" : "hoge", "age" : "100" }'というjson形式のデータを渡しているように見えると思います。

JSONPについては、これが全てです!

下記ソースをFirebugのコンソールなどに貼って実行してみてください。

別のドメインの情報を取得して、ページ内で取得データを使用できるようになりました!

■解説
ソースに存在する無名関数にて、scriptタグを生成しています。
このscriptタブのsrc属性に、最初に記述したjsonpデータを返却するURLを記述します。
そうすると、帰ってきたデータがクライアントのHTML上に展開され、javascriptのtest関数を呼びます。
test関数は、自分で好きな様に記述できるので、引数を受け取って今回はalertしています。

次回はGoogleカレンダーと連携した、もう少し面白い使い方を紹介したいと思います。

'},ClipboardSwf:null,Version:'1.5.1'}};dp.SyntaxHighlighter=dp.sh;dp.sh.Toolbar.Commands={ExpandSource:{label:'+ expand source',check:function(highlighter){return highlighter.collapse;},func:function(sender,highlighter) {sender.parentNode.removeChild(sender);highlighter.div.className=highlighter.div.className.replace('collapsed','');}},ViewSource:{label:'view plain',func:function(sender,highlighter) {var code=dp.sh.Utils.FixForBlogger(highlighter.originalCode).replace(/'+code+'');wnd.document.close();}},CopyToClipboard:{label:'copy to clipboard',check:function(){return window.clipboardData!=null||dp.sh.ClipboardSwf!=null;},func:function(sender,highlighter) {var code=dp.sh.Utils.FixForBlogger(highlighter.originalCode).replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');if(window.clipboardData) {window.clipboardData.setData('text',code);} else if(dp.sh.ClipboardSwf!=null) {var flashcopier=highlighter.flashCopier;if(flashcopier==null) {flashcopier=document.createElement('div');highlighter.flashCopier=flashcopier;highlighter.div.appendChild(flashcopier);} flashcopier.innerHTML='';} alert('The code is in your clipboard now');}},PrintSource:{label:'print',func:function(sender,highlighter) {var iframe=document.createElement('IFRAME');var doc=null;iframe.style.cssText='position:absolute;width:0px;height:0px;left:-500px;top:-500px;';document.body.appendChild(iframe);doc=iframe.contentWindow.document;dp.sh.Utils.CopyStyles(doc,window.document);doc.write('

'+highlighter.div.innerHTML+'

');doc.close();iframe.contentWindow.focus();iframe.contentWindow.print();alert('Printing...');document.body.removeChild(iframe);}},About:{label:'?',func:function(highlighter) {var wnd=window.open('','_blank','dialog,width=300,height=150,scrollbars=0');var doc=wnd.document;dp.sh.Utils.CopyStyles(doc,window.document);doc.write(dp.sh.Strings.AboutDialog.replace('{V}',dp.sh.Version));doc.close();wnd.focus();}}};dp.sh.Toolbar.Create=function(highlighter) {var div=document.createElement('DIV');div.className='tools';for(var name in dp.sh.Toolbar.Commands) {var cmd=dp.sh.Toolbar.Commands[name];if(cmd.check!=null&&!cmd.check(highlighter)) continue;div.innerHTML+=''+cmd.label+'';} return div;} dp.sh.Toolbar.Command=function(name,sender) {var n=sender;while(n!=null&&n.className.indexOf('dp-highlighter')==-1) n=n.parentNode;if(n!=null) dp.sh.Toolbar.Commands[name].func(sender,n.highlighter);} dp.sh.Utils.CopyStyles=function(destDoc,sourceDoc) {var links=sourceDoc.getElementsByTagName('link');for(var i=0;i');} dp.sh.Utils.FixForBlogger=function(str) {return(dp.sh.isBloggerMode==true)?str.replace(/
|<br\s*\/?>/gi,'\n'):str;} dp.sh.RegexLib={MultiLineCComments:new RegExp('/\\*[\\s\\S]*?\\*/','gm'),SingleLineCComments:new RegExp('//.*$','gm'),SingleLinePerlComments:new RegExp('#.*$','gm'),DoubleQuotedString:new RegExp('"(?:\\.|(\\\\\\")|[^\\""\\n])*"','g'),SingleQuotedString:new RegExp("'(?:\\.|(\\\\\\')|[^\\''\\n])*'",'g')};dp.sh.Match=function(value,index,css) {this.value=value;this.index=index;this.length=value.length;this.css=css;} dp.sh.Highlighter=function() {this.noGutter=false;this.addControls=true;this.collapse=false;this.tabsToSpaces=true;this.wrapColumn=80;this.showColumns=true;} dp.sh.Highlighter.SortCallback=function(m1,m2) {if(m1.indexm2.index) return 1;else {if(m1.lengthm2.length) return 1;} return 0;} dp.sh.Highlighter.prototype.CreateElement=function(name) {var result=document.createElement(name);result.highlighter=this;return result;} dp.sh.Highlighter.prototype.GetMatches=function(regex,css) {var index=0;var match=null;while((match=regex.exec(this.code))!=null) this.matches[this.matches.length]=new dp.sh.Match(match[0],match.index,css);} dp.sh.Highlighter.prototype.AddBit=function(str,css) {if(str==null||str.length==0) return;var span=this.CreateElement('SPAN');str=str.replace(/ /g,' ');str=str.replace(/');if(css!=null) {if((/br/gi).test(str)) {var lines=str.split(' 
');for(var i=0;ic.index)&&(match.index/gi,'\n');var lines=html.split('\n');if(this.addControls==true) this.bar.appendChild(dp.sh.Toolbar.Create(this));if(this.showColumns) {var div=this.CreateElement('div');var columns=this.CreateElement('div');var showEvery=10;var i=1;while(i<=150) {if(i%showEvery==0) {div.innerHTML+=i;i+=(i+'').length;} else {div.innerHTML+='·';i++;}} columns.className='columns';columns.appendChild(div);this.bar.appendChild(columns);} for(var i=0,lineIndex=this.firstLine;i0;i++) {if(Trim(lines[i]).length==0) continue;var matches=regex.exec(lines[i]);if(matches!=null&&matches.length>0) min=Math.min(matches[0].length,min);} if(min>0) for(var i=0;i