[#64,view/map] Add small editor for user input
Right now the form lets you define the fields where the geometries are stored (either in a single GeoJSON field or a pair of lat/lon fields). When adding features, if wrong geometries are found (ie wrong field values), the process will stop and an error notice will be shown.
This commit is contained in:
parent
e65b3f5418
commit
a8018c4e18
19
css/map.css
19
css/map.css
@ -2,3 +2,22 @@
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
* Editor
|
||||
*********************************************************/
|
||||
|
||||
.data-map-container .editor {
|
||||
float: right;
|
||||
width: 200px;
|
||||
padding-left: 0px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.data-map-container .editor form {
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.data-map-container .editor select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
132
src/view-map.js
132
src/view-map.js
@ -27,10 +27,66 @@ my.Map = Backbone.View.extend({
|
||||
*/
|
||||
|
||||
template: ' \
|
||||
<div class="editor"> \
|
||||
<form class="form-stacked"> \
|
||||
<div class="clearfix"> \
|
||||
<div class="editor-field-type"> \
|
||||
<label class="radio"> \
|
||||
<input type="radio" id="editor-field-type-latlon" name="editor-field-type" value="latlon" checked="checked"/> \
|
||||
Latitude / Longitude fields</label> \
|
||||
<label class="radio"> \
|
||||
<input type="radio" id="editor-field-type-geom" name="editor-field-type" value="geom" /> \
|
||||
GeoJSON field</label> \
|
||||
</div> \
|
||||
<div class="editor-field-type-latlon"> \
|
||||
<label>Latitude field</label> \
|
||||
<div class="input editor-lat-field"> \
|
||||
<select> \
|
||||
<option value=""></option> \
|
||||
{{#fields}} \
|
||||
<option value="{{id}}">{{label}}</option> \
|
||||
{{/fields}} \
|
||||
</select> \
|
||||
</div> \
|
||||
<label>Longitude field</label> \
|
||||
<div class="input editor-lon-field"> \
|
||||
<select> \
|
||||
<option value=""></option> \
|
||||
{{#fields}} \
|
||||
<option value="{{id}}">{{label}}</option> \
|
||||
{{/fields}} \
|
||||
</select> \
|
||||
</div> \
|
||||
</div> \
|
||||
<div class="editor-field-type-geom" style="display:none"> \
|
||||
<label>Geometry field (GeoJSON)</label> \
|
||||
<div class="input editor-geom-field"> \
|
||||
<select> \
|
||||
<option value=""></option> \
|
||||
{{#fields}} \
|
||||
<option value="{{id}}">{{label}}</option> \
|
||||
{{/fields}} \
|
||||
</select> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
<div class="editor-buttons"> \
|
||||
<button class="btn editor-update-map">Update</button> \
|
||||
</div> \
|
||||
<input type="hidden" class="editor-id" value="map-1" /> \
|
||||
</div> \
|
||||
</form> \
|
||||
</div> \
|
||||
<div class="panel map"> \
|
||||
</div> \
|
||||
',
|
||||
|
||||
events: {
|
||||
'click .editor-update-map': 'onEditorSubmit',
|
||||
'change .editor-field-type': 'onFieldTypeChange'
|
||||
},
|
||||
|
||||
|
||||
initialize: function(options, config) {
|
||||
var self = this;
|
||||
|
||||
@ -38,6 +94,11 @@ my.Map = Backbone.View.extend({
|
||||
this.model.bind('change', function() {
|
||||
self._setupGeometryField();
|
||||
});
|
||||
this.model.fields.bind('add', this.render);
|
||||
this.model.fields.bind('reset', function(){
|
||||
self._setupGeometryField()
|
||||
self.render()
|
||||
});
|
||||
this.model.currentDocuments.bind('add', function(doc){self.redraw('add',doc)});
|
||||
this.model.currentDocuments.bind('remove', function(doc){self.redraw('remove',doc)});
|
||||
this.model.currentDocuments.bind('reset', function(){self.redraw('reset')});
|
||||
@ -58,9 +119,22 @@ my.Map = Backbone.View.extend({
|
||||
var self = this;
|
||||
|
||||
htmls = $.mustache(this.template, this.model.toTemplateJSON());
|
||||
|
||||
$(this.el).html(htmls);
|
||||
this.$map = this.el.find('.panel.map');
|
||||
|
||||
// Setup editor fields
|
||||
if (this.geomReady && this.model.fields.length){
|
||||
if (this._geomFieldName){
|
||||
this._selectOption('editor-geom-field',this._geomFieldName);
|
||||
$('#editor-field-type-geom').attr('checked','checked').change();
|
||||
} else{
|
||||
this._selectOption('editor-lon-field',this._lonFieldName);
|
||||
this._selectOption('editor-lat-field',this._latFieldName);
|
||||
$('#editor-field-type-latlon').attr('checked','checked').change();
|
||||
}
|
||||
}
|
||||
|
||||
this.model.bind('query:done', function() {
|
||||
if (!self.geomReady){
|
||||
self._setupGeometryField();
|
||||
@ -81,7 +155,7 @@ my.Map = Backbone.View.extend({
|
||||
|
||||
action = action || 'refresh';
|
||||
|
||||
if (this.geomReady){
|
||||
if (this.geomReady && this.mapReady){
|
||||
if (action == 'reset'){
|
||||
// Clear all features
|
||||
this.features.clearLayers();
|
||||
@ -99,6 +173,34 @@ my.Map = Backbone.View.extend({
|
||||
}
|
||||
},
|
||||
|
||||
/* UI Event handlers */
|
||||
|
||||
onEditorSubmit: function(e){
|
||||
e.preventDefault();
|
||||
if ($('#editor-field-type-geom').attr('checked')){
|
||||
this._geomFieldName = $('.editor-geom-field > select > option:selected').val();
|
||||
this._latFieldName = this._lonFieldName = false;
|
||||
} else {
|
||||
this._geomFieldName = false;
|
||||
this._latFieldName = $('.editor-lat-field > select > option:selected').val();
|
||||
this._lonFieldName = $('.editor-lon-field > select > option:selected').val();
|
||||
}
|
||||
this.geomReady = (this._geomFieldName || (this._latFieldName && this._lonFieldName));
|
||||
this.redraw();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
onFieldTypeChange: function(e){
|
||||
if (e.target.value == 'geom'){
|
||||
$('.editor-field-type-geom').show();
|
||||
$('.editor-field-type-latlon').hide();
|
||||
} else {
|
||||
$('.editor-field-type-geom').hide();
|
||||
$('.editor-field-type-latlon').show();
|
||||
}
|
||||
},
|
||||
|
||||
_add: function(doc){
|
||||
|
||||
var self = this;
|
||||
@ -107,7 +209,7 @@ my.Map = Backbone.View.extend({
|
||||
|
||||
doc.forEach(function(doc){
|
||||
var feature = self._getGeometryFromDocument(doc);
|
||||
if (feature){
|
||||
if (feature instanceof Object){
|
||||
// Build popup contents
|
||||
// TODO: mustache?
|
||||
html = ''
|
||||
@ -120,7 +222,17 @@ my.Map = Backbone.View.extend({
|
||||
// link this Leaflet layer to a Recline doc
|
||||
feature.properties.cid = doc.cid;
|
||||
|
||||
self.features.addGeoJSON(feature);
|
||||
try {
|
||||
self.features.addGeoJSON(feature);
|
||||
} catch (except) {
|
||||
var msg = 'Wrong geometry value';
|
||||
if (except.message) msg += ' (' + except.message + ')';
|
||||
my.notify(msg,{category:'error'});
|
||||
_.breakLoop();
|
||||
}
|
||||
} else {
|
||||
my.notify('Wrong geometry value',{category:'error'});
|
||||
_.breakLoop();
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -169,8 +281,6 @@ my.Map = Backbone.View.extend({
|
||||
this._latFieldName = this._checkField(this.latitudeFieldNames);
|
||||
this._lonFieldName = this._checkField(this.longitudeFieldNames);
|
||||
|
||||
// TODO: Allow users to choose the fields
|
||||
|
||||
this.geomReady = (this._geomFieldName || (this._latFieldName && this._lonFieldName));
|
||||
},
|
||||
|
||||
@ -212,6 +322,18 @@ my.Map = Backbone.View.extend({
|
||||
this.map.setView(new L.LatLng(0, 0), 2);
|
||||
|
||||
this.mapReady = true;
|
||||
},
|
||||
|
||||
_selectOption: function(id,value){
|
||||
var options = $('.' + id + ' > select > option');
|
||||
if (options){
|
||||
options.each(function(opt){
|
||||
if (this.value == value) {
|
||||
$(this).attr('selected','selected');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user