diff --git a/js/draw.js b/js/draw.js
index 1a817ad..9249b8a 100644
--- a/js/draw.js
+++ b/js/draw.js
@@ -1,244 +1,290 @@
(function ($) {
- Drupal.leaflet_widget = Drupal.leaflet_widget || {};
-
- Drupal.behaviors.geofield_widget = {
- attach: attach
- };
-
- function attach(context, settings) {
- $('.leaflet-widget').once().each(function(i, item) {
- var id = $(item).attr('id'),
- options = settings.leaflet_widget_widget[id];
- if (options.toggle) {
- $('#' + id + '-input').before('
GEOJSON
');
- $('#' + id + '-input').before('POINT
');
- $('#manual-' + id + '-point-input').hide();
- $('#' + id + '-geojson-toggle').click(function () {
- $(item).toggle();
- if ($(this).hasClass('map')) {
- $(this).text('Use map');
- $(this).removeClass('map');
- $('#' + id + '-input').get(0).type = 'text';
-
- //Hide select geographic areas if is enable.
- if (options.geographic_areas) {
- $('.geographic_areas_desc').hide();
- }
- }
- else {
- $(this).text('GEOJSON');
- $('#' + id + '-input').get(0).type = 'hidden';
- $(this).addClass('map');
-
- //Show select geographic areas if is enable.
- if (options.geographic_areas) {
- $('.geographic_areas_desc').show();
- }
- }
- });
+ Drupal.leaflet_widget = Drupal.leaflet_widget || {};
- $('#' + id + '-point-toggle').click(function () {
- $(item).toggle();
- $('#manual-' + id + '-point-input').toggle();
+ Drupal.behaviors.geofield_widget = {
+ attach: attach
+ };
- if ($(this).hasClass('map')) {
- $(this).text('Use map');
- $(this).removeClass('map');
- $('#manual-' + id + '-point-input').get(0).type = 'text';
+ function attach(context, settings) {
+ $('.leaflet-widget').once().each(function(i, item) {
+ var id = $(item).attr('id'),
+ options = settings.leaflet_widget_widget[id];
- //Hide select geographic areas if is enable.
- if (options.geographic_areas) {
- $('.geographic_areas_desc').hide();
- }
- }
- else {
- $(this).text('POINT');
- $('#' + id + '-input').get(0).type = 'hidden';
- $(this).addClass('map');
- var point_string = $('#manual-' + id + '-point-input').val();
-
- if (point_string) {
- var point_array = point_string.split(',');
- var geojsonFeature = {
- "type": "Feature",
- "properties": {},
- "geometry": {
- "type": "Point",
- "coordinates": [point_array[0], point_array[1]]
- }
- };
- L.geoJson(geojsonFeature).addTo(map);
- leafletWidgetFormWrite(map._layers, id);
- }
+ // Keeps map from updating when fired from other event.
+ if (typeof id == 'undefined')
+ return false;
- //Show select geographic areas if is enable.
- if (options.geographic_areas) {
- $('.geographic_areas_desc').show();
- }
- }
- });
+ var map = L.map(id, options.map);
- }
- if (options.geographic_areas) {
- var json_data = {};
- var selectList = "Select a state to add into the map:
";
- $('#' + id + '-input').before(selectList);
-
- $('#geographic_areas').change(function() {
- var area = $(this).val();
-
- for (i = 0; i < options.areas.length; i++) {
- json_data = jQuery.parseJSON(options.areas[i]);
- $.each(json_data.features, function (index, item) {
- if (item.id == area) {
- L.geoJson(item).addTo(map);
- leafletWidgetFormWrite(map._layers, id);
- }
- });
- }
- });
- }
- var map = L.map(id, options.map);
-
- L.tileLayer(options.map.base_url).addTo(map);
-
- var current = $('#' + id + '-input').val();
- current = JSON.parse(current);
- var layers = Array();
- if (current.features.length) {
- var geojson = L.geoJson(current)
- for (var key in geojson._layers) {
- layers.push(geojson._layers[key]);
- }
- }
+ L.tileLayer(options.map.base_url).addTo(map);
+
+ // Get initial geojson value
+ var current = $('#' + id + '-input').val();
+ current = JSON.parse(current);
+ var layers = Array();
+ if (current.features.length) {
+ var geojson = L.geoJson(current)
+ for (var key in geojson._layers) {
+ layers.push(geojson._layers[key]);
+ }
+ }
+
+ var Items = new L.FeatureGroup(layers).addTo(map);
+
+ // Autocenter if that's cool.
+ if (options.map.auto_center) {
+ if (current.features.length) {
+ map.fitBounds(Items.getBounds());
+ }
+ }
+
+ // Add controles to the map
+ var drawControl = new L.Control.Draw({
+ autocenter: true,
+ draw: {
+ position: 'topleft',
+ polygon: options.draw.tools.polygon,
+ circle: options.draw.tools.circle,
+ marker: options.draw.tools.marker,
+ rectangle: options.draw.tools.rectangle,
+ polyline: options.draw.tools.polyline
+ },
+ edit: {
+ featureGroup: Items,
+ }
+ });
+
+ map.addControl(drawControl);
+
+ map.on('draw:created', function (e) {
+ var type = e.layerTypee,
+ layer = e.layer;
+ // Remove already created layers. We only want to save one
+ // per field.
+ leafletWidgetLayerRemove(map._layers, Items);
+ // Add new layer.
+ Items.addLayer(layer);
+
+ // Update the field input.
+ leafletWidgetFormWrite(Items._layers, id)
+ });
+
+ map.on('draw:deleted', function (e) {
+ $('#' + id + '-input').val('');
+ });
+
+ Drupal.leaflet_widget[id] = map;
+
+ if (options.toggle) {
+ $('#' + id).before('');
+
+ $('#' + id).after('' +
+ '' +
+ '' +
+ '
');
+
+ // Set placeholder
+ $('#' + id + '-geojson-textarea').attr('placeholder', JSON.stringify({"type":"FeatureCollection","features":[]}));
+
+ // Update field's input when geojson input is updated.
+ // @TODO validate before sync
+ $('#' + id + '-geojson-textarea').on('input', function(e) {
+ if(!$('#' + id + '-geojson-textarea').val()) {
+ $('#' + id + '-input').val(JSON.stringify({"type":"FeatureCollection","features":[]}));
+ } else {
+ $('#' + id + '-input').val($('#' + id + '-geojson-textarea').val());
+ }
+ });
- var Items = new L.FeatureGroup(layers).addTo(map);
- // Autocenter if that's cool.
- if (options.map.auto_center) {
+ $('#' + id).after('' +
+ '' +
+ '' +
+ '
');
+
+ // Update field's input when geojson input is updated.
+ $('#' + id + '-points-input').on('input', function(e) {
+ var latlng = L.latLng($('#' + id + '-points-input').val().split(','));
+ var coordinates = LatLngToCoords(latlng);
+ var write = JSON.stringify(
+ {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":coordinates},"properties":[]}]}
+ );
+ $('#' + id + '-input').val(write);
+ });
+
+ // Set parent as JQuery UI element and update on selection
+ $('#' + id).parent().tabs({
+ // Default tab is the map tab.
+ selected: 0,
+ select: function(event, ui){
+ switch(ui.index) {
+ case 0:
+ // Map tab is selected
+ // Clear previous layers
+ leafletWidgetLayerRemove(map._layers, Items);
+ var current = $('#' + id + '-input').val();
+ current = JSON.parse(current);
if (current.features.length) {
+ var geojson = L.geoJson(current)
+ for (var key in geojson._layers) {
+ // Add new layer.
+ Items.addLayer(geojson._layers[key]);
+ }
map.fitBounds(Items.getBounds());
}
+ break;
+
+ case 1:
+ // GeoJSON tab is selected
+ // Sync from field's input
+ $('#' + id + '-geojson-textarea').val($('#' + id + '-input').val());
+ break;
+
+ case 2:
+ // Points tab is selected
+ // Reset value and error message and classes (if any).
+ $('#' + id + '-points-input').val('');
+ $('#' + id + '-points-input').parent().removeClass('has-error');
+ $('#' + id + '-points-input').prop('disabled', false)
+ .removeClass('error');
+ $('#' + id + '-points .help-block').remove();
+
+ var current = $('#' + id + '-input').val();
+ current = JSON.parse(current);
+ // Make this unavailable if more then single point.
+ if (current.features.length == 0) {
+ // Empty. Nothing to do
+ } else if (current.features.length == 1
+ && current.features[0].geometry.type == 'Point') {
+ $('#' + id + '-points-input').val(current.features[0].geometry.coordinates.toString());
+ } else {
+ $('#' + id + '-points-input').parent().addClass('has-error');
+ $('#' + id + '-points-input').prop('disabled', true)
+ .addClass('error')
+ .after('Current data cannot be converted to a single point!');
+ }
+ break;
}
+ }
+ });
+ }
- var drawControl = new L.Control.Draw({
- autocenter: true,
- draw: {
- position: 'topleft',
- polygon: options.draw.tools.polygon,
- circle: options.draw.tools.circle,
- marker: options.draw.tools.marker,
- rectangle: options.draw.tools.rectangle,
- polyline: options.draw.tools.polyline
- },
- edit: {
- featureGroup: Items
- }
+ if (options.geographic_areas) {
+ var json_data = {};
+ var selectList = "Select a region to add into the map:
";
+ $('#' + id + '-input').before(selectList);
- map.on('draw:created', function (e) {
- var type = e.layerTypee,
- layer = e.layer;
- // Remove already created layers. We only want to save one
- // per field.
- leafletWidgetLayerRemove(map._layers, Items);
- // Add new layer.
- Items.addLayer(layer);
- });
+ $('#geographic_areas').change(function() {
+ var area = $(this).val();
- $(item).parents('form').submit(function(event){
- if ($('#' + id + '-toggle').hasClass('map')) {
- leafletWidgetFormWrite(map._layers, id)
- }
- });
+ for (i = 0; i < options.areas.length; i++) {
+ json_data = jQuery.parseJSON(options.areas[i]);
+ $.each(json_data.features, function (index, item) {
+ if (item.id == area) {
+ var geojson = L.geoJson(item, {
+ onEachFeature: function (feature, layer) {
+ // Remove already created layers. We only want to save one
+ // per field.
+ leafletWidgetLayerRemove(map._layers, Items);
+ Items.addLayer(layer);
- Drupal.leaflet_widget[id] = map;
+ }
+ });
+ leafletWidgetFormWrite(map._layers, id);
+ }
+ });
+ }
});
- }
-
- /**
- * Writes layer to input field if there is a layer to write.
- */
- function leafletWidgetFormWrite(layers, id) {
- var write = Array();
- for (var key in layers) {
- if (layers[key]._latlngs || layers[key]._latlng) {
- write.push(layerToGeometry(layers[key]));
- }
}
- // If no value then provide empty collection.
- if (!write.length) {
- write = JSON.stringify({"type":"FeatureCollection","features":[]});
+ });
+ }
+
+ /**
+ * Writes layer to input field if there is a layer to write.
+ */
+ function leafletWidgetFormWrite(layers, id) {
+ var write = Array();
+ for (var key in layers) {
+ if (layers[key]._latlngs || layers[key]._latlng) {
+ var feature = '{ "type": "Feature","geometry":' + layerToGeometry(layers[key]) + '}';
+ write.push(feature);
}
- $('#' + id + '-input').val('{"type":"FeatureCollection", "features":[' + write + ']}');
}
-
- /**
- * Removes layers that are already on the map.
- */
- function leafletWidgetLayerRemove(layers, Items) {
- for (var key in layers) {
- if (layers[key]._latlngs || layers[key]._latlng) {
- Items.removeLayer(layers[key]);
- }
+ // If no value then provide empty collection.
+ if (!write.length) {
+ write = JSON.stringify({"type":"FeatureCollection","features":[]});
+ }
+ $('#' + id + '-input').val('{"type":"FeatureCollection", "features":[' + write + ']}');
+ }
+
+ /**
+ * Removes layers that are already on the map.
+ */
+ function leafletWidgetLayerRemove(layers, Items) {
+ for (var key in layers) {
+ if (layers[key]._latlngs || layers[key]._latlng) {
+ Items.removeLayer(layers[key]);
}
}
+ }
- // This will all go away once this gets into leaflet main branch:
- // https://github.com/jfirebaugh/Leaflet/commit/4bc36d4c1926d7c68c966264f3cbf179089bd998
- var layerToGeometry = function(layer) {
- var json, type, latlng, latlngs = [], i;
+ // This will all go away once this gets into leaflet main branch:
+ // https://github.com/jfirebaugh/Leaflet/commit/4bc36d4c1926d7c68c966264f3cbf179089bd998
+ var layerToGeometry = function(layer) {
+ var json, type, latlng, latlngs = [], i;
- if (L.Marker && (layer instanceof L.Marker)) {
- type = 'Point';
- latlng = LatLngToCoords(layer._latlng);
- return JSON.stringify({"type": type, "coordinates": latlng});
+ if (L.Marker && (layer instanceof L.Marker)) {
+ type = 'Point';
+ latlng = LatLngToCoords(layer._latlng);
+ return JSON.stringify({"type": type, "coordinates": latlng});
- } else if (L.Polygon && (layer instanceof L.Polygon)) {
- type = 'Polygon';
- latlngs = LatLngsToCoords(layer._latlngs, 1);
- return JSON.stringify({"type": type, "coordinates": [latlngs]});
+ } else if (L.Polygon && (layer instanceof L.Polygon)) {
+ type = 'Polygon';
+ latlngs = LatLngsToCoords(layer._latlngs, 1);
+ return JSON.stringify({"type": type, "coordinates": [latlngs]});
- } else if (L.Polyline && (layer instanceof L.Polyline)) {
- type = 'LineString';
- latlngs = LatLngsToCoords(layer._latlngs);
- return JSON.stringify({"type": type, "coordinates": latlngs});
+ } else if (L.Polyline && (layer instanceof L.Polyline)) {
+ type = 'LineString';
+ latlngs = LatLngsToCoords(layer._latlngs);
+ return JSON.stringify({"type": type, "coordinates": latlngs});
- }
}
+ }
- var LatLngToCoords = function (LatLng, reverse) { // (LatLng, Boolean) -> Array
- var lat = parseFloat(reverse ? LatLng.lng : LatLng.lat),
- lng = parseFloat(reverse ? LatLng.lat : LatLng.lng);
-
- return [lng,lat];
- }
+ var LatLngToCoords = function (LatLng, reverse) { // (LatLng, Boolean) -> Array
+ var lat = parseFloat(reverse ? LatLng.lng : LatLng.lat),
+ lng = parseFloat(reverse ? LatLng.lat : LatLng.lng);
- var LatLngsToCoords = function (LatLngs, levelsDeep, reverse) { // (LatLngs, Number, Boolean) -> Array
- var coord,
- coords = [],
- i, len;
+ return [lng,lat];
+ }
- for (i = 0, len = LatLngs.length; i < len; i++) {
- coord = levelsDeep ?
- LatLngToCoords(LatLngs[i], levelsDeep - 1, reverse) :
- LatLngToCoords(LatLngs[i], reverse);
- coords.push(coord);
- }
+ var LatLngsToCoords = function (LatLngs, levelsDeep, reverse) { // (LatLngs, Number, Boolean) -> Array
+ var coord,
+ coords = [],
+ i, len;
- return coords;
+ for (i = 0, len = LatLngs.length; i < len; i++) {
+ coord = levelsDeep ?
+ LatLngToCoords(LatLngs[i], levelsDeep - 1, reverse) :
+ LatLngToCoords(LatLngs[i], reverse);
+ coords.push(coord);
}
+ return coords;
+ }
+
}(jQuery));
diff --git a/leaflet_widget.module b/leaflet_widget.module
index 127b148..623be6a 100644
--- a/leaflet_widget.module
+++ b/leaflet_widget.module
@@ -172,6 +172,7 @@ function leaflet_widget_field_widget_form(&$form, &$form_state, $field, $instanc
// Include javascript.
$widget['#attached']['library'][] = array('leaflet_widget', 'draw');
+ $widget['#attached']['library'][] = array('system', 'ui.tabs');
//Check if we need to add geographic areas
if (isset($settings['geographic_areas']) && $settings['geographic_areas']) {
@@ -334,7 +335,7 @@ function leaflet_widget_geojson_feature($wkt, $properties = array()) {
*/
function leaflet_widget_leaflet_widget_base_layers() {
return array(
- 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' => 'OSM Mapnik',
+ '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' => 'OSM Mapnik',
);
}