[35821] | 1 | // Global autocomplete labels list: one list for all the map editors' shape labels in a page
|
---|
| 2 | // We use the global labels hashmap to more efficiently ensure uniqueness of labels in our autocomplete list
|
---|
| 3 | var global_autocompleteLabelsList = [];
|
---|
| 4 | var global_labels_hashmap = {};
|
---|
| 5 |
|
---|
| 6 | function MapEditor(id) {
|
---|
| 7 | // TODO: investigate const, see https://www.w3schools.com/js/js_const.asp and check it will work on older browsers,
|
---|
| 8 | // https://stackoverflow.com/questions/4271566/how-do-i-know-which-version-of-javascript-im-using
|
---|
| 9 | this.MAX_THICKNESS = 5.0;
|
---|
| 10 | this.MIN_THICKNESS = 0.0;
|
---|
| 11 | this.MAX_OPACITY = 100.00;
|
---|
| 12 | this.MIN_OPACITY = 0.00;
|
---|
| 13 |
|
---|
| 14 | // WORK-IN-PROGRESS FEATURE: label on Map (to be changed to a label associated with each shape later)
|
---|
| 15 | // Also uncomment import of label-overlay-class.js in document.xsl
|
---|
| 16 | //this.labelOverlay = null;
|
---|
| 17 |
|
---|
| 18 |
|
---|
| 19 | this.id = id;
|
---|
| 20 | this.shiftKeyPressed = false;
|
---|
| 21 | this.beingDragged = false;
|
---|
| 22 | this.allowDeselect = true;
|
---|
| 23 | this.colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
|
---|
| 24 | this.selectedColor;
|
---|
| 25 | this.colorButtons = {};
|
---|
| 26 | this.thicknessValue = 1;
|
---|
| 27 | this.opacityValue = 40;
|
---|
| 28 | this.overlays = [];
|
---|
| 29 | this.selectedShapes = [];
|
---|
| 30 | this.listenersArray = [];
|
---|
| 31 | this.mapsArray = [];
|
---|
| 32 | this.drawingManager;
|
---|
| 33 | this.selectedShape;
|
---|
| 34 | this.savedOverlays = null;
|
---|
| 35 | this.map = null;
|
---|
| 36 | this.counter = 0;
|
---|
| 37 | this.branchNum = 1;
|
---|
| 38 | this.mouseState = "up";
|
---|
| 39 | this.thicknessRangeListener = this.thicknessValue; // ????
|
---|
| 40 | this.resizable = false;
|
---|
| 41 | this.dontResize = false;
|
---|
| 42 |
|
---|
| 43 | this.shapeOptions = {
|
---|
| 44 | suppressUndo: true,
|
---|
| 45 | fillColor: '#CA4A2F',
|
---|
| 46 | strokeWeight: this.thicknessValue,
|
---|
| 47 | fillOpacity: this.opacityValue / 100,
|
---|
| 48 | editable: true,
|
---|
| 49 | geodesic: false,
|
---|
| 50 | draggable: true,
|
---|
| 51 | description: ""
|
---|
| 52 | };
|
---|
| 53 | this.mapEditorHistory = new MapEditorHistory(this);
|
---|
| 54 | }
|
---|
| 55 |
|
---|
| 56 | //draggable checkbox control
|
---|
| 57 | MapEditor.prototype.initMapEditorControls = function () {
|
---|
| 58 | var that = this;
|
---|
| 59 |
|
---|
| 60 | var draggableCB = document.getElementById("draggableCB-"+ this.id);
|
---|
| 61 | draggableCB.addEventListener('change', function () {
|
---|
| 62 | if (this.checked) {
|
---|
| 63 | for (var i = 0; i < that.overlays.length; i++) {
|
---|
| 64 | that.overlays[i].draggable = false;
|
---|
| 65 | that.shapeOptions.draggable = false;
|
---|
| 66 | }
|
---|
| 67 | } else {
|
---|
| 68 | for (var i = 0; i < that.overlays.length; i++) {
|
---|
| 69 | that.overlays[i].draggable = true;
|
---|
| 70 | that.shapeOptions.draggable = true;
|
---|
| 71 | }
|
---|
| 72 | }
|
---|
| 73 | });
|
---|
| 74 |
|
---|
| 75 |
|
---|
| 76 | //Update thickness
|
---|
| 77 | var thicknessSliderOutput = document.getElementById("thicknessRangeVal" + "-" + this.id);
|
---|
| 78 | var thicknessSlider = document.getElementById("thicknessRange" + "-" + this.id);
|
---|
| 79 | var thicknessValue = ((thicknessSlider.value / 20) * 100) / 100;
|
---|
| 80 | thicknessSliderOutput.value = thicknessValue.toFixed(2);
|
---|
| 81 |
|
---|
| 82 | thicknessSlider.oninput = function () {
|
---|
| 83 | that.shapeSpecsChangeMD();
|
---|
| 84 | var thicknessVal = ((this.value / 20) * 100) / 100;
|
---|
| 85 | thicknessSliderOutput.value = thicknessVal.toFixed(2);
|
---|
| 86 | that.thicknessValue = this.value / 20;
|
---|
| 87 | that.shapeOptions.strokeWeight = that.thicknessValue;
|
---|
| 88 | that.setSelectedThickness(that.thicknessValue);
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | thicknessSliderOutput.oninput = function () {
|
---|
| 92 | that.shapeSpecsChangeMD(); // TODO: DO WE NEED THIS LINE? (LINE COPIED & PASTED FROM ABOVE)
|
---|
| 93 | if(this.value > that.MAX_THICKNESS) this.value = that.MAX_THICKNESS;
|
---|
| 94 | if(this.value < that.MIN_THICKNESS) this.value = that.MIN_THICKNESS;
|
---|
| 95 | var thicknessVal = this.value * 20;
|
---|
| 96 | thicknessSlider.value = thicknessVal.toFixed(2);
|
---|
| 97 | that.thicknessValue = this.value;
|
---|
| 98 | that.shapeOptions.strokeWeight = that.thicknessValue;
|
---|
| 99 | that.setSelectedThickness(that.thicknessValue);
|
---|
| 100 | }
|
---|
| 101 | //Update opacity
|
---|
| 102 | // TODO: https://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
|
---|
| 103 | var opacitySlider = document.getElementById("colourOpacity" + "-" + this.id);
|
---|
| 104 | var opacitySliderOutput = document.getElementById("opacityRangeVal" + "-" + this.id);
|
---|
| 105 |
|
---|
| 106 | opacitySlider.oninput = function () {
|
---|
| 107 | that.shapeSpecsChangeMD();
|
---|
| 108 | opacitySliderOutput.value = this.value;
|
---|
| 109 | that.opacityValue = this.value / 100;
|
---|
| 110 | that.shapeOptions.fillOpacity = that.opacityValue;
|
---|
| 111 | that.setSelectedOpacity(that.opacityValue);
|
---|
| 112 | }
|
---|
| 113 | opacitySliderOutput.oninput = function () {
|
---|
| 114 | that.shapeSpecsChangeOnInput();
|
---|
| 115 | if(this.value > that.MAX_OPACITY) this.value = that.MAX_OPACITY;
|
---|
| 116 | if(this.value < that.MIN_OPACITY) this.value = that.MIN_OPACITY;
|
---|
| 117 | opacitySlider.value = this.value;
|
---|
| 118 | that.opacityValue = this.value / 100;
|
---|
| 119 | that.shapeOptions.fillOpacity = that.opacityValue;
|
---|
| 120 | that.setSelectedOpacity(that.opacityValue);
|
---|
| 121 | }
|
---|
| 122 |
|
---|
| 123 | var descriptionInput = document.getElementById("description" + "-" + this.id);
|
---|
| 124 | // don't use oninput, use onchange, because with autocomplete a newly entered or pasted value
|
---|
| 125 | // doesn't always get stored properly when using oninput.
|
---|
| 126 | descriptionInput.onchange = function () {
|
---|
| 127 | that.shapeSpecsChangeOnInput(); // takes care of history (undo/redo)
|
---|
| 128 | var description = this.value;
|
---|
| 129 | that.shapeOptions.description = description;
|
---|
| 130 | that.setSelectedDescription(that.shapeOptions.description);
|
---|
| 131 | }
|
---|
| 132 |
|
---|
| 133 | // Also add a COMPLETED description (i.e. when description input box loses focus)
|
---|
| 134 | // to the autocomplete list of descriptions/labels
|
---|
| 135 | descriptionInput.onblur = function () {
|
---|
| 136 | var description = this.value;
|
---|
| 137 | that.addToAutocompleteLabelsList(description);
|
---|
| 138 | }
|
---|
| 139 |
|
---|
| 140 | // TODO: Do we need these listeners, when we already have onInput methods above? Test.
|
---|
| 141 | document.getElementById("color-palette1" + "-" + this.id).addEventListener("mousedown", function() { that.shapeSpecsChangeMD() });
|
---|
| 142 | document.getElementById("thicknessRange" + "-" + this.id).addEventListener("mouseup", function () { that.shapeSpecsChangeMU() });
|
---|
| 143 | document.getElementById("colourOpacity" + "-" + this.id).addEventListener("mouseup", function () { that.shapeSpecsChangeMU() });
|
---|
| 144 | //document.getElementById("description" + "-" + this.id).addEventListener("keypress", function () { that.shapeSpecsChangeOnInput() });
|
---|
| 145 |
|
---|
| 146 | document.onmousedown = function (ev) {
|
---|
| 147 | that.mouseState = "down";
|
---|
| 148 | // console.log('Down State you can now start dragging');
|
---|
| 149 | //do not write any code here in this function
|
---|
| 150 | }
|
---|
| 151 |
|
---|
| 152 | document.onmouseup = function (ev) {
|
---|
| 153 | that.mouseState = "up";
|
---|
| 154 | // console.log('up state you cannot drag now because you are not holding your mouse')
|
---|
| 155 | //do not write any code here in this function
|
---|
| 156 | }
|
---|
| 157 |
|
---|
| 158 |
|
---|
| 159 | //prompts the user to save the changes before reloading/leaving the page
|
---|
| 160 | window.onbeforeunload = function (e) {
|
---|
| 161 | var currentOverlays = JSON.stringify(ShapesUtil.overlayToJSON(that.overlays));
|
---|
| 162 | var enableMessage = currentOverlays !== that.savedOverlays;
|
---|
| 163 | var message = "Changes are not saved. Are you sure you want to leave?";
|
---|
| 164 |
|
---|
| 165 |
|
---|
| 166 | // Comment out following section in entirety -- from "e = e || window.event" to end of "if(e)" -- if
|
---|
| 167 | // you don't want to see the popup about changes that haven't been saved yet
|
---|
| 168 | e = e || window.event;
|
---|
| 169 | // For IE and Firefox
|
---|
| 170 | if (e) {
|
---|
| 171 |
|
---|
| 172 | if(enableMessage){
|
---|
| 173 | if(currentOverlays !== "[]") {
|
---|
| 174 | alert(message);
|
---|
| 175 | e.returnValue = message;
|
---|
| 176 |
|
---|
| 177 | // For Safari
|
---|
| 178 | return message;
|
---|
| 179 | }
|
---|
| 180 | }
|
---|
| 181 | }
|
---|
| 182 | }
|
---|
| 183 | }
|
---|
| 184 |
|
---|
| 185 | // Ensure only unique labels are added to our autocomplete list
|
---|
| 186 | MapEditor.prototype.addToAutocompleteLabelsList = function (newLabel) {
|
---|
| 187 |
|
---|
| 188 | if(typeof(newLabel) === 'undefined') { return; }
|
---|
| 189 |
|
---|
| 190 | // We use a hashmap to more efficiently ensure uniqueness of labels in our array
|
---|
| 191 | // https://stackoverflow.com/questions/11040472/how-to-check-if-object-property-exists-with-a-variable-holding-the-property-name
|
---|
| 192 | if (newLabel !== "" && !global_labels_hashmap.hasOwnProperty(newLabel)) { // label is not empty and unique, so
|
---|
| 193 | // add to hashmap now
|
---|
| 194 | global_labels_hashmap[newLabel] = 1;
|
---|
| 195 | // add to autocomplete list and sort alphabetically
|
---|
| 196 | global_autocompleteLabelsList.push(newLabel);
|
---|
| 197 | global_autocompleteLabelsList.sort();
|
---|
| 198 | }
|
---|
| 199 | }
|
---|
| 200 |
|
---|
| 201 | MapEditor.prototype.settingThePath = function () {
|
---|
| 202 | var that = this;
|
---|
| 203 | this.listenersArray = []
|
---|
| 204 | this.counter = 0;
|
---|
| 205 | this.branchNum = 1;
|
---|
| 206 |
|
---|
| 207 | for (var i = 0; i < this.selectedShapes.length * 2; i++) {
|
---|
| 208 | for (var j = 1; j < 6; j++) {
|
---|
| 209 | var path = "//*[@id='map-" + this.id + "']/div/div/div[1]/div[3]/div/div[3]/div[" + this.branchNum + "]/div[" + j + "]/div";
|
---|
| 210 | this.listenersArray[this.counter] = this.getElementByXpath(path);
|
---|
| 211 | if (this.listenersArray[this.counter] !== (undefined || null)) {
|
---|
| 212 | this.listenersArray[this.counter].addEventListener("mousemove", function () {
|
---|
| 213 | that.resizable = true;
|
---|
| 214 | that.shapeResize();
|
---|
| 215 | });
|
---|
| 216 | this.listenersArray[this.counter].addEventListener("mouseout", function () {
|
---|
| 217 | if (this.mouseDown) {
|
---|
| 218 | that.resizable = true;
|
---|
| 219 | that.shapeResize();
|
---|
| 220 |
|
---|
| 221 | }
|
---|
| 222 | });
|
---|
| 223 | }
|
---|
| 224 | this.counter++;
|
---|
| 225 | }
|
---|
| 226 | this.branchNum++;
|
---|
| 227 | }
|
---|
| 228 | }
|
---|
| 229 |
|
---|
| 230 | MapEditor.prototype.shapeResize = function () {
|
---|
| 231 | if (this.mouseState == "down") {
|
---|
| 232 | if (this.selectedShapes.length > 0) {
|
---|
| 233 | if (this.resizable) {
|
---|
| 234 | if (this.dontResize == false) {
|
---|
| 235 | this.mapEditorHistory.historyOverlayPush();
|
---|
| 236 | }
|
---|
| 237 |
|
---|
| 238 | }
|
---|
| 239 | }
|
---|
| 240 | }
|
---|
| 241 | }
|
---|
| 242 |
|
---|
| 243 | MapEditor.prototype.shapeSpecsChangeMD = function () {
|
---|
| 244 | if (this.selectedShapes.length > 0) {
|
---|
| 245 | this.mapEditorHistory.historyOverlayPush();
|
---|
| 246 | }
|
---|
| 247 | }
|
---|
| 248 |
|
---|
| 249 | MapEditor.prototype.shapeSpecsChangeMU = function () {
|
---|
| 250 | if (this.selectedShapes.length > 0) {
|
---|
| 251 | this.mapEditorHistory.presentOverlayPush();
|
---|
| 252 | }
|
---|
| 253 | }
|
---|
| 254 |
|
---|
| 255 | MapEditor.prototype.shapeSpecsChangeOnInput = function () {
|
---|
| 256 | if (this.selectedShapes.length > 0) {
|
---|
| 257 | this.mapEditorHistory.presentOverlayPush();
|
---|
| 258 | }
|
---|
| 259 | }
|
---|
| 260 |
|
---|
| 261 | MapEditor.prototype.makeColorButton = function (color) {
|
---|
| 262 | var that = this;
|
---|
| 263 |
|
---|
| 264 | var button = document.createElement('span');
|
---|
| 265 | button.className = 'color-buttons1';
|
---|
| 266 | button.style.backgroundColor = color;
|
---|
| 267 | google.maps.event.addDomListener(button, 'click', function () {
|
---|
| 268 | that.selectColor(color);
|
---|
| 269 | that.setSelectedShapeColor(color);
|
---|
| 270 | that.shapeSpecsChangeMU();
|
---|
| 271 | });
|
---|
| 272 | return button;
|
---|
| 273 | }
|
---|
| 274 |
|
---|
| 275 | MapEditor.prototype.buildColorPalette = function () {
|
---|
| 276 | var colorPalette = document.getElementById("color-palette1" + "-" + this.id);
|
---|
| 277 | for (var i = 0; i < this.colors.length; ++i) {
|
---|
| 278 | var currColor = this.colors[i];
|
---|
| 279 | var colorButton = this.makeColorButton(currColor);
|
---|
| 280 | colorPalette.appendChild(colorButton);
|
---|
| 281 | this.colorButtons[currColor] = colorButton;
|
---|
| 282 | }
|
---|
| 283 | this.selectColor(this.colors[0]);
|
---|
| 284 | };
|
---|
| 285 |
|
---|
| 286 | MapEditor.prototype.selectColor = function (color) {
|
---|
| 287 | this.selectedColor = color;
|
---|
| 288 | for (var i = 0; i < this.colors.length; ++i) {
|
---|
| 289 | var currColor = this.colors[i];
|
---|
| 290 | this.colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
|
---|
| 291 | }
|
---|
| 292 |
|
---|
| 293 | // Retrieves the current options from the drawing manager and replaces the
|
---|
| 294 | // stroke or fill color as appropriate.
|
---|
| 295 | var polylineOptions = this.drawingManager.get('polylineOptions');
|
---|
| 296 | polylineOptions.strokeColor = color;
|
---|
| 297 | this.drawingManager.set('polylineOptions', polylineOptions);
|
---|
| 298 |
|
---|
| 299 | var rectangleOptions = this.drawingManager.get('rectangleOptions');
|
---|
| 300 | rectangleOptions.fillColor = color;
|
---|
| 301 | this.drawingManager.set('rectangleOptions', rectangleOptions);
|
---|
| 302 |
|
---|
| 303 | var circleOptions = this.drawingManager.get('circleOptions');
|
---|
| 304 | circleOptions.fillColor = color;
|
---|
| 305 | this.drawingManager.set('circleOptions', circleOptions);
|
---|
| 306 |
|
---|
| 307 | var polygonOptions = this.drawingManager.get('polygonOptions');
|
---|
| 308 | polygonOptions.fillColor = color;
|
---|
| 309 | this.drawingManager.set('polygonOptions', polygonOptions);
|
---|
| 310 | }
|
---|
| 311 |
|
---|
| 312 | MapEditor.prototype.initMapEditor = function () {
|
---|
| 313 | var that = this;
|
---|
| 314 |
|
---|
| 315 | // By default, the map editor will be centred on Waikato Uni at a particular zoom
|
---|
| 316 | this.map = new google.maps.Map(document.getElementById("map-" + this.id), {
|
---|
| 317 | center: {
|
---|
| 318 | lat: -37.7891,
|
---|
| 319 | lng: 175.3180
|
---|
| 320 | },
|
---|
| 321 | zoom: 14,
|
---|
| 322 | mapId: this.id,
|
---|
| 323 | });
|
---|
| 324 |
|
---|
| 325 | // WORK-IN-PROGRESS FEATURE: label on Map (to be changed to a label associated with each shape later)
|
---|
| 326 | // let's associate a label with the map (for now, later associate labels for each shape)
|
---|
| 327 | //this.labelOverlay = new LabelOverlay(this.map);
|
---|
| 328 |
|
---|
| 329 | this.mapsArray.push(this.map);
|
---|
| 330 | // Add a style-selector control to the map.
|
---|
| 331 | var styleControl = document.getElementById('style-selector-control' + "-" + this.id);
|
---|
| 332 | this.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(styleControl);
|
---|
| 333 |
|
---|
| 334 | /*
|
---|
| 335 | // Set the map's style to the initial value of the selector.
|
---|
| 336 | var styleSelector = document.getElementById('style-selector' + "-" + this.id);
|
---|
| 337 | //console.log(styleSelector);
|
---|
| 338 | //map = google.maps.Map(document.getElementById('map' +"-"+ this.id));
|
---|
| 339 | this.map.setOptions({
|
---|
| 340 | styles: styles[styleSelector.value]
|
---|
| 341 |
|
---|
| 342 | });
|
---|
| 343 |
|
---|
| 344 | // Apply new JSON when the user selects a different style.
|
---|
| 345 | styleSelector.addEventListener('change', function () {
|
---|
| 346 | that.map.setOptions({
|
---|
| 347 | styles: styles[styleSelector.value]
|
---|
| 348 | });
|
---|
| 349 | });
|
---|
| 350 | */
|
---|
| 351 |
|
---|
| 352 | this.drawingManager = new google.maps.drawing.DrawingManager({
|
---|
| 353 | //drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
|
---|
| 354 | drawingControl: true,
|
---|
| 355 | drawingControlOptions: {
|
---|
| 356 | position: google.maps.ControlPosition.TOP_CENTER,
|
---|
| 357 | drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
|
---|
| 358 | },
|
---|
| 359 | markerOptions: {
|
---|
| 360 | draggable: true
|
---|
| 361 | },
|
---|
| 362 | circleOptions: this.shapeOptions,
|
---|
| 363 | polylineOptions: this.shapeOptions,
|
---|
| 364 | polygonOptions: this.shapeOptions,
|
---|
| 365 | rectangleOptions: this.shapeOptions,
|
---|
| 366 | });
|
---|
| 367 |
|
---|
| 368 | this.drawingManager.setMap(this.map);
|
---|
| 369 |
|
---|
| 370 | google.maps.event.addListener(this.drawingManager, "drawingmode_changed", function () {
|
---|
| 371 | if (that.shiftKeyPressed != true && that.drawingManager.drawingMode !== null) {
|
---|
| 372 | that.deselectAll();
|
---|
| 373 | }
|
---|
| 374 | that.settingThePath();
|
---|
| 375 |
|
---|
| 376 | })
|
---|
| 377 |
|
---|
| 378 | // store reference to added overlay
|
---|
| 379 | google.maps.event.addListener(this.drawingManager, 'overlaycomplete', function (e) {
|
---|
| 380 | that.allowDeselect = true;
|
---|
| 381 | that.mapEditorHistory.historyOverlayPush();
|
---|
| 382 | that.overlays.push(e.overlay); // store reference to added overlay
|
---|
| 383 | var newShape = e.overlay;
|
---|
| 384 | newShape.type = e.type;
|
---|
| 385 | that.mapEditorHistory.presentOverlayPush();
|
---|
| 386 |
|
---|
| 387 | if (e.type !== google.maps.drawing.OverlayType.MARKER) {
|
---|
| 388 | that.addShapeListeners(newShape, e);
|
---|
| 389 | that.setSelection(newShape, e);
|
---|
| 390 | } else {
|
---|
| 391 | that.addMarkerListeners(newShape, e);
|
---|
| 392 | that.setSelection(newShape, e);
|
---|
| 393 | }
|
---|
| 394 | });
|
---|
| 395 |
|
---|
| 396 | //Clears selection if clicked on the map when shift is not presseed
|
---|
| 397 | google.maps.event.addListener(this.map, 'click', function (e) {
|
---|
| 398 | var c = document.body.childNodes;
|
---|
| 399 | if (e.target && e.target.matches("a.classA")) {
|
---|
| 400 | console.log("Anchor element clicked!");
|
---|
| 401 | }
|
---|
| 402 | if (that.shiftKeyPressed == false) {
|
---|
| 403 | that.clearSelection();
|
---|
| 404 | that.selectedShape = null;
|
---|
| 405 | }
|
---|
| 406 | });
|
---|
| 407 |
|
---|
| 408 | google.maps.event.addListener(this.map, 'mousedown', function (e) {
|
---|
| 409 | that.dontResize = true;
|
---|
| 410 | });
|
---|
| 411 |
|
---|
| 412 | google.maps.event.addListener(this.map, 'mouseup', function (e) {
|
---|
| 413 | that.dontResize = false;
|
---|
| 414 | });
|
---|
| 415 |
|
---|
| 416 | //Keyboard shortcuts
|
---|
| 417 | var mapAndControls = document.getElementById("map-and-controls-" + this.id);
|
---|
| 418 | var thicknessField = document.getElementById ("thicknessRangeVal-" + this.id);
|
---|
| 419 | var opacityField = document.getElementById ("opacityRangeVal-" + this.id);
|
---|
| 420 | var openMapFunction = function() {
|
---|
| 421 | //Sets shift as unpressed
|
---|
| 422 | mapAndControls.addEventListener('keyup', function (event) {
|
---|
| 423 | if (event.keyCode == '16') {
|
---|
| 424 | that.shiftKeyPressed = false;
|
---|
| 425 | }
|
---|
| 426 | });
|
---|
| 427 |
|
---|
| 428 | mapAndControls.addEventListener('keydown', function (event) {
|
---|
| 429 |
|
---|
| 430 | // https://stackoverflow.com/questions/2220196/how-to-decode-character-pressed-from-jquerys-keydowns-event-handler
|
---|
| 431 | var keyCode = String.fromCharCode(event.which);
|
---|
| 432 | //console.log("Key pressed: " + keyCode);
|
---|
| 433 |
|
---|
| 434 | //disable keyboard shortcut within the number input field
|
---|
| 435 | var activeElement = $(document.activeElement);
|
---|
| 436 | if(activeElement.attr('type') == 'number' || activeElement.attr('type') == 'text'){
|
---|
| 437 | //console.log('number detected')
|
---|
| 438 | return;
|
---|
| 439 | }
|
---|
| 440 | //Sets shift as pressed
|
---|
| 441 | if (event.keyCode == '16') {
|
---|
| 442 | that.shiftKeyPressed = true;
|
---|
| 443 | }
|
---|
| 444 | else if (keyCode == 'Y' && (event.ctrlKey || event.metaKey)) {
|
---|
| 445 | that.mapEditorHistory.redo();
|
---|
| 446 | }
|
---|
| 447 | else if (keyCode == 'Z' && (event.ctrlKey || event.metaKey) ) {
|
---|
| 448 | if (that.shiftKeyPressed == false) {
|
---|
| 449 | that.mapEditorHistory.undo();
|
---|
| 450 | }
|
---|
| 451 | }
|
---|
| 452 | else if (keyCode == 'A' && (event.ctrlKey || event.metaKey)) {
|
---|
| 453 | event.preventDefault();
|
---|
| 454 | that.drawingManager.setDrawingMode(null);
|
---|
| 455 | that.selectAll();
|
---|
| 456 | }
|
---|
| 457 | else if (keyCode == 'D' && (event.ctrlKey || event.metaKey)) {
|
---|
| 458 | event.preventDefault();
|
---|
| 459 | that.deselectAll();
|
---|
| 460 | }
|
---|
| 461 |
|
---|
| 462 | else if (keyCode == '0' || keyCode == 'Ã' || (keyCode == 'G'&& (event.ctrlKey || event.metaKey))) {
|
---|
| 463 | event.preventDefault();
|
---|
| 464 | that.drawingManager.setDrawingMode(null);
|
---|
| 465 | } else if (keyCode == '1') {
|
---|
| 466 | that.drawingManager.setDrawingMode('marker');
|
---|
| 467 | } else if (keyCode == '2') {
|
---|
| 468 | that.drawingManager.setDrawingMode('circle');
|
---|
| 469 | } else if (keyCode == '3') {
|
---|
| 470 | that.drawingManager.setDrawingMode('polygon');
|
---|
| 471 | } else if (keyCode == '4') {
|
---|
| 472 | that.drawingManager.setDrawingMode('polyline');
|
---|
| 473 | } else if (keyCode == '5') {
|
---|
| 474 | that.drawingManager.setDrawingMode('rectangle');
|
---|
| 475 | }
|
---|
| 476 |
|
---|
| 477 | //else if (keyCode == 'S') {
|
---|
| 478 | // that.saveToArchives();
|
---|
| 479 | //}
|
---|
| 480 | else if (keyCode == 'Q') { // for debugging information, press Q (easy to hit key)
|
---|
| 481 | that.printHistory();
|
---|
| 482 | }
|
---|
| 483 | else if (keyCode == '.') {
|
---|
| 484 | that.deleteSelectedShapes();
|
---|
| 485 | }
|
---|
| 486 | // console.log(keyCode);
|
---|
| 487 | });
|
---|
| 488 | };
|
---|
| 489 |
|
---|
| 490 | openMapFunction();
|
---|
| 491 |
|
---|
| 492 | this.buildColorPalette();
|
---|
| 493 |
|
---|
| 494 |
|
---|
| 495 | var collection = gs.cgiParams.c;
|
---|
| 496 | var site_name = gs.xsltParams.site_name;
|
---|
| 497 | var nodeID = this.id; // documentID, hopefully contains section ID too
|
---|
| 498 | var metaname = gps_metadata_name;
|
---|
| 499 |
|
---|
| 500 | // collection, site, documentID, metadataName, metadataPosition, responseFunction
|
---|
| 501 | gs.functions.getArchivesMetadata(collection, site_name, nodeID, metaname, 0, function(responseText){
|
---|
| 502 | // responseText is of type GSMetadata
|
---|
| 503 |
|
---|
| 504 | // called when data has been retrieved from archives
|
---|
| 505 | var JSONString = responseText.getValue();
|
---|
| 506 | if(JSONString !== "")
|
---|
| 507 | {
|
---|
| 508 | that.LOAD(JSONString, nodeID);
|
---|
| 509 | that.savedOverlays = JSONString;
|
---|
| 510 |
|
---|
| 511 | // centre on the map's overlays now they're loaded up
|
---|
| 512 | var map_editor = gsmap_store["map-"+nodeID];
|
---|
| 513 | var overlayBounds = ShapesUtil.overlayBounds(map_editor.overlays);
|
---|
| 514 | if(map_editor.overlays.length === 1 && map_editor.overlays[0].type === google.maps.drawing.OverlayType.MARKER) {
|
---|
| 515 | that.map.setCenter(overlayBounds.getCenter());
|
---|
| 516 | that.map.setZoom(18);
|
---|
| 517 | } else {
|
---|
| 518 | that.map.fitBounds(overlayBounds);
|
---|
| 519 | }
|
---|
| 520 | }
|
---|
| 521 | }
|
---|
| 522 | ); // responseFunctions are now in the setMeta calls
|
---|
| 523 | }
|
---|
| 524 |
|
---|
| 525 | //Deletes a vertex if clicked on it
|
---|
| 526 | MapEditor.prototype.vertexAndPolyDel = function (e, newShape) {
|
---|
| 527 | var vertex = e.vertex;
|
---|
| 528 | if (e.vertex !== undefined) {
|
---|
| 529 | if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
|
---|
| 530 | var path = newShape.getPaths().getAt(e.path);
|
---|
| 531 | path.removeAt(e.vertex);
|
---|
| 532 | if (path.length < 3) {
|
---|
| 533 | newShape.setMap(null);
|
---|
| 534 | }
|
---|
| 535 | }
|
---|
| 536 | if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
|
---|
| 537 | var path = newShape.getPath();
|
---|
| 538 | path.removeAt(e.vertex);
|
---|
| 539 | if (path.length < 2) {
|
---|
| 540 | newShape.setMap(null);
|
---|
| 541 | }
|
---|
| 542 | }
|
---|
| 543 | }
|
---|
| 544 | }
|
---|
| 545 |
|
---|
| 546 | MapEditor.prototype.addMarkerListeners = function (newShape, e) {
|
---|
| 547 | var that = this;
|
---|
| 548 | //Click event if a marker is created
|
---|
| 549 | google.maps.event.addListener(newShape, 'click', function (e) {
|
---|
| 550 | if(that.shiftKeyPressed){
|
---|
| 551 |
|
---|
| 552 | } else {
|
---|
| 553 | that.mapEditorHistory.historyOverlayPush();
|
---|
| 554 | //newShape.setMap(null);
|
---|
| 555 | that.mapEditorHistory.presentOverlayPush();
|
---|
| 556 | }
|
---|
| 557 |
|
---|
| 558 | });
|
---|
| 559 |
|
---|
| 560 | google.maps.event.addListener(newShape, 'dragstart', function (e) {
|
---|
| 561 | that.beingDragged = true;
|
---|
| 562 | that.mapEditorHistory.historyOverlayPush();
|
---|
| 563 |
|
---|
| 564 | });
|
---|
| 565 |
|
---|
| 566 | google.maps.event.addListener(newShape, 'dragend', function () {
|
---|
| 567 | that.beingDragged = false;
|
---|
| 568 | that.mapEditorHistory.presentOverlayPush();
|
---|
| 569 | that.allowDeselect = false;
|
---|
| 570 | });
|
---|
| 571 | }
|
---|
| 572 |
|
---|
| 573 | MapEditor.prototype.addShapeListeners = function (newShape, e) {
|
---|
| 574 | var that = this;
|
---|
| 575 | // Add an event listener that selects the newly-drawn shape when the user
|
---|
| 576 | // mouses down on it.
|
---|
| 577 | google.maps.event.addListener(newShape, 'click', function (e) {
|
---|
| 578 | that.vertexAndPolyDel(e, newShape);
|
---|
| 579 | });
|
---|
| 580 |
|
---|
| 581 | google.maps.event.addListener(newShape, 'dragstart', function (e) {
|
---|
| 582 | that.allowDeselect = false;
|
---|
| 583 | that.mapEditorHistory.historyOverlayPush();
|
---|
| 584 | });
|
---|
| 585 |
|
---|
| 586 | google.maps.event.addListener(newShape, 'dragend', function () {
|
---|
| 587 | that.beingDragged = false;
|
---|
| 588 | that.mapEditorHistory.presentOverlayPush();
|
---|
| 589 | that.settingThePath();
|
---|
| 590 |
|
---|
| 591 | that.allowDeselect = false;
|
---|
| 592 | that.setSelection(newShape, e);
|
---|
| 593 | });
|
---|
| 594 |
|
---|
| 595 | //Store information after the event ends
|
---|
| 596 | google.maps.event.addListener(newShape, 'bounds_changed', function (e) {
|
---|
| 597 | if (that.beingDragged == false) {
|
---|
| 598 | that.mapEditorHistory.presentOverlayPush();
|
---|
| 599 | }
|
---|
| 600 | });
|
---|
| 601 |
|
---|
| 602 | //Add an event listener to select a shape if the mouse hovers over it
|
---|
| 603 | google.maps.event.addListener(newShape, 'mousedown', function (e) {
|
---|
| 604 | if (e.target && e.target.matches("a.classA")) {
|
---|
| 605 | console.log("Anchor element clicked!");
|
---|
| 606 | }
|
---|
| 607 | if (e.vertex !== undefined || e.edge !== undefined) {
|
---|
| 608 | that.mapEditorHistory.historyOverlayPush()
|
---|
| 609 | }
|
---|
| 610 | if (that.drawingManager.drawingMode == null) {
|
---|
| 611 | that.setSelection(newShape, e);
|
---|
| 612 | }
|
---|
| 613 | });
|
---|
| 614 |
|
---|
| 615 | google.maps.event.addListener(newShape, 'mouseup', function (e) {
|
---|
| 616 | if (e.vertex !== undefined || e.edge !== undefined) {
|
---|
| 617 | that.mapEditorHistory.presentOverlayPush()
|
---|
| 618 | } else {
|
---|
| 619 | //that.setSelection(newShape, e);
|
---|
| 620 | }
|
---|
| 621 |
|
---|
| 622 | });
|
---|
| 623 | }
|
---|
| 624 | MapEditor.prototype.clearSelection = function () {
|
---|
| 625 | if (this.selectedShape) {
|
---|
| 626 | if (this.shiftKeyPressed == false) {
|
---|
| 627 | for (var i = 0; i < this.selectedShapes.length; i++) {
|
---|
| 628 | if(this.selectedShapes[i].type !== 'marker') {
|
---|
| 629 | this.selectedShapes[i].setEditable(false);
|
---|
| 630 | }
|
---|
| 631 | }
|
---|
| 632 | this.selectedShapes = [];
|
---|
| 633 | }
|
---|
| 634 | this.selectedShape = null;
|
---|
| 635 | }
|
---|
| 636 | }
|
---|
| 637 |
|
---|
| 638 | //Set selection for the selected overlay
|
---|
| 639 | MapEditor.prototype.setSelection = function (shape, e) {
|
---|
| 640 | //var that = this;
|
---|
| 641 | if (shape.type !== 'marker') {
|
---|
| 642 | if (this.shiftKeyPressed == false) {
|
---|
| 643 | if (e !== null) {
|
---|
| 644 | if (e.vertex == undefined) {
|
---|
| 645 | if (e.edge == undefined) {
|
---|
| 646 | this.clearSelection();
|
---|
| 647 | shape.setEditable(true);
|
---|
| 648 | }
|
---|
| 649 | }
|
---|
| 650 | }
|
---|
| 651 | }
|
---|
| 652 | if (this.selectedShapes.includes(shape)) {
|
---|
| 653 | if (e !== null) {
|
---|
| 654 | if (e.vertex == undefined) {
|
---|
| 655 | if (e.edge == undefined) {
|
---|
| 656 | this.allowDeselect = true;
|
---|
| 657 | this.removeFromSelectedShapes(shape);
|
---|
| 658 | }
|
---|
| 659 | }
|
---|
| 660 | }
|
---|
| 661 | } else {
|
---|
| 662 | this.allowDeselect = false;
|
---|
| 663 | shape.setEditable(true);
|
---|
| 664 | this.selectedShapes.push(shape);
|
---|
| 665 | }
|
---|
| 666 |
|
---|
| 667 | //Send the values to be updated
|
---|
| 668 | var thi = shape.strokeWeight;
|
---|
| 669 | var opa = shape.fillOpacity;
|
---|
| 670 | var fCol = shape.fillColor;
|
---|
| 671 | var sCol = shape.strokeColor;
|
---|
| 672 | var description = shape.description;
|
---|
| 673 | this.updateMenuValues(thi, opa, fCol, sCol, description);
|
---|
| 674 |
|
---|
| 675 | } else if (shape.type == 'marker') {
|
---|
| 676 | this.allowDeselect = false;
|
---|
| 677 | this.selectedShapes.push(shape);
|
---|
| 678 | }
|
---|
| 679 | this.selectedShape = shape;
|
---|
| 680 | this.settingThePath();
|
---|
| 681 | }
|
---|
| 682 |
|
---|
| 683 | MapEditor.prototype.removeFromSelectedShapes = function (shape) {
|
---|
| 684 | if (this.selectedShapes.includes(shape)) {
|
---|
| 685 | if (this.allowDeselect) {
|
---|
| 686 | const index = this.selectedShapes.indexOf(shape);
|
---|
| 687 | this.selectedShapes.splice(index, 1);
|
---|
| 688 | shape.setEditable(false);
|
---|
| 689 | }
|
---|
| 690 | this.allowDeselect = true;
|
---|
| 691 | }
|
---|
| 692 | }
|
---|
| 693 |
|
---|
| 694 | //Set selected label
|
---|
| 695 | MapEditor.prototype.setSelectedDescription = function (label) {
|
---|
| 696 | if (this.selectedShapes.length > 0) {
|
---|
| 697 | for (var i = 0; i < this.selectedShapes.length; i++) {
|
---|
| 698 | this.selectedShapes[i].set('description', label); //SAME: this.selectedShapes[i].description = label;
|
---|
| 699 | }
|
---|
| 700 | }
|
---|
| 701 | }
|
---|
| 702 |
|
---|
| 703 | //Set selected thickness
|
---|
| 704 | MapEditor.prototype.setSelectedThickness = function (sWeight) {
|
---|
| 705 | if (this.selectedShapes.length > 0) {
|
---|
| 706 | for (var i = 0; i < this.selectedShapes.length; i++) {
|
---|
| 707 | this.selectedShapes[i].set('strokeWeight', sWeight);
|
---|
| 708 | }
|
---|
| 709 | }
|
---|
| 710 | }
|
---|
| 711 |
|
---|
| 712 | //Set selected opacity
|
---|
| 713 | MapEditor.prototype.setSelectedOpacity = function (fOpacity) {
|
---|
| 714 |
|
---|
| 715 | if (this.selectedShapes.length > 0) {
|
---|
| 716 | for (var i = 0; i < this.selectedShapes.length; i++) {
|
---|
| 717 | this.selectedShapes[i].set('fillOpacity', fOpacity);
|
---|
| 718 | }
|
---|
| 719 | }
|
---|
| 720 | }
|
---|
| 721 |
|
---|
| 722 | //set selected fill colour
|
---|
| 723 | MapEditor.prototype.setSelectedShapeColor = function (color) {
|
---|
| 724 | if (this.selectedShapes.length > 0) {
|
---|
| 725 | for (var i = 0; i < this.selectedShapes.length; i++) {
|
---|
| 726 | this.selectedShapes[i].set('fillColor', color);
|
---|
| 727 | this.selectedShapes[i].set('strokeColor', color);
|
---|
| 728 | }
|
---|
| 729 | }
|
---|
| 730 | }
|
---|
| 731 |
|
---|
| 732 | MapEditor.prototype.getElementByXpath = function (path) {
|
---|
| 733 | return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
|
---|
| 734 | }
|
---|
| 735 |
|
---|
| 736 | MapEditor.prototype.updateMenuValues = function (thi, opa, fCol, sCol, description) {
|
---|
| 737 | //Update thickness slider and value on the settings menu
|
---|
| 738 | var thicknessSliderOutput = document.getElementById("thicknessRangeVal" + "-" + this.id);
|
---|
| 739 | // update the thickness innerHTML's value to always have 2 decimal places, https://www.w3schools.com/js/js_number_methods.asp
|
---|
| 740 | thi = parseFloat(thi); //Ensure the thi is a number
|
---|
| 741 | thicknessSliderOutput.value = thi.toFixed(2);
|
---|
| 742 | document.getElementById("thicknessRange" + "-" + this.id).value = Math.round((thi * 20) * 100) / 100;
|
---|
| 743 |
|
---|
| 744 | //Update the opacity slider and value on the settings menu
|
---|
| 745 | var opacitySliderOutput = document.getElementById("opacityRangeVal" + "-" + this.id);
|
---|
| 746 | opacitySliderOutput.value = opa * 100;
|
---|
| 747 | document.getElementById("colourOpacity" + "-" + this.id).value = opa * 100;
|
---|
| 748 |
|
---|
| 749 | // Show the description in the description field
|
---|
| 750 | var descriptionInput = document.getElementById("description" + "-" + this.id);
|
---|
| 751 | descriptionInput.value = description;
|
---|
| 752 |
|
---|
| 753 | if (this.drawingManager.drawingMode == null) {
|
---|
| 754 | this.selectColor(fCol);
|
---|
| 755 | }
|
---|
| 756 | }
|
---|
| 757 | MapEditor.prototype.selectAll = function () {
|
---|
| 758 | this.shiftKeyPressed = true;
|
---|
| 759 | var e = new Object();
|
---|
| 760 | e.vertex = undefined;
|
---|
| 761 | this.selectedShapes = [];
|
---|
| 762 | for (var i = 0; i < this.overlays.length; i++) {
|
---|
| 763 | this.setSelection(this.overlays[i], e);
|
---|
| 764 | }
|
---|
| 765 | this.shiftKeyPressed = false;
|
---|
| 766 | }
|
---|
| 767 | MapEditor.prototype.deselectAll = function () {
|
---|
| 768 | for (var i = 0; i < this.selectedShapes.length; i++) {
|
---|
| 769 | if (this.selectedShapes[i].type !== google.maps.drawing.OverlayType.MARKER) {
|
---|
| 770 | this.selectedShapes[i].setEditable(false);
|
---|
| 771 | }
|
---|
| 772 |
|
---|
| 773 | }
|
---|
| 774 | this.selectedShapes = [];
|
---|
| 775 | }
|
---|
| 776 |
|
---|
| 777 | // event handler for s being pressed *when map editor has the focus*
|
---|
| 778 | // For saving and rebuilding, see map_scripts
|
---|
| 779 | MapEditor.prototype.saveToArchives = function () {
|
---|
| 780 | var that = this;
|
---|
| 781 | console.log("Save pressed");
|
---|
| 782 |
|
---|
| 783 | var json_overlays = JSON.stringify(ShapesUtil.overlayToJSON(this.overlays));
|
---|
| 784 | that.savedOverlays = json_overlays; // save the old version to compare with future changes
|
---|
| 785 | var collection = gs.cgiParams.c;
|
---|
| 786 | var site_name = gs.xsltParams.site_name;
|
---|
| 787 | var nodeID = this.id; // documentID, hopefully contains section ID too
|
---|
| 788 | var metaname = "GPS.mapOverlay";
|
---|
| 789 |
|
---|
| 790 | // collection, site, documentID, metadataName, metadataPosition, metadataValue, prevMetadataValue, metamode, responseFunction
|
---|
| 791 | gs.functions.setArchivesMetadata(collection, site_name, nodeID, metaname, 0, json_overlays, null, "override", function(){
|
---|
| 792 | console.log("SAVED");
|
---|
| 793 | }
|
---|
| 794 | );
|
---|
| 795 | }
|
---|
| 796 |
|
---|
| 797 | // TODO: When finished testing, can remove this debug function that just prints to console
|
---|
| 798 | MapEditor.prototype.printHistory = function () {
|
---|
| 799 | console.log("prev", this.mapEditorHistory.prevOverlays);
|
---|
| 800 | console.log("present ", this.mapEditorHistory.presentOverlays);
|
---|
| 801 | console.log("undone ", this.mapEditorHistory.undoneOverlays);
|
---|
| 802 | console.log("@@@@ allShapes: ", this.overlays);
|
---|
| 803 | console.log("@@@@ selectedShapes: ", this.selectedShapes);
|
---|
| 804 | }
|
---|
| 805 |
|
---|
| 806 | // to be called after reading back in stored JSON from archives meta
|
---|
| 807 | MapEditor.prototype.LOAD = function (json_str, nodeID) {
|
---|
| 808 | this.mapEditorHistory.historyOverlayPush();
|
---|
| 809 |
|
---|
| 810 | // This seems to convert the map_store object into an array and forces array index access, instead of convenient property access using nodeID
|
---|
| 811 | //Object.values(gsmap_store)[0]; // Always gets top level section's map-editor, not what we want.
|
---|
| 812 |
|
---|
| 813 | // Get the map editor for the nodeID, as we're asked to load that editor
|
---|
| 814 | var map_editor = gsmap_store["map-"+nodeID];
|
---|
| 815 |
|
---|
| 816 | var new_overlays = ShapesUtil.JSONToOverlays(json_str);
|
---|
| 817 | for (var i=0; i<map_editor.overlays.length; i++) {
|
---|
| 818 | map_editor.overlays[i].setMap(null);
|
---|
| 819 | }
|
---|
| 820 |
|
---|
| 821 | map_editor.overlays = new_overlays;
|
---|
| 822 |
|
---|
| 823 | for (var i=0; i<map_editor.overlays.length; i++) {
|
---|
| 824 | var shape = map_editor.overlays[i];
|
---|
| 825 |
|
---|
| 826 | // set up the autocomplete list using saved labels/descriptions
|
---|
| 827 | map_editor.addToAutocompleteLabelsList(shape.description); // now efficiently ensures uniqueness of values using (hash)map
|
---|
| 828 |
|
---|
| 829 | // make the shapes selectable on load:
|
---|
| 830 | if (ShapesUtil.overlayItemIsShape(shape)) {
|
---|
| 831 | map_editor.addShapeListeners(shape, null); // don't have an overlay event!
|
---|
| 832 | } else {
|
---|
| 833 | map_editor.addMarkerListeners(shape, null); // don't have an overlay event!
|
---|
| 834 | }
|
---|
| 835 | shape.setMap(map_editor.map);
|
---|
| 836 | }
|
---|
| 837 |
|
---|
| 838 | this.mapEditorHistory.presentOverlayPush();
|
---|
| 839 | }
|
---|
| 840 |
|
---|
| 841 | MapEditor.prototype.deleteSelectedShapes = function () {
|
---|
| 842 | if(this.selectedShapes.length !== 0) {
|
---|
| 843 | this.mapEditorHistory.historyOverlayPush();
|
---|
| 844 | for (var i = 0; i < this.selectedShapes.length; i++) {
|
---|
| 845 | this.selectedShapes[i].setMap(null);
|
---|
| 846 |
|
---|
| 847 | if (this.overlays.includes(this.selectedShapes[i])) {
|
---|
| 848 | const index = this.overlays.indexOf(this.selectedShapes[i]);
|
---|
| 849 | this.overlays.splice(index, 1);
|
---|
| 850 | // this.selectedShapes[i].setEditable(false);
|
---|
| 851 | }
|
---|
| 852 | }
|
---|
| 853 | this.selectedShapes = [];
|
---|
| 854 | this.mapEditorHistory.presentOverlayPush();
|
---|
| 855 | }
|
---|
| 856 | }
|
---|
| 857 |
|
---|
| 858 | MapEditor.prototype.draggableState = function () {
|
---|
| 859 |
|
---|
| 860 | var draggableCB = document.querySelector("input[name=draggableCB]");
|
---|
| 861 | draggableCB.addEventListener('change', function () {
|
---|
| 862 | if (this.checked) {
|
---|
| 863 | this.overlays.draggable = false;
|
---|
| 864 | } else {
|
---|
| 865 | this.overlays.draggable = false;
|
---|
| 866 | }
|
---|
| 867 | });
|
---|
| 868 | }
|
---|
| 869 |
|
---|
| 870 | MapEditor.prototype.deleteAllShapes = function () {
|
---|
| 871 | if(this.overlays.length !== 0) {
|
---|
| 872 | //console.log("deleteAllShape() this.id = " + this.id);
|
---|
| 873 | this.mapEditorHistory.historyOverlayPush();
|
---|
| 874 | for (var i = 0; i < this.overlays.length; i++) {
|
---|
| 875 | this.overlays[i].setMap(null);
|
---|
| 876 | }
|
---|
| 877 | this.overlays = [];
|
---|
| 878 | this.mapEditorHistory.presentOverlayPush();
|
---|
| 879 | }
|
---|
| 880 | }
|
---|
| 881 |
|
---|
| 882 | // Global function that uses jquery to set the autocomplete list's data source to whatever's in our global autocomplete labels array
|
---|
| 883 | $(function setupAutocompleteLabelsList() {
|
---|
| 884 | // Overrides the default autocomplete filter function to
|
---|
| 885 | // search only from the beginning of the string
|
---|
| 886 | //resource: https://miroslavpopovic.com/posts/2012/06/jqueryui-autocomplete-filter-words-starting-with-term
|
---|
| 887 | $.ui.autocomplete.filter = function (array, term) {
|
---|
| 888 | var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(term), "i");
|
---|
| 889 | return $.grep(array, function (value) {
|
---|
| 890 | return matcher.test(value.label || value.value || value);
|
---|
| 891 | });
|
---|
| 892 | };
|
---|
| 893 |
|
---|
| 894 | $(".description").autocomplete({
|
---|
| 895 | source: global_autocompleteLabelsList
|
---|
| 896 | });
|
---|
| 897 | });
|
---|