Browse files

Rewrite the program.html code using backbone for fun and profit.

The best way to understand code it to rewrite it. Done.

Signed-off-by: François de Metz <francois@stormz.me>
  • Loading branch information...
1 parent 665cdac commit 74e5825a028fa97bdad061284e2c983fd3b48806 @francois2metz francois2metz committed Mar 22, 2012
Showing with 249 additions and 165 deletions.
  1. +2 −3 css/program.css
  2. +38 −0 js/backbone-min.js
  3. +183 −147 js/google_spreadsheet.js
  4. +26 −15 program.html
View
5 css/program.css
@@ -52,10 +52,9 @@ a.add_prez {
-webkit-box-shadow: 0px 1px 2px rgba(255, 255, 255, 0.7) inset,0px 1px 3px rgba(0, 0, 0, 0.5);
box-shadow: 0px 1px 2px rgba(255, 255, 255, 0.7) inset,0px 1px 3px rgba(0, 0, 0, 0.5);
float: left;
- visibility: hidden;
}
-a.add_prez:hover{
+a.add_prez:hover {
color:#497e6c;
cursor:pointer;
text-shadow: 1px 1px 0px rgba(255,255,255,0.4);
@@ -159,4 +158,4 @@ section.abstract:before {
#spin {
margin-top: 200px;
margin-left: -100px;
-}
+}
View
38 js/backbone-min.js
@@ -0,0 +1,38 @@
+// Backbone.js 0.9.2
+
+// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Backbone may be freely distributed under the MIT license.
+// For all details and documentation:
+// http://backbonejs.org
+(function(){var l=this,y=l.Backbone,z=Array.prototype.slice,A=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:l.Backbone={};g.VERSION="0.9.2";var f=l._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var i=l.jQuery||l.Zepto||l.ender;g.setDomLibrary=function(a){i=a};g.noConflict=function(){l.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,k=g.Events={on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks=
+{});e=a.shift();)f=(j=d[e])?j.tail:{},f.next=g={},f.context=c,f.callback=b,d[e]={tail:g,next:j?j.next:f};return this},off:function(a,b,c){var d,e,h,g,j,q;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(h=e[d],delete e[d],h&&(b||c))for(g=h.tail;(h=h.next)!==g;)if(j=h.callback,q=h.context,b&&j!==b||c&&q!==c)this.on(d,j,q);return this}},trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(p);for(g=
+z.call(arguments,1);b=a.shift();){if(c=d[b])for(e=c.tail;(c=c.next)!==e;)c.callback.apply(c.context||this,g);if(c=f){e=c.tail;for(b=[b].concat(g);(c=c.next)!==e;)c.callback.apply(c.context||this,b)}}return this}};k.bind=k.on;k.unbind=k.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=n(this,"defaults"))a=f.extend({},c,a);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent=
+{};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,k,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(null==
+b?"":""+b)},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},h=this.attributes,g=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(h[e],a)||c.unset&&f.has(h,e))delete g[e],(c.silent?this._silent:
+b)[e]=!0;c.unset?delete h[e]:h[e]=a;!f.isEqual(j[e],a)||f.has(h,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d)};
+a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var h=this,i=c.success;c.success=function(a,b,e){b=h.parse(a,e);if(c.wait){delete c.wait;b=f.extend(d||{},b)}if(!h.set(b,c))return false;i?i(h,a):h.trigger("sync",h,a,c)};c.error=g.wrapError(c.error,
+h,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d(),!1;a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=n(this,"urlRoot")||n(this.collection,"url")||t();
+return this.isNew()?a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;var d=f.extend({},a.changes,this._silent);this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending=
+{};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=!1;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length||
+!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var r=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);b.comparator&&(this.comparator=b.comparator);
+this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(r.prototype,k,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},add:function(a,b){var c,d,e,g,i,j={},k={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c<d;c++){if(!(e=a[c]=this._prepareModel(a[c],b)))throw Error("Can't add an invalid model to a collection");g=e.cid;i=e.id;j[g]||this._byCid[g]||null!=i&&(k[i]||this._byId[i])?
+l.push(c):j[g]=k[i]=e}for(c=l.length;c--;)a.splice(l[c],1);c=0;for(d=a.length;c<d;c++)(e=a[c]).on("all",this._onModelEvent,this),this._byCid[e.cid]=e,null!=e.id&&(this._byId[e.id]=e);this.length+=d;A.apply(this.models,[null!=b.at?b.at:this.models.length,0].concat(a));this.comparator&&this.sort({silent:!0});if(b.silent)return this;c=0;for(d=this.models.length;c<d;c++)if(j[(e=this.models[c]).cid])b.index=c,e.trigger("add",e,this,b);return this},remove:function(a,b){var c,d,e,g;b||(b={});a=f.isArray(a)?
+a.slice():[a];c=0;for(d=a.length;c<d;c++)if(g=this.getByCid(a[c])||this.get(a[c]))delete this._byId[g.id],delete this._byCid[g.cid],e=this.indexOf(g),this.models.splice(e,1),this.length--,b.silent||(b.index=e,g.trigger("remove",g,this,b)),this._removeReference(g);return this},push:function(a,b){a=this._prepareModel(a,b);this.add(a,b);return a},pop:function(a){var b=this.at(this.length-1);this.remove(b,a);return b},unshift:function(a,b){a=this._prepareModel(a,b);this.add(a,f.extend({at:0},b));return a},
+shift:function(a){var b=this.at(0);this.remove(b,a);return b},get:function(a){return null==a?void 0:this._byId[null!=a.id?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},where:function(a){return f.isEmpty(a)?[]:this.filter(function(b){for(var c in a)if(a[c]!==b.get(c))return!1;return!0})},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");var b=f.bind(this.comparator,this);1==this.comparator.length?
+this.models=this.sortBy(b):this.models.sort(b);a.silent||this.trigger("reset",this,a);return this},pluck:function(a){return f.map(this.models,function(b){return b.get(a)})},reset:function(a,b){a||(a=[]);b||(b={});for(var c=0,d=this.models.length;c<d;c++)this._removeReference(this.models[c]);this._reset();this.add(a,f.extend({silent:!0},b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?f.clone(a):{};void 0===a.parse&&(a.parse=!0);var b=this,c=a.success;a.success=function(d,
+e,f){b[a.add?"add":"reset"](b.parse(d,f),a);c&&c(b,d)};a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},create:function(a,b){var c=this,b=b?f.clone(b):{},a=this._prepareModel(a,b);if(!a)return!1;b.wait||c.add(a,b);var d=b.success;b.success=function(e,f){b.wait&&c.add(e,b);d?d(e,f):e.trigger("sync",a,f,b)};a.save(null,b);return a},parse:function(a){return a},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId=
+{};this._byCid={}},_prepareModel:function(a,b){b||(b={});a instanceof o?a.collection||(a.collection=this):(b.collection=this,a=new this.model(a,b),a._validate(a.attributes,b)||(a=!1));return a},_removeReference:function(a){this==a.collection&&delete a.collection;a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,b,c,d){("add"==a||"remove"==a)&&c!=this||("destroy"==a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],this._byId[b.id]=b),this.trigger.apply(this,
+arguments))}});f.each("forEach,each,map,reduce,reduceRight,find,detect,filter,select,reject,every,all,some,any,include,contains,invoke,max,min,sortBy,sortedIndex,toArray,size,first,initial,rest,last,without,indexOf,shuffle,lastIndexOf,isEmpty,groupBy".split(","),function(a){r.prototype[a]=function(){return f[a].apply(f,[this.models].concat(f.toArray(arguments)))}});var u=g.Router=function(a){a||(a={});a.routes&&(this.routes=a.routes);this._bindRoutes();this.initialize.apply(this,arguments)},B=/:\w+/g,
+C=/\*\w+/g,D=/[-[\]{}()+?.,\\^$|#\s]/g;f.extend(u.prototype,k,{initialize:function(){},route:function(a,b,c){g.history||(g.history=new m);f.isRegExp(a)||(a=this._routeToRegExp(a));c||(c=this[b]);g.history.route(a,f.bind(function(d){d=this._extractParameters(a,d);c&&c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d));g.history.trigger("route",this,b,d)},this));return this},navigate:function(a,b){g.history.navigate(a,b)},_bindRoutes:function(){if(this.routes){var a=[],b;for(b in this.routes)a.unshift([b,
+this.routes[b]]);b=0;for(var c=a.length;b<c;b++)this.route(a[b][0],a[b][1],this[a[b][1]])}},_routeToRegExp:function(a){a=a.replace(D,"\\$&").replace(B,"([^/]+)").replace(C,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});var m=g.History=function(){this.handlers=[];f.bindAll(this,"checkUrl")},s=/^[#\/]/,E=/msie [\w.]+/;m.started=!1;f.extend(m.prototype,k,{interval:50,getHash:function(a){return(a=(a?a.location:window.location).href.match(/#(.*)$/))?a[1]:
+""},getFragment:function(a,b){if(null==a)if(this._hasPushState||b){var a=window.location.pathname,c=window.location.search;c&&(a+=c)}else a=this.getHash();a.indexOf(this.options.root)||(a=a.substr(this.options.root.length));return a.replace(s,"")},start:function(a){if(m.started)throw Error("Backbone.history has already been started");m.started=!0;this.options=f.extend({},{root:"/"},this.options,a);this._wantsHashChange=!1!==this.options.hashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=
+!(!this.options.pushState||!window.history||!window.history.pushState);var a=this.getFragment(),b=document.documentMode;if(b=E.exec(navigator.userAgent.toLowerCase())&&(!b||7>=b))this.iframe=i('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a);this._hasPushState?i(window).bind("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!b?i(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,
+this.interval));this.fragment=a;a=window.location;b=a.pathname==this.options.root;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),window.location.replace(this.options.root+"#"+this.fragment),!0;this._wantsPushState&&this._hasPushState&&b&&a.hash&&(this.fragment=this.getHash().replace(s,""),window.history.replaceState({},document.title,a.protocol+"//"+a.host+this.options.root+this.fragment));if(!this.options.silent)return this.loadUrl()},
+stop:function(){i(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);m.started=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a==this.fragment&&this.iframe&&(a=this.getFragment(this.getHash(this.iframe)));if(a==this.fragment)return!1;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(this.getHash())},loadUrl:function(a){var b=this.fragment=this.getFragment(a);return f.any(this.handlers,
+function(a){if(a.route.test(b))return a.callback(b),!0})},navigate:function(a,b){if(!m.started)return!1;if(!b||!0===b)b={trigger:b};var c=(a||"").replace(s,"");this.fragment!=c&&(this._hasPushState?(0!=c.indexOf(this.options.root)&&(c=this.options.root+c),this.fragment=c,window.history[b.replace?"replaceState":"pushState"]({},document.title,c)):this._wantsHashChange?(this.fragment=c,this._updateHash(window.location,c,b.replace),this.iframe&&c!=this.getFragment(this.getHash(this.iframe))&&(b.replace||
+this.iframe.document.open().close(),this._updateHash(this.iframe.location,c,b.replace))):window.location.assign(this.options.root+a),b.trigger&&this.loadUrl(a))},_updateHash:function(a,b,c){c?a.replace(a.toString().replace(/(javascript:|#).*$/,"")+"#"+b):a.hash=b}});var v=g.View=function(a){this.cid=f.uniqueId("view");this._configure(a||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()},F=/^(\S+)\s*(.*)$/,w="model,collection,el,id,attributes,className,tagName".split(",");
+f.extend(v.prototype,k,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();return this},make:function(a,b,c){a=document.createElement(a);b&&i(a).attr(b);c&&i(a).html(c);return a},setElement:function(a,b){this.$el&&this.undelegateEvents();this.$el=a instanceof i?a:i(a);this.el=this.$el[0];!1!==b&&this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=n(this,"events"))){this.undelegateEvents();
+for(var b in a){var c=a[b];f.isFunction(c)||(c=this[a[b]]);if(!c)throw Error('Method "'+a[b]+'" does not exist');var d=b.match(F),e=d[1],d=d[2],c=f.bind(c,this),e=e+(".delegateEvents"+this.cid);""===d?this.$el.bind(e,c):this.$el.delegate(d,e,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(a){this.options&&(a=f.extend({},this.options,a));for(var b=0,c=w.length;b<c;b++){var d=w[b];a[d]&&(this[d]=a[d])}this.options=a},_ensureElement:function(){if(this.el)this.setElement(this.el,
+!1);else{var a=n(this,"attributes")||{};this.id&&(a.id=this.id);this.className&&(a["class"]=this.className);this.setElement(this.make(this.tagName,a),!1)}}});o.extend=r.extend=u.extend=v.extend=function(a,b){var c=G(this,a,b);c.extend=this.extend;return c};var H={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=H[a];c||(c={});var e={type:d,dataType:"json"};c.url||(e.url=n(b,"url")||t());if(!c.data&&b&&("create"==a||"update"==a))e.contentType="application/json",
+e.data=JSON.stringify(b.toJSON());g.emulateJSON&&(e.contentType="application/x-www-form-urlencoded",e.data=e.data?{model:e.data}:{});if(g.emulateHTTP&&("PUT"===d||"DELETE"===d))g.emulateJSON&&(e.data._method=d),e.type="POST",e.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d)};"GET"!==e.type&&!g.emulateJSON&&(e.processData=!1);return i.ajax(f.extend(e,c))};g.wrapError=function(a,b,c){return function(d,e){e=d===b?e:d;a?a(b,e,c):b.trigger("error",b,e,c)}};var x=function(){},G=function(a,
+b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){a.apply(this,arguments)};f.extend(d,a);x.prototype=a.prototype;d.prototype=new x;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},n=function(a,b){return!a||!a[b]?null:f.isFunction(a[b])?a[b]():a[b]},t=function(){throw Error('A "url" property or function must be specified');}}).call(this);
View
330 js/google_spreadsheet.js
@@ -1,7 +1,6 @@
var Spin = {};
-Spin.init = function (target)
-{
+Spin.init = function(target) {
var opts = {
lines: 16,
length: 9,
@@ -16,171 +15,208 @@ Spin.init = function (target)
this.spinner = new Spinner(opts).spin(target);
};
-Spin.stop = function ()
-{
+Spin.stop = function() {
this.spinner.stop();
};
- onload="Spin.init (document.getElementById ('spin'));"
-/****************************************************************
- * Data and Parse
- ****************************************************************/
+
/**
- *
+ * Backbone App
*/
-function Talk (title, authors, contacts, type, abstract, state)
-{
- this.title = title;
- this.authors = authors;
- this.contacts = contacts;
- this.type = type;
- this.abstract = abstract;
- this.state = state;
-}
-
-Talk.TEMPLATE = "<article class=\"prez\"><header><h1>{title}</h1></header><section class=\"authors\"><span>{authors}</span><span>{contacts}</span></section><section class=\"abstract\"><p>{abstract}</p></section></article>";
-
-Talk.TYPE_NORMAL = 1;
-Talk.TYPE_SHORT = 2;
-
-Talk.STATE_ACCEPTED = 'Accepte';
-Talk.STATE_NEXT = 'Prochain';
-Talk.STATE_NEXT_NEXT = 'Suivant';
-
-Talk.prototype.generateView = function ()
-{
- var str = Talk.TEMPLATE;
- for (var key in this)
- {
- text = this [key];
- if (text.replace) text = text.replace (/\n/g, '<br/>');
- str = str.replace ('{' + key + '}',text);
- }
-
- var div = document.createElement (div);
- div.innerHTML = str;
- div = div.firstElementChild;
-
- if (this.type === Talk.TYPE_SHORT) div.className = "prez lightning";
- return div;
-}
-
-Talk.hasAcceptedTalk = false;
+var App = {
+ models: {},
+ views: {},
+ collections: {}
+};
/**
- *
+ * Tall model
*/
-function parseRow (row)
-{
- var title = (row[1])?row[1].v:"";
- var authors = (row[2])?row[2].v:"";
- var contacts = (row[3])?row[3].v:"";
- var type =
- (row[4] && row[4].v.indexOf ("Lightning") === 0)?Talk.TYPE_SHORT:Talk.TYPE_NORMAL;
- var abstract = (row[5])?row[5].v:"";
- var state = (row[7])?row[7].v:Talk.STATE_NEXT_NEXT;
-
- if (state == Talk.STATE_ACCEPTED) Talk.hasAcceptedTalk = true;
-
- return new Talk (title, authors, contacts, type, abstract, state);
-}
+App.models.Talk = Backbone.Model.extend({
+ // normal talk (10-20 min)
+ TYPE_NORMAL : 1,
+ // lightning talk
+ TYPE_SHORT : 2,
+
+ // accepted scheduled for the next parisjs
+ STATE_ACCEPTED : 'Accepte',
+ // can be scheduled on the next parisjs by not yet accepted
+ STATE_NEXT : 'Prochain',
+ // cannot be scheduled on the next parisjs
+ STATE_NEXT_NEXT : 'Suivant',
+
+ defaults: {
+ title: '',
+ authors: '',
+ contacts: '',
+ type: '',
+ abstract: '',
+ state: ''
+ },
+
+ /**
+ * Parse the json returned by the spreadsheet
+ */
+ parse: function(response) {
+ var row = response.c;
+ var title = (row[1]) ?row[1].v : "";
+ var authors = (row[2]) ? row[2].v : "";
+ var contacts = (row[3]) ? row[3].v : "";
+ var type = (row[4] && row[4].v.indexOf("Lightning") === 0) ? this.TYPE_SHORT : this.TYPE_NORMAL;
+ var abstract = (row[5]) ? row[5].v: "";
+ var state = (row[7]) ? row[7].v : this.STATE_NEXT_NEXT;
+ return {
+ title: title,
+ authors: authors,
+ contacts: contacts,
+ type: type,
+ abstract: abstract,
+ state: state
+ };
+ }
+});
/**
- *
+ * Collection of talks
*/
-function parseDataTable (dataTable)
-{
- var talks = [];
-
- // oui c un peu con mais au moins c plus simple a parser
- var data = JSON.parse (dataTable.toJSON ());
-
- for (var i = 0; i < data.rows.length; i++)
- {
- talks.push (parseRow (data.rows [i].c));
- }
- return talks;
-}
-
-/****************************************************************
- * Gui generation
- ****************************************************************/
+App.collections.Talks = Backbone.Collection.extend({
+ model: App.models.Talk,
+
+ /**
+ * Return only accepted prezs
+ */
+ accepted: function() {
+ return this.where({state: App.models.Talk.prototype.STATE_ACCEPTED});
+ },
+
+ /**
+ * Return all non-accepted prezs
+ */
+ submitted: function() {
+ return this.filter(function(talk) {
+ return talk.get('state') != App.models.Talk.prototype.STATE_ACCEPTED;
+ });
+ },
+
+ /**
+ * Parse the json returned by the spreadsheet
+ */
+ parse: function(response) {
+ // the easiest way :(
+ var data = JSON.parse(response.toJSON());
+ return data.rows;
+ },
+
+ /**
+ * Custom sync for google spreadsheets
+ */
+ sync: function(method, model, options) {
+ if (method != "read") throw new Error("not (yet) supported");
+ var query = new google.visualization.Query('http://spreadsheets.google.com/tq?key=0AnLhUwtBNx3zdDNDbU93eUh1NXpCenNXT1FqQksxZmc&pub=1');
+ query.send(function(response) {
+ if (response.isError()) options.error(response);
+ else options.success(response.getDataTable());
+ });
+ }
+});
/**
- *
+ * Render a talk
*/
-function generateGUI (className, talks, state)
-{
- var div_normal = document.querySelector (className + ' .normal');
- var div_lightning = document.querySelector (className + ' .lightning');
-
- for (var i = 0; i < talks.length; i++)
- {
- var talk = talks[i];
- if (talk.state != state) continue;
-
- article = talk.generateView ();
-
- if (talk.type === Talk.TYPE_SHORT) div_lightning.appendChild (article);
- else div_normal.appendChild (article);
- }
-}
-
-/****************************************************************
- * Google Stuff
- ****************************************************************/
-
+App.views.Talk = Backbone.View.extend({
+ tagName: 'article',
+ className: 'prez',
+
+ render: function() {
+ var template = _.template($('#talk-template').html());
+ var data = this.model.toJSON();
+ data.abstract = data.abstract.replace(/\n/g, '<br/>');
+ this.$el.append(template(data));
+
+ if (this.model.get('type') === this.TYPE_SHORT)
+ this.$el.addClass("lightning");
+
+ return this;
+ }
+});
/**
- *
+ * Render a collection of talks
*/
-function _google_on_laoded ()
-{
- google.load("visualization", "1");
- google.setOnLoadCallback (requestData);
-}
+App.views.Talks = Backbone.View.extend({
+ initialize: function() {
+ this.collection.bind('reset', this.render, this);
+ },
+
+ render: function() {
+ this.collection.each(_.bind(this.renderTalk, this));
+ return this;
+ },
+
+ renderTalk: function(talkModel) {
+ var talkView = new App.views.Talk({model: talkModel}).render();
+ this.$el.append(talkView.el);
+ }
+});
/**
- *
+ * The basic router of the page
*/
-function queryResult (response)
-{
- Spin.stop ();
- document.getElementById ("spin").style.display = "none";
- document.getElementById ("content").style.visibility = "visible";
-
- if (response.isError ())
- {
- alert ('Error in query: ' + response.getMessage() + ' ' +
- response.getDetailedMessage());
- return;
- }
- var data = response.getDataTable ();
- var talks = parseDataTable (data);
-
- // Un programme est dispo
- if (Talk.hasAcceptedTalk)
- {
- generateGUI (".prez", talks, Talk.STATE_ACCEPTED);
- document.querySelector (".prez.prochain").style.visibility = "hidden";
- document.querySelector (".prez.avenir").style.visibility = "hidden";
- }
- // Pas de programme dispo, on affiche les propositions
- else
- {
- document.querySelector ("a.add_prez").style.visibility = "visible";
- document.querySelector (".prez").innerHTML = "<h2>Programme du prochain ParisJS en cours de finalisation...<h2>";
-
- generateGUI (".prez.prochain", talks, Talk.STATE_NEXT);
- generateGUI (".prez.avenir", talks, Talk.STATE_NEXT_NEXT);
- }
-}
+App.Program = Backbone.Router.extend({
+
+ routes: {
+ "": "index",
+ "submitted": "submitted"
+ },
+
+ initialize: function() {
+ Spin.init($('#spin').get(0));
+ this.talks = new App.collections.Talks();
+ this.talksAccepted = new App.collections.Talks();
+ this.talksSubmitted = new App.collections.Talks();
+ this.talks.on('reset', this.onReset, this);
+ this.talks.fetch();
+ },
+
+ onReset: function() {
+ $("#spin").hide();
+ Spin.stop();
+ var accepted = this.talks.accepted();
+ if (accepted.length > 0) {
+ this.talksAccepted.reset(accepted);
+ } else {
+ // show only submitted talks
+ this.submitted();
+ $('.switch').hide();
+ }
+ var submitted = this.talks.submitted();
+ if (submitted.length > 0) {
+ this.talksSubmitted.reset(submitted);
+ }
+ new App.views.Talks({collection: this.talksAccepted,
+ el: $('#prezs-scheduled .prezs').get(0)}).render();
+
+ new App.views.Talks({collection: this.talksSubmitted,
+ el: $('#prezs-submitted .prezs').get(0)}).render();
+ },
+
+ index: function() {
+ $('#prezs-scheduled').show();
+ $('#prezs-submitted').hide();
+ },
+
+ submitted: function() {
+ $('#prezs-scheduled').hide();
+ $('#prezs-submitted').show();
+ }
+});
/**
- *
+ * Callback when the google jsapi is loaded
*/
-function requestData ()
-{
- var query = new google.visualization.Query ( 'http://spreadsheets.google.com/tq?key=0AnLhUwtBNx3zdDNDbU93eUh1NXpCenNXT1FqQksxZmc&pub=1');
-
- query.send (queryResult)
+function _google_on_loaded() {
+ google.load("visualization", "1");
+ google.setOnLoadCallback(function() {
+ new App.Program();
+ Backbone.history.start();
+ });
}
View
41 program.html
@@ -13,7 +13,7 @@
<header>
<div class="container">
<div id="logo">
- <a href="http://parisjs.org">
+ <a href="/">
<img src="images/logo.png" alt="ParisJS.org - Home">
</a>
</div>
@@ -28,29 +28,27 @@
</div>
<section class="container">
<div id="spin"></div>
- <div id="content" style="visibility:hidden">
- <div class="prez">
- <div class="normal"></div>
- <div class="lightning"></div>
+ <div id="content">
+ <div class="switch">
+ <a class="" href="#">Programme du prochain Paris.js</a>
+ <a class="" href="#submitted">Présentations soumises</a>
</div>
- <div class="prez prochain">
- <h1>Propositions pour le prochain Paris JS</h1>
- <div class="normal"></div>
- <div class="lightning"></div>
+ <div id="prezs-scheduled">
+ <div class="prezs"></div>
</div>
- <div class="prez avenir">
- <h1>Propositions pour Paris JS à venir</h1>
- <div class="normal"></div>
- <div class="lightning"></div>
+ <div id="prezs-submitted" style="display:none;">
+ <h1>Propositions soumises pour les prochains Paris.js</h1>
+ <div class="prezs"></div>
</div>
</div>
</section>
- <script src="http://www.google.com/jsapi?key=ABQIAAAAE4BGaIh0t-7l9PDR7PA0rRR6KW34AlT62yZeC298tyhOjAL-9hQQpk22pW6ZfaCFEr3zjz2Q8rjqAw&callback=_google_on_laoded" type="text/javascript"></script>
-
<script type="text/javascript" src="js/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="js/spin.js"></script>
+ <script type="text/javascript" src="js/underscore-min.js"></script>
+ <script type="text/javascript" src="js/backbone-min.js"></script>
<script type="text/javascript" src="js/google_spreadsheet.js"></script>
+ <script src="http://www.google.com/jsapi?key=ABQIAAAAE4BGaIh0t-7l9PDR7PA0rRR6KW34AlT62yZeC298tyhOjAL-9hQQpk22pW6ZfaCFEr3zjz2Q8rjqAw&callback=_google_on_loaded" type="text/javascript"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-23072906-1']);
@@ -63,5 +61,18 @@
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
+
+ <script id="talk-template" type="text/x-template">
+ <header>
+ <h1><%= title %></h1>
+ </header>
+ <section class="authors">
+ <span><%= authors %></span>
+ <span><%= contacts %></span>
+ </section>
+ <section class="abstract">
+ <p><%= abstract %></p>
+ </section>
+ </script>
</body>
</html>

0 comments on commit 74e5825

Please sign in to comment.