Skip to content

Instantly share code, notes, and snippets.

@leplatrem
Created December 13, 2012 12:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leplatrem/4276106 to your computer and use it in GitHub Desktop.
Save leplatrem/4276106 to your computer and use it in GitHub Desktop.
First (very first) try with Backbone and daybed
var MushroomSpot = Backbone.Model.extend({
defaults: function() {
return {
mushroom: "Unknown",
area: [0.0, 0.0]
};
},
initialize: function() {
if (!this.get("mushroom")) {
this.set({"mushroom": this.defaults.mushroom});
}
},
geometry: function () {
var area = JSON.parse(this.get('area'));
return L.circleMarker([area[1], area[0]], {fillColor: 'green'})
.bindPopup(this.get('mushroom'));
}
});
var MushroomSpotList = Backbone.Collection.extend({
url: '/daybed/data/mushroomspot',
model: MushroomSpot,
parse: function(response) {
return response.data;
},
});
var MushroomSpots = new MushroomSpotList;
var MushroomSpotRow = Backbone.View.extend({
tagName: "li",
template: Mustache.compile('{{ mushroom }}'),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var MushroomSpotCreate = Backbone.View.extend({
tagName: "div",
template: Mustache.compile('<form><input name="mushroom" type="text" placeholder="Mushroom"/><span id="map-help">Click on map</span><textarea name="area" style="display:none"></textarea><a href="#" id="clear">Cancel</a><button type="submit">Save</button></form>'),
templateError: Mustache.compile('<span class="field-error">{{ msg }}</span>'),
events: {
"submit form": "formSubmitted",
"click #clear": "formCancelled",
},
initialize: function (map) {
this.map = map;
this.marker = null;
},
render: function () {
this.$el.html(this.template({}));
this.delegateEvents();
this.map.on('click', this.onMapClick.bind(this));
return this;
},
close: function (e) {
if (this.marker) this.map.removeLayer(this.marker);
this.map.off('click');
this.remove();
return false;
},
formCancelled: function (e) {
e.preventDefault();
this.close();
return false;
},
formSubmitted: function(e) {
e.preventDefault();
this.$el.find('.field-error').remove();
var data = Backbone.Syphon.serialize(this);
MushroomSpots.create(data, {
wait: true,
error: this.showErrors.bind(this),
success: this.success.bind(this),
});
return false;
},
onMapClick: function (e) {
this.marker = L.marker(e.latlng).addTo(this.map);
this.$el.find('#map-help').remove();
var lnglat = [e.latlng.lng, e.latlng.lat];
this.$el.find('[name=area]').val(JSON.stringify(lnglat));
},
success: function (model, response, options) {
this.close();
},
showErrors: function (model, xhr, options) {
var descriptions = JSON.parse(xhr.responseText),
self = this;
$(descriptions.errors).each(function (i, e) {
self.$el.find("[name='" + e.name + "']")
.after(self.templateError({msg: e.description}));
});
},
});
var AppView = Backbone.View.extend({
el: $('#content').parent(),
statsTemplate: Mustache.compile('{{ count }} items.'),
events: {
"click #create": "createOne",
},
initialize: function () {
this.map = L.map('map').setView([0, 0], 3);
this.map.attributionControl.setPrefix('');
L.tileLayer('http://{s}.tiles.mapbox.com/v3/mapbox.mapbox-streets/{z}/{x}/{y}.png').addTo(this.map);
this.bounds = new L.LatLngBounds();
this.footer = $('#footer');
this.createView = new MushroomSpotCreate(this.map);
MushroomSpots.bind('add', this.addOne, this);
MushroomSpots.bind('reset', this.addAll, this);
MushroomSpots.bind('all', this.render, this);
MushroomSpots.fetch();
},
render: function () {
var count = MushroomSpots.length;
if (count > 0) {
this.map.fitBounds(this.bounds);
this.footer.show();
this.footer.html(this.statsTemplate({count: count}));
}
else {
this.footer.hide();
}
return this;
},
createOne: function(e) {
this.$("#content").prepend(this.createView.render().el);
},
addOne: function (spot) {
self = App; // WTF ?
var view = new MushroomSpotRow({model: spot});
this.$('#content').append(view.render().el);
var geom = spot.geometry();
geom.addTo(self.map);
self.bounds.extend(geom.getLatLng());
},
addAll: function () {
MushroomSpots.each(this.addOne);
}
});
<html>
<head>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/mustache.js/0.7.0/mustache.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/backbone.syphon/0.4.1/backbone.syphon.min.js"></script>
<link rel="stylesheet" href="http://leafletjs.com/dist/leaflet.css" />
<script src="http://leafletjs.com/dist/leaflet.js"></script>
<script src="app.js"></script>
<style>
#content {
width: 50%;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 50%;
right: 0;
}
</style>
<script type="text/javascript">
/*
curl -XPUT http://localhost:8000/definitions/mushroomspot -d '{"title":"mushroomspots","description":"mushroom spots", "fields": [{"name":"mushroom","type":"string","description":"what"},{"name":"area","type":"point","description":"where"}]}'
{"token": "9f0ca0d00ee48080f79bc2b6cbc2075ab7e678b0de4ce99a079f12296c6f777a41e412a88b7e04a6"}
*/
$(function(){
App = new AppView;
});
</script>
</head>
<body>
<div id="toolbar">
<button id="create">Create</button>
</div>
<div id="content"></div>
<div id="map"></div>
<div id="footer"></div>
</body>
</html>
import bottle
from wsgiproxy.app import WSGIProxyApp
DAYBED = "http://localhost:8000"
# Remove "hop-by-hop" headers (as defined by RFC2613, Section 13)
# since they are not allowed by the WSGI standard.
FILTER_HEADERS = [
'Connection',
'Keep-Alive',
'Proxy-Authenticate',
'Proxy-Authorization',
'TE',
'Trailers',
'Transfer-Encoding',
'Upgrade',
]
root = bottle.Bottle()
proxy_app = WSGIProxyApp(DAYBED)
def wrap_start_response(start_response):
def wrapped_start_response(status, headers_out):
# Remove "hop-by-hop" headers
headers_out = [(k,v) for (k,v) in headers_out
if k not in FILTER_HEADERS]
return start_response(status, headers_out)
return wrapped_start_response
def wrapped_proxy_app(environ, start_response):
start_response = wrap_start_response(start_response)
return proxy_app(environ, start_response)
root.mount(wrapped_proxy_app, "/daybed")
@root.route('/app/:resource')
def static(resource):
return bottle.static_file(resource, root='.')
bottle.debug(True)
bottle.run(app=root, host='localhost', port=8080)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment