Refactor notes code to work with recent site changes
[rails.git] / app / assets / javascripts / index / notes.js.erb
1 $(document).ready(function () {
2   var params = OSM.mapParams();
3   var newNotes;
4
5   function saveNewNotes(o) {
6     var layer = o.object;
7     newNotes = layer.getFeaturesByAttribute("status", "new")
8     layer.removeFeatures(newNotes, { silent: true });
9   }
10
11   function restoreNewNotes(o) {
12     var layer = o.object;
13     layer.addFeatures(newNotes);
14     newNotes = undefined;
15   }
16
17   function describeNote(n) {
18     var description = "<h2>Note " + n.id + "</h2>";
19
20     n.comments.forEach(function (c) {
21       description += "<p><small class='deemphasize'>" + c.action + " by ";
22       description += c.user + " at " + c.date + "</small><br/>" + c.text + "</p>";
23     });
24
25     return description;
26   }
27
28   function noteSelected(o) {
29     var feature = o.feature;
30     var location = feature.geometry.getBounds().getCenterLonLat();
31     var content;
32     var close;
33
34     if (feature.attributes.status === "new") {
35       var form = $("#new-note").clone();
36       form.removeClass("hidden");
37       content = form.html();
38       close = false;
39     } else {
40       content = describeNote(feature.attributes);
41       close = true;
42     };
43
44     feature.popup = new OpenLayers.Popup.FramedCloud(
45       feature.attributes.id, location, null, content, null, close,
46       function (e) { map.noteSelector.unselect(feature) }
47     );
48
49     map.addPopup(feature.popup);
50     // feature.popup.show();
51
52     $(feature.popup.contentDiv).find("textarea").autoGrow();
53
54     $(feature.popup.contentDiv).find("input#note-submit").click(function (e) {
55       var location = unproj(feature.geometry.getBounds().getCenterLonLat());
56       var form = $(e.target).parents("form").first();
57
58       $.ajax(form.prop("action"), {
59         type: form.prop("method"),
60         data: {
61           lon: location.lon,
62           lat: location.lat,
63           text: form.find("textarea#comment").val()
64         },
65         success: function (data) {
66           map.noteSelector.unselect(feature);
67
68           feature.attributes.status = "open";
69           feature.attributes.id = data;
70
71           map.noteLayer.drawFeature(feature);
72
73           map.noteMover.deactivate();
74         }
75       });
76
77       e.preventDefault();
78     });
79
80     $(feature.popup.contentDiv).find("input#note-cancel").click(function (e) {
81       feature.attributes.status = "cancelled";
82
83       map.noteSelector.unselect(feature);
84       map.noteLayer.removeFeatures(feature);
85
86       feature.destroy();
87
88       map.noteMover.deactivate();
89
90       e.preventDefault();
91     });
92
93     feature.popup.updateSize();
94   }
95
96   function noteUnselected(o) {
97     var feature = o.feature;
98
99     map.removePopup(feature.popup);
100   }
101
102   function addNote() {
103     var lonlat = map.getCenter();
104     var layer = map.noteLayer;
105     var geometry = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);
106     var feature = new OpenLayers.Feature.Vector(geometry, {
107       status: "new"
108     });
109
110     layer.addFeatures(feature);
111     map.noteSelector.unselectAll();
112     map.noteSelector.select(feature);
113     map.noteMover.activate();
114     map.noteLayer.setVisibility(true);
115   }
116
117   $("#map").on("initialised", function () {
118     map.noteLayer = new OpenLayers.Layer.Vector("Notes", {
119       visibility: params.notes,
120       displayInLayerSwitcher: false,
121       projection: new OpenLayers.Projection("EPSG:4326"),
122       styleMap: new OpenLayers.StyleMap(new OpenLayers.Style({
123         graphicWidth: 22,
124         graphicHeight: 22,
125         graphicOpacity: 0.7,
126         graphicXOffset: -11,
127         graphicYOffset: -11
128       }, {
129         rules: [
130           new OpenLayers.Rule({
131             filter: new OpenLayers.Filter.Comparison({
132               type: OpenLayers.Filter.Comparison.EQUAL_TO,
133               property: "status",
134               value: "new"
135             }),
136             symbolizer: {
137               externalGraphic: "<%= image_path 'new_note_marker.png' %>"
138             }
139           }),
140           new OpenLayers.Rule({
141             filter: new OpenLayers.Filter.Comparison({
142               type: OpenLayers.Filter.Comparison.EQUAL_TO,
143               property: "status",
144               value: "open"
145             }),
146             symbolizer: {
147               externalGraphic: "<%= image_path 'open_note_marker.png' %>"
148             }
149           }),
150           new OpenLayers.Rule({
151             filter: new OpenLayers.Filter.Comparison({
152               type: OpenLayers.Filter.Comparison.EQUAL_TO,
153               property: "status",
154               value: "closed"
155             }),
156             symbolizer: {
157               externalGraphic: "<%= image_path 'closed_note_marker.png' %>"
158             }
159           })
160         ]
161       })),
162       strategies: [
163         new OpenLayers.Strategy.BBOX()
164       ],
165       protocol: new OpenLayers.Protocol.HTTP({
166         url: $("#show_notes").attr("href"),
167         format: new OpenLayers.Format.GeoJSON()
168       })
169     });
170
171     map.noteLayer.events.register("beforefeaturesremoved", map, saveNewNotes);
172     map.noteLayer.events.register("featuresremoved", map, restoreNewNotes);
173     map.noteLayer.events.register("featureselected", map, noteSelected);
174     map.noteLayer.events.register("featureunselected", map, noteUnselected);
175
176     map.addLayer(map.noteLayer);
177
178     map.noteSelector = new OpenLayers.Control.SelectFeature(map.noteLayer, {
179       autoActivate: true
180     });
181
182     map.addControl(map.noteSelector);
183
184     map.noteMover = new OpenLayers.Control.DragFeature(map.noteLayer, {
185       onDrag: function (feature, pixel) {
186         feature.popup.lonlat = feature.geometry.getBounds().getCenterLonLat();
187         feature.popup.updatePosition();
188       },
189       featureCallbacks: {
190         over: function (feature) {
191           if (feature.attributes.status === "new") {
192             map.noteMover.overFeature.apply(map.noteMover, [feature]);
193           }
194         }
195       }
196     });
197
198     map.addControl(map.noteMover);
199
200     $("#show_notes").click(function (e) {
201       map.noteLayer.setVisibility(true);
202
203       e.preventDefault();
204     });
205
206     $("#createnoteanchor").click(function (e) {
207       map.noteLayer.setVisibility(true);
208
209       addNote();
210
211       e.preventDefault();
212     });
213   });
214 });