Skip to content

Instantly share code, notes, and snippets.

@bielfrontera
Last active August 29, 2015 14:17
Show Gist options
  • Save bielfrontera/de36b1f510000ccbaf48 to your computer and use it in GitHub Desktop.
Save bielfrontera/de36b1f510000ccbaf48 to your computer and use it in GitHub Desktop.
boundingbox field for backbone-forms
;
(function(Form) {
/**
* BoundingBox editor
*
*/
Form.editors.BoundingBox = Form.editors.Base.extend({
events: {},
initialize: function(options) {
options = options || {};
Form.editors.Base.prototype.initialize.call(this, options);
var Self = Form.editors.BoundingBox;
//Option defaults
this.options = options;
//Schema defaults
this.schema = _.extend({
mapOptions: {
zoom: 2,
center: [0, 0],
minZoom: 2,
}
}, options.schema || {});
//Template
this.template = options.template || this.constructor.template;
},
render: function() {
var options = this.options,
schema = this.schema,
$ = Backbone.$;
//Render the selects
var $el = $($.trim(this.template({
className: this.className
})));
//Store references to inputs
this.$left = $el.find('[data-type="left"]');
this.$bottom = $el.find('[data-type="bottom"]');
this.$right = $el.find('[data-type="right"]');
this.$top = $el.find('[data-type="top"]');
this.$showMap = $el.find('[data-action="show-map"]');
this.mapVisible = false;
this.$showMap.click((function(ev) {
ev.preventDefault();
if (this.mapVisible) {
$el.find('.bbox-map').hide();
this.$showMap.html("<span class='glyphicon glyphicon-globe' aria-hidden='true'></span> Show map");
this.mapVisible = false;
} else {
$el.find('.bbox-map').show();
this.$showMap.html("<span class='glyphicon glyphicon-globe' aria-hidden='true'></span> Hide map");
this.mapVisible = true;
this.map.invalidateSize(false);
}
}).bind(this));
$el.find('[data-action="clear"]').click((function(ev) {
ev.preventDefault();
this.setValue(null);
}).bind(this));
// Create the map
var mapOptions = this.schema.mapOptions;
this.map = L.map($el.find('.bbox-map')[0], mapOptions);
if (L.control.pan)
L.control.pan({
panOffset: 100
}).addTo(this.map);
var Esri_OceanBasemap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri',
maxZoom: 13
}).addTo(this.map);
var drawnBBox = new L.FeatureGroup();
this.map.addLayer(drawnBBox);
this.drawRectangleHandler = new L.Draw.Rectangle(this.map, {
repeatMode: true
});
this.map.on('draw:created', (function(e) {
var b = e.layer.getBounds();
this.setValue(b.toBBoxString());
_.each(drawnBBox.getLayers(), function(layer) {
drawnBBox.removeLayer(layer);
});
e.layer.setStyle({
"color": "#12202f",
"weight": 2,
"opacity": 1,
"fillColor": '#fbd448',
"fillOpacity": 0.2
});
drawnBBox.addLayer(e.layer);
}).bind(this));
this.map.on('mouseover', (function(e) {
this.drawRectangleHandler.enable();
}).bind(this));
this.map.on('mouseout', (function(e) {
this.drawRectangleHandler.disable();
}).bind(this));
this.$hidden = $('<input type="hidden" name="' + this.key + '" />');
$el.append(this.$hidden);
//Remove the wrapper tag
this.setElement($el);
//Set value on this and hidden field
this.setValue(this.value);
this.$el.attr('id', this.id);
this.$el.attr('name', this.getName());
if (this.hasFocus) this.trigger('blur', this);
return this;
},
/**
* @return {BBoxString} Selected BBox
*/
getValue: function() {
if (this.$left && this.$bottom && this.$right && this.$top) {
var left = this.$left.val(),
bottom = this.$bottom.val(),
right = this.$right.val(),
top = this.$top.val();
if (!left || !bottom || !right || !top) {
this.value = null;
} else {
this.value = left.concat(",", bottom, ",", right, ",", top);
}
}
return this.value;
},
/**
* @param {BBoxString} bbox
*/
setValue: function(bbox) {
var splitBbox = "";
if (bbox) {
splitBbox = bbox.split(",");
}
if (splitBbox.length == 4) {
this.$left.val(parseFloat(splitBbox[0]).toFixed(4));
this.$bottom.val(parseFloat(splitBbox[1]).toFixed(4));
this.$right.val(parseFloat(splitBbox[2]).toFixed(4));
this.$top.val(parseFloat(splitBbox[3]).toFixed(4));
this.$el.find('[data-action="clear"]').show();
} else {
this.$left.val("");
this.$bottom.val("");
this.$right.val("");
this.$top.val("");
this.$el.find('[data-action="clear"]').hide();
}
this.updateHidden();
},
focus: function() {
if (this.hasFocus) return;
this.$left.focus();
},
blur: function() {
if (!this.hasFocus) return;
this.$left.blur();
},
/**
* Update the hidden input which is maintained for when submitting a form
* via a normal browser POST
*/
updateHidden: function() {
var val = this.getValue();
this.$hidden.val(val);
}
}, {
//STATICS
template: _.template('\
<div class="row">\
<div class="col-xs-2">\
<input data-type="left" class="<%= className %>" placeholder="min longitude" />\
</div>\
<div class="col-xs-2">\
<input data-type="bottom" class="<%= className %>" placeholder="min latitude" />\
</div>\
<div class="col-xs-2">\
<input data-type="right" class="<%= className %>" placeholder="max longitude" />\
</div>\
<div class="col-xs-2">\
<input data-type="top" class="<%= className %>" placeholder="max latitude" />\
</div>\
<div class="col-xs-4">\
<button type="button" class="btn btn-default" data-action="clear">\
<span class="glyphicon glyphicon-erase" aria-hidden="true"></span> Clear\
</button>\
<button type="button" class="btn btn-primary" data-action="show-map">\
<span class="glyphicon glyphicon-globe" aria-hidden="true"></span> Show map\
</button>\
</div>\
<div class="col-xs-12"><div class="bbox-map" style="display:none; width: 100%; height: 350px; margin-top: 30px;" ></div></div>\
</div>\
', null, Form.templateSettings),
});
})(Backbone.Form);
<link rel="stylesheet" href="/js/vendors/leaflet-0.7.3/leaflet.css" type="text/css" media="screen" />
<link rel="stylesheet" href="/js/vendors/leaflet-plugins/L.Control.Pan.css" type="text/css" media="screen" />
<link rel="stylesheet" href="/js/vendors/leaflet-plugins/leaflet.draw.css" type="text/css" media="screen" />
<link rel="stylesheet" href="/js/vendors/backbone/backbone-forms-bootstrap.css" type="text/css" media="screen" />
<script type="text/javascript" src="/js/vendors/leaflet-0.7.3/leaflet.js"></script>
<script type="text/javascript" src="/js/vendors/leaflet-plugins/L.Control.Pan.js"></script>
<script type="text/javascript" src="/js/vendors/leaflet-plugins/leaflet.draw.js"></script>
<script type="text/javascript" src="/js/vendors/underscore-min.js"></script>
<script type="text/javascript" src="/js/vendors/backbone/backbone-min.js"></script>
<script type="text/javascript" src="/js/vendors/backbone/backbone-forms.min.js}"></script>
<script type="text/javascript" src="/js/vendors/backbone/backbone-forms-editor-bbox.js"></script>
<script type="text/javascript" src="/js/vendors/backbone/backbone-forms-bootstrap.js"></script>
var filterForm = new Backbone.Form({
schema: {
bbox: {
type: 'BoundingBox',
title: 'Bounding box',
mapOptions: {
zoom: 5,
center: [39.4, 2.9],
minZoom: 2,
}
}
},
submitButton: '<span class="glyphicon glyphicon-filter" aria-hidden="true"></span> Filter',
}).render();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment