usage hints for 477 zone editor, #30260
[freeside.git] / httemplate / elements / polygon.html
1 <%init>
2 my %opt = @_;
3 my $field = $opt{'field'};
4 my $id = $opt{'id'} || $opt{'field'};
5 my $div_id = "div_$id";
6
7 my $vertices_json = $opt{'curr_value'} || '[]';
8 </%init>
9 <& hidden.html, %opt &>
10 <div id="<% $div_id %>" style="height: 600px; width: 600px"></div>
11 <div id="<% $div_id %>_hint" style="width: 100%; border: 2px solid black; text-align: center; box-sizing: border-box; padding: 4px">&nbsp;</div>
12
13 <script src="<% $fsurl %>elements/jquery.js"></script>
14 <script src="https://maps.googleapis.com/maps/api/js?libraries=drawing&v=3.22"></script>
15 <script>
16 var map;
17 var drawingManager;
18
19 function updateFormInput(event) {
20   var path = window.polygon.getPath();
21   var vertices = []; // array of arrays, geoJSON style
22   for (var i =0; i < path.getLength(); i++) {
23     var xy = path.getAt(i);
24     vertices[i] = [ xy.lat(), xy.lng() ];
25   }
26   if (console) console.log(vertices); //XXX
27   $('#<% $field %>').prop('value', JSON.stringify(vertices));
28 }
29
30 $(function() {
31   mapOptions = {
32     zoom: 4,
33     center: {lat: 39.40114, lng: -96.57127}, // continental U.S.
34     mapTypeId: google.maps.MapTypeId.ROADMAP,
35     panControl: true,
36     scaleControl: true,
37     streetViewControl: false,
38   };
39   var div_map = $('#<% $div_id %>');
40   var div_hint = $('#<% $div_id %>_hint');
41   map = new google.maps.Map(div_map[0], mapOptions);
42
43   var set_hint = function(txt) {
44     div_hint.text(txt);
45   }
46
47   var polygonComplete = function(p) {
48     window.polygon = p;
49     if (drawingManager) {
50       drawingManager.setDrawingMode(null);
51       drawingManager.setOptions({ drawingControl: false });
52     }
53     // double click to delete a vertex (so long as it remains a polygon)
54     p.addListener('dblclick', function (mev) {
55       if (mev.vertex != null && window.polygon.getPath().length > 3) {
56         p.getPath().removeAt(mev.vertex);
57       }
58     });
59     // any time the polygon is modified, update the vertex list
60     p.getPath().addListener('set_at', updateFormInput);
61     p.getPath().addListener('insert_at', updateFormInput);
62     p.getPath().addListener('remove_at', updateFormInput);
63
64     // and also now
65     updateFormInput();
66
67     set_hint('Edit the zone by dragging the markers. Double-click to remove a vertex.');
68
69   };
70
71   var polygonOptions = {
72     fillColor: '#0000a0',
73     fillOpacity: 0.2,
74     strokeColor: '#0000a0',
75     strokeWeight: 2,
76     clickable: false,
77     editable: true,
78     zIndex: 1,
79     map: map,
80   };
81
82   var vertex_array = <% $vertices_json %>;
83   if ( vertex_array.length > 2 ) {
84     // then we already have a polygon. make it acceptable to google maps,
85     // and also create a bounding box for it and fit the map to that.
86
87     var path = [];
88     var bounds = new google.maps.LatLngBounds();
89     for (var i = 0; i < vertex_array.length; i++) {
90       var xy = new google.maps.LatLng(vertex_array[i][0], vertex_array[i][1]);
91       path.push(xy);
92       bounds.extend(xy);
93     }
94
95     polygonOptions.paths = [ path ];
96     polygonComplete(new google.maps.Polygon(polygonOptions));
97     map.fitBounds(bounds);
98
99   } else {
100     // there are no vertices, or not enough to make a polygon, so 
101     // enable drawing mode to create a new one
102
103     drawingManager = new google.maps.drawing.DrawingManager({
104       drawingMode: google.maps.drawing.OverlayType.POLYGON,
105       drawingControl: true,
106       drawingControlOptions: {
107         position: google.maps.ControlPosition.TOP_CENTER,
108         drawingModes: [
109           google.maps.drawing.OverlayType.POLYGON,
110         ]
111       },
112       polygonOptions: polygonOptions,
113     });
114
115     // after a single polygon is drawn: remember it, add a listener to let
116     // nodes be deleted, and exit drawing mode
117     drawingManager.addListener('polygoncomplete', polygonComplete);
118     drawingManager.setMap(map);
119
120     // center the map on the user (for lack of a better choice)
121     if (navigator.geolocation) {
122       navigator.geolocation.getCurrentPosition(function(position) {
123         var pos = {
124           lat: position.coords.latitude,
125           lng: position.coords.longitude
126         };
127
128         map.setCenter(pos);
129         map.setZoom(12);
130       });
131     } // on error, or if geolocation isn't available, do nothing
132
133     set_hint('Click to place the corners of the zone.');
134   }
135
136 });
137
138     </script>
139   </body>
140 </html>