Rework notes UI using leaflet

This commit is contained in:
Tom Hughes 2012-12-01 17:46:26 +00:00
parent 78f608b114
commit de78176e04
8 changed files with 152 additions and 230 deletions

View file

@ -45,12 +45,11 @@ $(document).ready(function () {
var centre = bbox.getCenter();
updatelinks(centre.lon, centre.lat, 16, null, params.minlon, params.minlat, params.maxlon, params.maxlat);
} else if (params.type == "note") {
var centre = new OpenLayers.LonLat(params.lon, params.lat);
map.setView([params.lat, params.lon], 16);
setMapCenter(centre, 16);
addMarkerToMap(centre);
L.marker([params.lat, params.lon], { icon: getUserIcon() }).addTo(map);
var bbox = unproj(map.getExtent());
var bbox = map.getBounds();
$("#loading").hide();
$("#browse_map .geolink").show();
@ -59,7 +58,9 @@ $(document).ready(function () {
return remoteEditHandler(bbox);
});
updatelinks(centre.lon, centre.lat, 16, null, bbox.left, bbox.bottom, bbox.right, bbox.top)
updatelinks(params.lon, params.lat, 16, null,
bbox.getWestLng(), bbox.getSouthLat(),
bbox.getEastLng(), bbox.getNorthLat());
} else {
$("#object_larger_map").hide();
$("#object_edit").hide();

View file

@ -3,247 +3,184 @@
$(document).ready(function () {
var params = OSM.mapParams();
var newNotes;
function saveNewNotes(o) {
var layer = o.object;
newNotes = layer.getFeaturesByAttribute("status", "new")
layer.removeFeatures(newNotes, { silent: true });
var noteIcons = {
"new": L.icon({
iconUrl: "<%= image_path 'new_note_marker.png' %>",
iconSize: [22, 22],
iconAnchor: [11, 11]
}),
"open": L.icon({
iconUrl: "<%= image_path 'open_note_marker.png' %>",
iconSize: [22, 22],
iconAnchor: [11, 11]
}),
"closed": L.icon({
iconUrl: "<%= image_path 'closed_note_marker.png' %>",
iconSize: [22, 22],
iconAnchor: [11, 11]
})
};
var noteLayer = new L.LayerGroup();
var notes = {};
map.on("layeradd", function (e) {
if (e.layer == noteLayer) {
loadNotes();
map.on("moveend", loadNotes);
}
});
map.on("layerremove", function (e) {
if (e.layer == noteLayer) {
map.off("moveend", loadNotes);
noteLayer.clearLayers();
}
});
if (OSM.STATUS != 'api_offline' && OSM.STATUS != 'database_offline') {
map.layersControl.addOverlay(noteLayer, I18n.t("browse.start_rjs.notes_layer_name"));
if (params.notes) map.addLayer(noteLayer);
}
function restoreNewNotes(o) {
var layer = o.object;
layer.addFeatures(newNotes);
newNotes = undefined;
function updateMarker(marker, feature) {
var icon = noteIcons[feature.properties.status];
var popupContent = createPopupContent(marker, feature.properties);
if (marker)
{
marker.setIcon(noteIcons[feature.properties.status]);
marker._popup.setContent(popupContent);
}
else
{
marker = L.marker(feature.geometry.coordinates.reverse(), {
icon: icon,
opacity: 0.7
});
marker.addTo(noteLayer).bindPopup(popupContent);
}
return marker;
}
function createNote(feature, form) {
var location = unproj(feature.geometry.getBounds().getCenterLonLat());
function loadNotes() {
var bounds = map.getBounds();
var url = "/api/" + OSM.API_VERSION + "/notes.json?bbox=" + bounds.toBBOX();
$(form).find("input[type=submit]").prop("disabled", true);
$.ajax({
url: url,
success: function (json) {
var oldNotes = notes;
$.ajax($("#createnoteanchor").attr("href"), {
type: "POST",
data: {
lon: location.lon,
lat: location.lat,
text: $(form.text).val()
},
success: function (data) {
map.noteSelector.unselect(feature);
notes = {};
feature.attributes = data.properties;
json.features.forEach(function (feature) {
var marker = oldNotes[feature.properties.id];
map.noteLayer.drawFeature(feature);
delete oldNotes[feature.properties.id];
map.noteMover.deactivate();
notes[feature.properties.id] = updateMarker(marker, feature);
});
for (id in oldNotes) {
noteLayer.removeLayer(oldNotes[id]);
}
}
});
}
};
function updateNote(feature, form, close) {
var url = close ? feature.attributes.close_url : feature.attributes.comment_url;
function createPopupContent(marker, properties) {
var content = $(JST["templates/notes/show"]({ note: properties }));
$(form).find("input[type=submit]").prop("disabled", true);
$.ajax(url, {
type: "POST",
data: {
text: $(form.text).val()
},
success: function (data) {
map.noteSelector.unselect(feature)
feature.attributes = data.properties;
map.noteSelector.select(feature)
}
});
}
function noteSelected(o) {
var feature = o.feature;
var location = feature.geometry.getBounds().getCenterLonLat();
var content;
var onClose;
if (feature.attributes.status === "new") {
content = JST["templates/notes/new"]();
onClose = function (e) {
feature.attributes.status = "cancelled";
map.noteSelector.unselect(feature);
map.noteLayer.removeFeatures(feature);
feature.destroy();
map.noteMover.deactivate();
};
} else {
content = JST["templates/notes/show"]({ note: feature.attributes });
onClose = function (e) {
map.noteSelector.unselect(feature)
};
};
feature.popup = new OpenLayers.Popup.FramedCloud(
feature.attributes.id, location, null, content, null, true, onClose
);
map.addPopup(feature.popup);
// feature.popup.show();
$(feature.popup.contentDiv).find("textarea").autoGrow();
$(feature.popup.contentDiv).find("textarea").on("input", function (e) {
content.find("textarea").on("input", function (e) {
var form = e.target.form;
if ($(e.target).val() == "") {
$(form.close).val(I18n.t("javascripts.notes.show.close"));
$(form.comment).prop("disabled", true);
} else {
$(form.close).val(I18n.t("javascripts.notes.show.comment_and_close"));
$(form.comment).prop("disabled", false);
}
});
$(feature.popup.contentDiv).find("input#note-add").click(function (e) {
content.find("input[type=submit]").on("click", function (e) {
e.preventDefault();
createNote(feature, e.target.form);
updateNote(marker, e.target.form, $(e.target).data("url"));
});
$(feature.popup.contentDiv).find("input#note-comment").click(function (e) {
e.preventDefault();
updateNote(feature, e.target.form, false);
});
$(feature.popup.contentDiv).find("input#note-close").click(function (e) {
e.preventDefault();
updateNote(feature, e.target.form, true);
});
feature.popup.updateSize();
return content[0];
}
function noteUnselected(o) {
var feature = o.feature;
function createNote(marker, form, url) {
var location = marker.getLatLng();
map.removePopup(feature.popup);
}
$(form).find("input[type=submit]").prop("disabled", true);
function addNote() {
var lonlat = map.getCenter();
var layer = map.noteLayer;
var geometry = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);
var feature = new OpenLayers.Feature.Vector(geometry, {
status: "new"
});
layer.addFeatures(feature);
map.noteSelector.unselectAll();
map.noteSelector.select(feature);
map.noteMover.activate();
map.noteLayer.setVisibility(true);
}
$("#map").on("initialised", function () {
map.noteLayer = new OpenLayers.Layer.Vector("Notes", {
visibility: params.notes,
displayInLayerSwitcher: false,
projection: new OpenLayers.Projection("EPSG:4326"),
styleMap: new OpenLayers.StyleMap(new OpenLayers.Style({
graphicWidth: 22,
graphicHeight: 22,
graphicOpacity: 0.7,
graphicXOffset: -11,
graphicYOffset: -11
}, {
rules: [
new OpenLayers.Rule({
filter: new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.EQUAL_TO,
property: "status",
value: "new"
}),
symbolizer: {
externalGraphic: "<%= image_path 'new_note_marker.png' %>"
}
}),
new OpenLayers.Rule({
filter: new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.EQUAL_TO,
property: "status",
value: "open"
}),
symbolizer: {
externalGraphic: "<%= image_path 'open_note_marker.png' %>"
}
}),
new OpenLayers.Rule({
filter: new OpenLayers.Filter.Comparison({
type: OpenLayers.Filter.Comparison.EQUAL_TO,
property: "status",
value: "closed"
}),
symbolizer: {
externalGraphic: "<%= image_path 'closed_note_marker.png' %>"
}
})
]
})),
strategies: [
new OpenLayers.Strategy.BBOX()
],
protocol: new OpenLayers.Protocol.HTTP({
url: $("#show_notes").attr("href"),
format: new OpenLayers.Format.GeoJSON()
})
});
map.noteLayer.events.register("beforefeaturesremoved", map, saveNewNotes);
map.noteLayer.events.register("featuresremoved", map, restoreNewNotes);
map.noteLayer.events.register("featureselected", map, noteSelected);
map.noteLayer.events.register("featureunselected", map, noteUnselected);
map.addLayer(map.noteLayer);
map.noteSelector = new OpenLayers.Control.SelectFeature(map.noteLayer, {
autoActivate: true
});
map.addControl(map.noteSelector);
map.noteMover = new OpenLayers.Control.DragFeature(map.noteLayer, {
onDrag: function (feature, pixel) {
feature.popup.lonlat = feature.geometry.getBounds().getCenterLonLat();
feature.popup.updatePosition();
$.ajax({
url: url,
type: "POST",
data: {
lat: location.lat,
lon: location.lng,
text: $(form.text).val()
},
featureCallbacks: {
over: function (feature) {
if (feature.attributes.status === "new") {
map.noteMover.overFeature.apply(map.noteMover, [feature]);
}
}
success: function (feature) {
notes[feature.properties.id] = updateMarker(marker, feature);
$(".leaflet-popup-close-button").off("click.close");
}
});
}
map.addControl(map.noteMover);
function updateNote(marker, form, url) {
$(form).find("input[type=submit]").prop("disabled", true);
$("#show_notes").click(function (e) {
map.noteLayer.setVisibility(true);
$.ajax({
url: url,
type: "POST",
data: {
text: $(form.text).val()
},
success: function (feature) {
var popupContent = createPopupContent(marker, feature.properties);
e.preventDefault();
marker.setIcon(noteIcons[feature.properties.status]);
marker._popup.setContent(popupContent);
}
});
}
$("#createnoteanchor").click(function (e) {
e.preventDefault();
map.addLayer(noteLayer);
var marker = L.marker(map.getCenter(), {
icon: noteIcons["new"],
opacity: 0.7,
draggable: true
});
$("#createnoteanchor").click(function (e) {
map.noteLayer.setVisibility(true);
addNote();
var popupContent = $(JST["templates/notes/new"]({ create_url: $(e.target).attr("href") }));
popupContent.find("input[type=submit]").on("click", function (e) {
e.preventDefault();
createNote(marker, e.target.form, $(e.target).data("url"));
});
marker.addTo(noteLayer).bindPopup(popupContent[0]).openPopup();
$(".leaflet-popup-close-button").on("click.close", function (e) {
map.removeLayer(marker);
});
marker.on("dragend", function (e) {
e.target.openPopup();
});
});
});

View file

@ -109,8 +109,6 @@ function createMap(divName, options) {
map.invalidateSize();
});
$("#" + divName).trigger("initialised");
return map;
}

View file

@ -1,15 +1,12 @@
<div class="note">
<p>
<%- I18n.t('javascripts.notes.new.intro_1') %><br/>
<%- I18n.t('javascripts.notes.new.intro_2') %>
</p>
<p><%- I18n.t('javascripts.notes.new.intro') %></p>
<form action="#">
<input type="hidden" name="lon">
<input type="hidden" name="lat">
<textarea name="text" cols="40" rows="10"></textarea>
<br/>
<div class="buttons">
<input type="submit" name="add" value="<%- I18n.t('javascripts.notes.new.add') %>" id="note-add">
<input type="submit" name="add" value="<%- I18n.t('javascripts.notes.new.add') %>" data-url="<%- create_url %>">
</div>
</form>
</div>

View file

@ -16,8 +16,8 @@
<textarea name="text" cols="40" rows="5"></textarea>
<br/>
<div class="buttons">
<input type="submit" name="close" value="<%- I18n.t('javascripts.notes.show.close') %>" id="note-close">
<input type="submit" name="comment" value="<%- I18n.t('javascripts.notes.show.comment') %>" id="note-comment">
<input type="submit" name="close" value="<%- I18n.t('javascripts.notes.show.close') %>" data-url="<%- note.close_url %>">
<input type="submit" name="comment" value="<%- I18n.t('javascripts.notes.show.comment') %>" data-url="<%- note.comment_url %>" disabled="1">
</div>
</form>
<% } %>

View file

@ -1417,11 +1417,7 @@ abbr.geo {
/* Rules for the notes interface */
.note {
width: 300px;
.buttons {
margin-top: 5px;
text-align: right;
}
.note .buttons {
margin-top: 5px;
text-align: right;
}

View file

@ -2,12 +2,6 @@
<%= javascript_include_tag "index" %>
<% end %>
<% unless STATUS == :api_offline or STATUS == :database_offline -%>
<% content_for :editmenu do -%>
<li><%= link_to t("browse.start_rjs.notes_layer_name"), notes_url(:format => :json), :id => "show_notes" %></li>
<% end -%>
<% end -%>
<% content_for :left_menu do %>
<li><h4><%= link_to t("site.key.map_key"), {:action => :key}, :id => "open_map_key", :title => t("site.key.map_key_tooltip") %></h4></li>
<% end %>

View file

@ -2017,8 +2017,7 @@ en:
createnote_zoom_alert: You must zoom in to add a note to the map
notes:
new:
intro_1: Move the marker to the correct position and
intro_2: "add your comment in the box below:"
intro: "Move the marker to the correct position and add your comment in the box below:"
add: Add Note
show:
title: Note %{id}