Last active
February 2, 2017 14:10
-
-
Save ciscou/300d2375a4851b4946cfd70bd52afa8f to your computer and use it in GitHub Desktop.
Example of a minimal Backbone Marionette + Framework7 application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
<script src="https://code.jquery.com/jquery-2.2.4.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.radio/2.0.0/backbone.radio.js"></script> | |
<script src="http://marionettejs.com/downloads/backbone.marionette.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timeago/1.5.4/jquery.timeago.js"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/framework7/1.5.2/css/framework7.material.css"></link> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/framework7/1.5.2/css/framework7.material.colors.css"></link> | |
<style> | |
.fullscreen { | |
position: absolute; | |
top: 0; | |
left: 0; | |
bottom: 0; | |
right: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<script id="page-wrapper-template" type="text/template"> | |
<div></div> | |
</script> | |
<script id="main-view-template" type="text/template"> | |
<div class="navbar"> | |
<div class="navbar-inner"> | |
<div class="center">Recent changes</div> | |
</div> | |
</div> | |
<div class="toolbar toolbar-bottom"> | |
<div class="toolbar-inner"> | |
<a href="#" class="link" id="refresh" style="flex-grow: 1">Refresh</a> | |
</div> | |
</div> | |
<div class="page-content"> | |
<div class="content-block-title"> | |
Recent changes | |
</div> | |
<div class="content-block"> | |
<div class="list-block media-list"></div> | |
</div> | |
</div> | |
</script> | |
<script id="secondary-view-template" type="text/template"> | |
<div class="navbar"> | |
<div class="navbar-inner"> | |
<div class="left"><a href="#" class="back link icon-only"><i class="icon icon-back"></i></a></div> | |
<div class="center"><%- author.key %></div> | |
</div> | |
</div> | |
<div class="page-content"> | |
<div class="content-block-title"> | |
<time class="timeago" datetime="<%- timestamp %>Z"><%- timestamp %></time> | |
</div> | |
<div class="content-block"> | |
<p><%- comment %></p> | |
</div> | |
</div> | |
</script> | |
<script id="recent-change-empty-template" type="text/template"> | |
<a href="#" class="item-content item-link"> | |
<div class="item-media"> | |
</div> | |
<div class="item-inner"> | |
<div class="item-title-row"> | |
<div class="item-title"> | |
Loading... | |
</div> | |
</div> | |
<div class="item-subtitle"> | |
</div> | |
<div class="item-text"> | |
</div> | |
</div> | |
</a> | |
</script> | |
<script id="recent-change-template" type="text/template"> | |
<a href="#" class="item-content item-link"> | |
<div class="item-media"> | |
<img width="64" src="http://files.softicons.com/download/game-icons/super-mario-icons-by-sandro-pereira/png/256/Goomba.png"></img> | |
</div> | |
<div class="item-inner"> | |
<div class="item-title-row"> | |
<div class="item-title"> | |
<%- author.key %> | |
</div> | |
</div> | |
<div class="item-subtitle"> | |
<time class="timeago" datetime="<%- timestamp %>Z"><%- timestamp %></time> | |
</div> | |
<div class="item-text"> | |
<%- comment %> | |
</div> | |
</div> | |
</a> | |
</script> | |
<script id="indicator-template" type="text/template"> | |
<div class="preloader-indicator-overlay"></div> | |
<div class="preloader-indicator-modal"><span class="preloader preloader-white"><span class="preloader-inner"><span class="preloader-inner-gap"></span><span class="preloader-inner-left"><span class="preloader-inner-half-circle"></span></span><span class="preloader-inner-right"><span class="preloader-inner-half-circle"></span></span></span></span></div> | |
</script> | |
<script id="application-layout-template" type="text/template"> | |
<div class="views"> | |
<div class="view view-main"> | |
</div> | |
</div> | |
<div id="overlay-region"> | |
</div> | |
</script> | |
<div id="main-region" class="fullscreen"> | |
</div> | |
<script type="text/javascript"> | |
var App = Backbone.Marionette.Application.extend({ | |
models: {}, | |
collections: {}, | |
views: {}, | |
region: '#main-region', | |
showIndicator: function() { | |
app.layout.showIndicator(); | |
}, | |
hideIndicator: function() { | |
app.layout.hideIndicator(); | |
} | |
}); | |
var app = new App(); | |
app.models.Change = Backbone.Model.extend({}); | |
app.collections.RecentChanges = Backbone.Collection.extend({ | |
model: app.models.Change, | |
url: "http://openlibrary.org/recentchanges.json" | |
}); | |
app.views.ApplicationLayout = Backbone.Marionette.View.extend({ | |
template: '#application-layout-template', | |
className: 'fullscreen', | |
regions: { | |
mainView: '.view-main', | |
overlay: '#overlay-region' | |
}, | |
showIndicator: function() { | |
this.showChildView('overlay', new app.views.Indicator()); | |
}, | |
hideIndicator: function() { | |
this.getRegion('overlay').empty(); | |
}, | |
onRender: function() { | |
this.showChildView('mainView', this.getOption('mainView')); | |
} | |
}); | |
app.views.Indicator = Backbone.Marionette.View.extend({ | |
template: '#indicator-template' | |
}); | |
app.views.PageWrapper = Backbone.Marionette.View.extend({ | |
template: '#page-wrapper-template', | |
regions: { | |
page: { | |
el: 'div', | |
replaceElement: true | |
} | |
}, | |
onRender: function() { | |
var view = this.model.get('view'); | |
this.showChildView('page', view); | |
} | |
}); | |
app.views.Pages = Backbone.Marionette.CollectionView.extend({ | |
className: 'pages', | |
childView: app.views.PageWrapper, | |
push: function(model) { | |
this.collection.push(model); | |
var $a = this._getPageAt(-2); | |
var $b = this._getPageAt(-1); | |
if($a) { | |
$a.one('animationend', function() { | |
$a.removeClass('page-from-center-to-left').addClass('page-on-left'); | |
}); | |
$a.removeClass('page-on-center').addClass('page-from-center-to-left'); | |
$b.one('animationend', function() { | |
$b.removeClass('page-from-right-to-center').addClass('page-on-center'); | |
}); | |
$b.removeClass('page-on-right').addClass('page-from-right-to-center'); | |
} | |
}, | |
pop: function() { | |
var $a = this._getPageAt(-2); | |
var $b = this._getPageAt(-1); | |
var collection = this.collection; | |
$a.one('animationend', function() { | |
$a.removeClass('page-from-left-to-center').addClass('page-on-center'); | |
}); | |
$a.removeClass('page-on-left').addClass('page-from-left-to-center'); | |
$b.one('animationend', function() { | |
$b.removeClass('page-from-center-to-right').addClass('page-on-right'); | |
collection.pop(); | |
}); | |
$b.removeClass('page-on-center').addClass('page-from-center-to-right'); | |
}, | |
_getPageAt: function(idx) { | |
if(idx < 0) { | |
idx += this.children.length; | |
} | |
view = this.children.findByIndex(idx); | |
if(view) { | |
return view.$el.find('.page'); | |
} | |
} | |
}); | |
app.views.RecentChange = Backbone.Marionette.View.extend({ | |
template: "#recent-change-template", | |
tagName: "li", | |
ui: { | |
timeago: 'time.timeago' | |
}, | |
triggers: { | |
click: 'clicked' | |
}, | |
onDomRefresh: function() { | |
this.getUI('timeago').timeago(); | |
} | |
}); | |
app.views.RecentChangeEmpty = Backbone.Marionette.View.extend({ | |
template: "#recent-change-empty-template", | |
tagName: "li" | |
}); | |
app.views.RecentChanges = Backbone.Marionette.CollectionView.extend({ | |
tagName: "ul", | |
className: "list-block media-list", | |
childView: app.views.RecentChange, | |
emptyView: app.views.RecentChangeEmpty | |
}); | |
app.views.MainPage = Backbone.Marionette.View.extend({ | |
template: "#main-view-template", | |
className: 'page navbar-fixed toolbar-fixed', | |
data: { | |
page: "index" | |
}, | |
ui: { | |
refresh: 'a#refresh' | |
}, | |
triggers: { | |
'click @ui.refresh': 'refresh' | |
}, | |
regions: { | |
list: '.media-list' | |
}, | |
collectionEvents: { | |
request: 'onCollectionRequest', | |
sync: 'onCollectionSync' | |
}, | |
onRender: function() { | |
this.showChildView( | |
'list', | |
new app.views.RecentChanges({ | |
collection: this.collection | |
}) | |
); | |
}, | |
onCollectionRequest: function() { | |
app.showIndicator(); | |
this.getUI('refresh').addClass('disabled'); | |
}, | |
onCollectionSync: function() { | |
app.hideIndicator(); | |
this.getUI('refresh').removeClass('disabled'); | |
} | |
}); | |
app.views.SecondaryPage = Backbone.Marionette.View.extend({ | |
template: "#secondary-view-template", | |
className: 'page navbar-fixed', | |
data: { | |
page: "secondary" | |
}, | |
ui: { | |
back: 'a.back', | |
timeago: 'time.timeago' | |
}, | |
triggers: { | |
'click @ui.back': 'back' | |
}, | |
onDomRefresh: function() { | |
this.getUI('timeago').timeago(); | |
} | |
}); | |
var recentChanges = new app.collections.RecentChanges(); | |
var mainPage = new app.views.MainPage({ | |
collection: recentChanges | |
}); | |
app.pages = new app.views.Pages({ | |
collection: new Backbone.Collection() | |
}); | |
mainPage.on('refresh', function() { | |
recentChanges.fetch({data: {limit: 10}}); | |
}); | |
mainPage.on('childview:clicked', function(v) { | |
var secondaryView = new app.views.SecondaryPage({model: v.model}); | |
app.pages.push({view: secondaryView}); | |
secondaryView.on('back', function() { | |
app.pages.pop(); | |
}); | |
}); | |
app.on('start', function() { | |
app.layout = new app.views.ApplicationLayout({mainView: app.pages}); | |
app.showView(app.layout); | |
app.pages.push({view: mainPage}); | |
recentChanges.fetch({data: {limit: 10}}); | |
}); | |
$(function() { | |
app.start(); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment