From bc4d266b6a3a1c32ee3f09f9326d9d8ef7f555c3 Mon Sep 17 00:00:00 2001 From: Tam Date: Thu, 25 Jan 2018 22:35:58 +0000 Subject: [PATCH 1/5] Use `afterInstall` in favour of after plugin install event --- src/SimpleMap.php | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/SimpleMap.php b/src/SimpleMap.php index e58b3b9..822b0ac 100644 --- a/src/SimpleMap.php +++ b/src/SimpleMap.php @@ -59,18 +59,11 @@ public function init () // Field Types Event::on( - Fields::className(), + Fields::class, Fields::EVENT_REGISTER_FIELD_TYPES, [$this, 'onRegisterFieldTypes'] ); - // Redirect to settings after install - Event::on( - Plugins::className(), - Plugins::EVENT_AFTER_INSTALL_PLUGIN, - [$this, 'onAfterInstallPlugin'] - ); - // Variable Event::on( CraftVariable::class, @@ -90,6 +83,18 @@ public function init () } } + public function afterInstall () + { + parent::afterInstall(); + + if (Craft::$app->getRequest()->getIsConsoleRequest()) + return; + + Craft::$app->getResponse()->redirect( + UrlHelper::cpUrl('settings/plugins/simplemap') + )->send(); + } + // Craft: Settings // ------------------------------------------------------------------------- @@ -124,16 +129,6 @@ public function onRegisterFieldTypes (RegisterComponentTypesEvent $event) $event->types[] = MapField::class; } - public function onAfterInstallPlugin (PluginEvent $event) - { - if (!Craft::$app->getRequest()->getIsConsoleRequest() - && ($event->plugin === $this)) { - Craft::$app->getResponse()->redirect( - UrlHelper::cpUrl('settings/plugins/simplemap') - )->send(); - } - } - public function onRegisterVariable (Event $event) { /** @var CraftVariable $variable */ From b373b004c687c16c00585b8153dfecfb2088d009 Mon Sep 17 00:00:00 2001 From: Tam Date: Thu, 25 Jan 2018 22:49:06 +0000 Subject: [PATCH 2/5] Fixed map height jumping on page load --- CHANGELOG.md | 7 +++++++ composer.json | 2 +- src/fields/MapField.php | 1 + src/templates/field-input.twig | 6 +++++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80a864c..1a972fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 3.2.1 - WIP +### Improved +- Map height no longer jumps when page loads + +### Changed +- Now using the plugins `afterInstall` function in favour of the plugin after install event + ## 3.2.0 - 2018-01-25 ### Fixed - Fixed bug where pagination would error when querying via a map field. #70 diff --git a/composer.json b/composer.json index 1df6103..e2ad749 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "ether/simplemap", "description": "A beautifully simple Google Map field type.", - "version": "3.2.0", + "version": "3.2.1", "type": "craft-plugin", "license": "MIT", "minimum-stability": "dev", diff --git a/src/fields/MapField.php b/src/fields/MapField.php index 563bae9..b2c1439 100644 --- a/src/fields/MapField.php +++ b/src/fields/MapField.php @@ -491,6 +491,7 @@ public function getInputHtml ( 'name' => $this->handle, 'value' => $value, 'field' => $this, + 'height'=> $this->height, ] ); } diff --git a/src/templates/field-input.twig b/src/templates/field-input.twig index 397114c..66bdd97 100644 --- a/src/templates/field-input.twig +++ b/src/templates/field-input.twig @@ -22,7 +22,11 @@ {% if not field.hideMap %} -
+
{% endif %} Date: Sun, 28 Jan 2018 20:24:04 +0000 Subject: [PATCH 3/5] Started settings re-work --- CHANGELOG.md | 4 +- README.md | 4 +- resources/.buildrc | 21 ++ resources/{ => imgs}/banner.jpg | Bin resources/{ => imgs}/preview.png | Bin resources/js/Helpers.js | 44 ++++ resources/js/SimpleMapSettings.js | 238 +++++++++++++++++++++ src/fields/MapField.php | 81 +++++-- src/resources/MapSettingsAsset.php | 33 +++ src/resources/SimpleMapSettings.css | 57 +++++ src/resources/SimpleMapSettings.min.js | 2 + src/resources/SimpleMapSettings.min.js.map | 1 + src/templates/field-settings.twig | 173 ++++++--------- src/translations/en/simplemap.php | 21 +- 14 files changed, 539 insertions(+), 140 deletions(-) create mode 100644 resources/.buildrc rename resources/{ => imgs}/banner.jpg (100%) rename resources/{ => imgs}/preview.png (100%) create mode 100644 resources/js/Helpers.js create mode 100644 resources/js/SimpleMapSettings.js create mode 100644 src/resources/MapSettingsAsset.php create mode 100644 src/resources/SimpleMapSettings.css create mode 100644 src/resources/SimpleMapSettings.min.js create mode 100644 src/resources/SimpleMapSettings.min.js.map diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a972fe..97e849f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,11 @@ ## 3.2.1 - WIP ### Improved - Map height no longer jumps when page loads +- Vastly improved the map fields settings UI/UX ### Changed -- Now using the plugins `afterInstall` function in favour of the plugin after install event +- Now using the plugins `afterInstall` function instead of the plugin after install event +- The "Hide Lat/Lng" option is now true by default ## 3.2.0 - 2018-01-25 ### Fixed diff --git a/README.md b/README.md index 5bc01d8..cfa9358 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![SimpleMap](resources/banner.jpg) +![SimpleMap](resources/imgs/banner.jpg) # SimpleMap A beautifully simple Google Map field type for **Craft 3**. Full localization support, compatible with Matrix & [CraftQL](https://github.com/markhuot/craftql), supports @@ -6,7 +6,7 @@ searching by location and sorting by distance. [Click here for the **Craft 2.5** version.](https://github.com/ethercreative/simplemap/tree/v2) -![How it looks](resources/preview.png) +![How it looks](resources/imgs/preview.png) ## Usage Create the field as you would any other. diff --git a/resources/.buildrc b/resources/.buildrc new file mode 100644 index 0000000..e8ecaa0 --- /dev/null +++ b/resources/.buildrc @@ -0,0 +1,21 @@ +{ + "less": { + "ignore": true, + "input": "public/assets/less/style.less", + "output": "public/assets/css", + "watch": [ + "public/assets/less/**/*" + ] + }, + "js": { + "ignore": false, + "input": "./js/SimpleMapSettings.js", + "output": "../src/resources/SimpleMapSettings.min.js", + "watch": [ + "./js/**/*.js" + ] + }, + "browserSync": { + "ignore": true + } +} \ No newline at end of file diff --git a/resources/banner.jpg b/resources/imgs/banner.jpg similarity index 100% rename from resources/banner.jpg rename to resources/imgs/banner.jpg diff --git a/resources/preview.png b/resources/imgs/preview.png similarity index 100% rename from resources/preview.png rename to resources/imgs/preview.png diff --git a/resources/js/Helpers.js b/resources/js/Helpers.js new file mode 100644 index 0000000..9689a7d --- /dev/null +++ b/resources/js/Helpers.js @@ -0,0 +1,44 @@ +/* globals google */ + +/** + * Load the google API into the dom + * + * @param {string} key - Google Maps API key + * @param {string} locale - The locale + * @static + */ +export const loadGoogleAPI = function (key, locale) { + window.simpleMapsLoadingGoogle = true; + + const gmjs = document.createElement("script"); + gmjs.type = "text/javascript"; + gmjs.src = "https://www.google.com/jsapi?key=" + key; + gmjs.onreadystatechange = function () { + loadMapsApi(key, locale); + }; + gmjs.onload = function () { + loadMapsApi(key, locale); + }; + document.body.appendChild(gmjs); +}; + +/** + * Load the google maps API into the dom + * + * @param {string} key - Google Maps API key + * @param {string} locale - The locale + * @static + */ +export const loadMapsApi = function (key, locale) { + google.load("maps", "3", { + other_params: [ + "libraries=places", + `key=${key}`, + `language=${locale.replace("_", "-")}`, + `region=${locale}`, + ].join("&"), + callback: function () { + document.dispatchEvent(new Event("SimpleMapsGAPILoaded")); + } + }); +}; \ No newline at end of file diff --git a/resources/js/SimpleMapSettings.js b/resources/js/SimpleMapSettings.js new file mode 100644 index 0000000..4e63307 --- /dev/null +++ b/resources/js/SimpleMapSettings.js @@ -0,0 +1,238 @@ +/* globals google, $ */ + +import { loadGoogleAPI, loadMapsApi } from "./Helpers"; + +class SimpleMapSettings { + + // Variables + // ========================================================================= + + namespacedId = null; + mapSettings = { + lat: 51.272154, + lng: 0.514951, + zoom: 15, + height: 400, + boundary: { + nw: { lat: 0, lng: 0 }, + se: { lat: 0, lng: 0 }, + } + }; + + setup = false; + inputs = null; + + settingsMap = null; + settingsMapEl = null; + settingsMapWrap = null; + + boundaryMap = null; + + mouseMoveLastPos = 0; + nextHeight = 0; + + // SimpleMapSettings + // ========================================================================= + + constructor (key, locale, namespacedId, mapSettings) { + this.namespacedId = namespacedId; + this.mapSettings = Object.keys(mapSettings).reduce((a, b) => { + a[b] = +mapSettings[b]; + return a; + }, {}); + + this.inputs = { + lat: document.getElementById(`${this.namespacedId}lat`), + lng: document.getElementById(`${this.namespacedId}lng`), + zoom: document.getElementById(`${this.namespacedId}zoom`), + height: document.getElementById(`${this.namespacedId}height`), + }; + + // Load Google APIs if they aren"t already + if (typeof google === "undefined") { + if (!window.simpleMapsLoadingGoogle) + loadGoogleAPI(key, locale); + } else if (!google.maps || !google.maps.places) { + // Load Google Maps APIs if the aren"t already + if (!window.simpleMapsLoadingGoogle) + loadMapsApi(key, locale); + } else { + if (!this.setup) + this.setupMaps(); + } + + document.addEventListener("SimpleMapsGAPILoaded", () => { + if (!this.setup) + this.setupMaps(); + }); + + // Re-draw the maps when the type select changes + // (otherwise the maps will be grey) + document.getElementById("type").addEventListener("change", e => { + if (e.target.value === "ether\\simplemap\\fields\\MapField") + this.redrawMaps(); + }); + + $(`#${this.namespacedId}hideMap`).on("change", this.onHideMapToggle); + } + + // Events + // ========================================================================= + + // Events: Settings Map + // ------------------------------------------------------------------------- + + onHideMapToggle = e => { + const shouldHide = !!e.target.getElementsByTagName("input")[0].value; + + if (shouldHide) { + const nextMaxHeight = + this.settingsMapWrap.getBoundingClientRect().height + "px"; + + if (nextMaxHeight !== 0) + this.settingsMapWrap.style.maxHeight = nextMaxHeight; + } + + setTimeout(() => { + this.settingsMapWrap + .classList[shouldHide ? "add" : "remove"]("hide"); + }, 1); + }; + + onSettingsMapReposition = () => { + this.inputs.lng.value = this.settingsMap.center.lng(); + this.inputs.lat.value = this.settingsMap.center.lat(); + }; + + onSettingsMapZoom = () => { + this.inputs.zoom.value = this.settingsMap.getZoom(); + }; + + onResizeMouseDown = e => { + e.preventDefault(); + + this.mouseMoveLastPos = e.clientY; + this.nextHeight = this.mapSettings.height; + + this.settingsMapEl.style.pointerEvents = "none"; + this.settingsMapWrap.style.maxHeight = ''; + + document.addEventListener("mousemove", this.onResizeMouseMove); + document.addEventListener("mouseup", this.onResizeMouseUp); + }; + + onResizeMouseMove = e => { + this.nextHeight = this.nextHeight + (e.clientY - this.mouseMoveLastPos); + this.mouseMoveLastPos = e.clientY; + + if (this.nextHeight < 250) + return; + + requestAnimationFrame(() => { + this.mapSettings.height = this.nextHeight; + this.inputs.height.value = this.nextHeight; + this.settingsMapEl.style.height = `${this.nextHeight}px`; + + const c = this.settingsMap.getCenter(); + + google.maps.event.trigger(this.settingsMap, "resize"); + this.settingsMap.setCenter(c); + }); + }; + + onResizeMouseUp = () => { + this.settingsMapEl.style.pointerEvents = ""; + document.removeEventListener("mousemove", this.onResizeMouseMove); + document.removeEventListener("mouseup", this.onResizeMouseUp); + }; + + // Actions + // ========================================================================= + + setupMaps () { + + this.setup = true; + + // Settings Map + // --------------------------------------------------------------------- + + this.settingsMapEl = + document.getElementById(`${this.namespacedId}settingsMap`); + this.settingsMapWrap = + document.getElementById(`${this.namespacedId}settingsMapWrap`); + + this.settingsMap = new google.maps.Map(this.settingsMapEl, { + zoom: this.mapSettings.zoom, + center: new google.maps.LatLng( + this.mapSettings.lat, + this.mapSettings.lng + ), + scrollwheel: false, + fullscreenControl: false, + mapTypeControl: false, + streetViewControl: false, + rotateControl: false, + mapTypeId: google.maps.MapTypeId.ROADMAP, + }); + + google.maps.event.addListener( + this.settingsMap, + 'dragend', + this.onSettingsMapReposition + ); + + google.maps.event.addListener( + this.settingsMap, + 'zoom_changed', + this.onSettingsMapZoom + ); + + // Resizer + document.getElementById(`${this.namespacedId}settingsMapHeight`) + .addEventListener("mousedown", this.onResizeMouseDown); + + // Boundary Map + // --------------------------------------------------------------------- + + const boundaryMapEl = + document.getElementById(`${this.namespacedId}boundaryMap`); + + // TODO: If we have boundaries, position the map to contain them. + // TODO: Add [Clear] button + + this.boundaryMap = new google.maps.Map(boundaryMapEl, { + zoom: this.mapSettings.zoom, + center: new google.maps.LatLng( + this.mapSettings.lat, + this.mapSettings.lng + ), + scrollwheel: false, + fullscreenControl: false, + mapTypeControl: false, + streetViewControl: false, + rotateControl: false, + mapTypeId: google.maps.MapTypeId.ROADMAP, + }); + + } + + redrawMaps () { + const xa = this.settingsMap.getZoom() + , ca = this.settingsMap.getCenter() + , xb = this.boundaryMap.getZoom() + , cb = this.boundaryMap.getCenter(); + + setTimeout(() => { + google.maps.event.trigger(this.settingsMap, 'resize'); + this.settingsMap.setZoom(xa); + this.settingsMap.setCenter(ca); + + google.maps.event.trigger(this.boundaryMap, 'resize'); + this.boundaryMap.setZoom(xb); + this.boundaryMap.setCenter(cb); + }, 1); + } + +} + +window.SimpleMapSettings = SimpleMapSettings; \ No newline at end of file diff --git a/src/fields/MapField.php b/src/fields/MapField.php index b2c1439..6f565ee 100644 --- a/src/fields/MapField.php +++ b/src/fields/MapField.php @@ -7,6 +7,8 @@ use craft\base\Field; use craft\base\PreviewableFieldInterface; use craft\elements\db\ElementQueryInterface; +use craft\helpers\Json; +use ether\simplemap\resources\MapSettingsAsset; use ether\simplemap\resources\SimpleMapAsset; use ether\simplemap\services\MapService; use ether\simplemap\SimpleMap; @@ -50,7 +52,7 @@ class MapField extends Field implements PreviewableFieldInterface /** * @var bool - If true, the lat/lng inputs will not be displayed */ - public $hideLatLng = false; + public $hideLatLng = true; /** * @var string|null - The country to restrict the location search to @@ -418,6 +420,36 @@ public function rules () */ public function getSettingsHtml () { + $view = \Craft::$app->getView(); + $key = SimpleMap::$plugin->getSettings()->apiKey; + $locale = \Craft::$app->locale->id; + $namespacedId = $view->namespaceInputId(''); + $boundary = $this->_getBoundary(); + + if ($boundary === null) { + $emptyLatLng = [ 'lat' => 0, 'lng' => 0 ]; + $boundary = [ + 'nw' => $emptyLatLng, + 'se' => $emptyLatLng, + ]; + } + + $settings = Json::encode([ + 'lat' => $this->lat, + 'lng' => $this->lng, + 'zoom' => $this->zoom, + 'height' => $this->height, + 'boundary' => $boundary, + ]); + + $view->registerAssetBundle(MapSettingsAsset::class); + $view->registerJs("new SimpleMapSettings( + '{$key}', + '{$locale}', + '{$namespacedId}', + {$settings} +);"); + return \Craft::$app->getView()->renderTemplate( 'simplemap/field-settings', [ @@ -443,24 +475,8 @@ public function getInputHtml ( $id = $view->formatInputId($this->handle); $namespacedId = $view->namespaceInputId($id); - if ( - $this->boundaryRestrictionNELat - && $this->boundaryRestrictionNELng - && $this->boundaryRestrictionSWLat - && $this->boundaryRestrictionSWLng - ) { - $ne = [ - 'lat' => $this->boundaryRestrictionNELat, - 'lng' => $this->boundaryRestrictionNELng, - ]; - - $sw = [ - 'lat' => $this->boundaryRestrictionSWLat, - 'lng' => $this->boundaryRestrictionSWLng, - ]; - - $this->boundary = json_encode(['ne' => $ne, 'sw' => $sw]); - } + if ($boundary = $this->_getBoundary()) + $this->boundary = $boundary; $key = SimpleMap::$plugin->getSettings()->apiKey; $locale = $element ? $element->siteId : \Craft::$app->locale->id; @@ -536,4 +552,31 @@ public function afterElementSave (ElementInterface $element, bool $isNew) parent::afterElementSave($element, $isNew); } + // Helpers + // ========================================================================= + + private function _getBoundary () + { + if ( + $this->boundaryRestrictionNELat + && $this->boundaryRestrictionNELng + && $this->boundaryRestrictionSWLat + && $this->boundaryRestrictionSWLng + ) { + $ne = [ + 'lat' => $this->boundaryRestrictionNELat, + 'lng' => $this->boundaryRestrictionNELng, + ]; + + $sw = [ + 'lat' => $this->boundaryRestrictionSWLat, + 'lng' => $this->boundaryRestrictionSWLng, + ]; + + return json_encode(['ne' => $ne, 'sw' => $sw]); + } + + return null; + } + } \ No newline at end of file diff --git a/src/resources/MapSettingsAsset.php b/src/resources/MapSettingsAsset.php new file mode 100644 index 0000000..5a48f28 --- /dev/null +++ b/src/resources/MapSettingsAsset.php @@ -0,0 +1,33 @@ +sourcePath = '@ether/simplemap/resources'; + + $this->depends = [ + CpAsset::class, + ]; + + $this->js = [ + 'SimpleMapSettings.min.js', + ]; + + $this->css = [ + 'SimpleMapSettings.css', + ]; + + parent::init(); + } + +} \ No newline at end of file diff --git a/src/resources/SimpleMapSettings.css b/src/resources/SimpleMapSettings.css new file mode 100644 index 0000000..96d3d91 --- /dev/null +++ b/src/resources/SimpleMapSettings.css @@ -0,0 +1,57 @@ +.simplemap-settings--wrap { + overflow: hidden; + transition: + max-height 0.15s ease, + opacity 0.25s ease, + margin-bottom 0.25s ease; + transition-delay: 0s, 0.1s, 0s; +} +.simplemap-settings--wrap.hide { + max-height: 0 !important; + opacity: 0; + transition-delay: 0.1s, 0s, 0s; + margin-bottom: -24px; +} + +.simplemap-settings--settings-map { + border-radius: 4px 4px 0 0; +} + +.simplemap-settings--resize { + position: relative; + + height: 25px; + + background-color: #ebedef; + border-top: 1px solid #fff; + border-radius: 0 0 4px 4px; + + cursor: ns-resize; + user-select: none; +} + +.simplemap-settings--resize:after { + content: '.. .. .. ..'; + position: absolute; + top: 50%; + left: 50%; + + display: inline-block; + width: 11px; + height: 24px; + vertical-align: middle; + + color: #cccccc; + font-size: 12px; + font-family: sans-serif; + line-height: 5px; + letter-spacing: 2px; + + text-shadow: 1px 0 1px black; + transform: translate3d(-50%, -50%, 0) rotate(90deg); +} + +.simplemap-settings--boundary-map { + height: 500px; + border-radius: 4px; +} \ No newline at end of file diff --git a/src/resources/SimpleMapSettings.min.js b/src/resources/SimpleMapSettings.min.js new file mode 100644 index 0000000..da786df --- /dev/null +++ b/src/resources/SimpleMapSettings.min.js @@ -0,0 +1,2 @@ +var loadGoogleAPI=function(e,t){window.simpleMapsLoadingGoogle=!0;var n=document.createElement("script");n.type="text/javascript",n.src="https://www.google.com/jsapi?key="+e,n.onreadystatechange=function(){loadMapsApi(e,t)},n.onload=function(){loadMapsApi(e,t)},document.body.appendChild(n)},loadMapsApi=function(e,t){google.load("maps","3",{other_params:["libraries=places","key="+e,"language="+t.replace("_","-"),"region="+t].join("&"),callback:function(){document.dispatchEvent(new Event("SimpleMapsGAPILoaded"))}})},classCallCheck=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},createClass=function(){function e(e,t){for(var n=0;n {\n\t\t\ta[b] = +mapSettings[b];\n\t\t\treturn a;\n\t\t}, {});\n\t\t\n\t\tthis.inputs = {\n\t\t\tlat: document.getElementById(`${this.namespacedId}lat`),\n\t\t\tlng: document.getElementById(`${this.namespacedId}lng`),\n\t\t\tzoom: document.getElementById(`${this.namespacedId}zoom`),\n\t\t\theight: document.getElementById(`${this.namespacedId}height`),\n\t\t};\n\t\t\n\t\t// Load Google APIs if they aren\"t already\n\t\tif (typeof google === \"undefined\") {\n\t\t\tif (!window.simpleMapsLoadingGoogle)\n\t\t\t\tloadGoogleAPI(key, locale);\n\t\t} else if (!google.maps || !google.maps.places) {\n\t\t\t// Load Google Maps APIs if the aren\"t already\n\t\t\tif (!window.simpleMapsLoadingGoogle)\n\t\t\t\tloadMapsApi(key, locale);\n\t\t} else {\n\t\t\tif (!this.setup)\n\t\t\t\tthis.setupMaps();\n\t\t}\n\t\t\n\t\tdocument.addEventListener(\"SimpleMapsGAPILoaded\", () => {\n\t\t\tif (!this.setup)\n\t\t\t\tthis.setupMaps();\n\t\t});\n\t\t\n\t\t// Re-draw the maps when the type select changes\n\t\t// (otherwise the maps will be grey)\n\t\tdocument.getElementById(\"type\").addEventListener(\"change\", e => {\n\t\t\tif (e.target.value === \"ether\\\\simplemap\\\\fields\\\\MapField\")\n\t\t\t\tthis.redrawMaps();\n\t\t});\n\t\t\n\t\t$(`#${this.namespacedId}hideMap`).on(\"change\", this.onHideMapToggle);\n\t}\n\t\n\t// Events\n\t// =========================================================================\n\t\n\t// Events: Settings Map\n\t// -------------------------------------------------------------------------\n\t\n\tonHideMapToggle = e => {\n\t\tconst shouldHide = !!e.target.getElementsByTagName(\"input\")[0].value;\n\t\t\n\t\tif (shouldHide) {\n\t\t\tconst nextMaxHeight =\n\t\t\t\tthis.settingsMapWrap.getBoundingClientRect().height + \"px\";\n\t\t\t\n\t\t\tif (nextMaxHeight !== 0)\n\t\t\t\tthis.settingsMapWrap.style.maxHeight = nextMaxHeight;\n\t\t}\n\t\t\n\t\tsetTimeout(() => {\n\t\t\tthis.settingsMapWrap\n\t\t\t\t.classList[shouldHide ? \"add\" : \"remove\"](\"hide\");\n\t\t}, 1);\n\t};\n\t\n\tonSettingsMapReposition = () => {\n\t\tthis.inputs.lng.value = this.settingsMap.center.lng();\n\t\tthis.inputs.lat.value = this.settingsMap.center.lat();\n\t};\n\t\n\tonSettingsMapZoom = () => {\n\t\tthis.inputs.zoom.value = this.settingsMap.getZoom();\n\t};\n\t\n\tonResizeMouseDown = e => {\n\t\te.preventDefault();\n\t\t\n\t\tthis.mouseMoveLastPos = e.clientY;\n\t\tthis.nextHeight = this.mapSettings.height;\n\t\t\n\t\tthis.settingsMapEl.style.pointerEvents = \"none\";\n\t\tthis.settingsMapWrap.style.maxHeight = '';\n\t\t\n\t\tdocument.addEventListener(\"mousemove\", this.onResizeMouseMove);\n\t\tdocument.addEventListener(\"mouseup\", this.onResizeMouseUp);\n\t};\n\t\n\tonResizeMouseMove = e => {\n\t\tthis.nextHeight = this.nextHeight + (e.clientY - this.mouseMoveLastPos);\n\t\tthis.mouseMoveLastPos = e.clientY;\n\t\t\n\t\tif (this.nextHeight < 250)\n\t\t\treturn;\n\t\t\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.mapSettings.height = this.nextHeight;\n\t\t\tthis.inputs.height.value = this.nextHeight;\n\t\t\tthis.settingsMapEl.style.height = `${this.nextHeight}px`;\n\t\t\t\n\t\t\tconst c = this.settingsMap.getCenter();\n\t\t\t\n\t\t\tgoogle.maps.event.trigger(this.settingsMap, \"resize\");\n\t\t\tthis.settingsMap.setCenter(c);\n\t\t});\n\t};\n\t\n\tonResizeMouseUp = () => {\n\t\tthis.settingsMapEl.style.pointerEvents = \"\";\n\t\tdocument.removeEventListener(\"mousemove\", this.onResizeMouseMove);\n\t\tdocument.removeEventListener(\"mouseup\", this.onResizeMouseUp);\n\t};\n\t\n\t// Actions\n\t// =========================================================================\n\t\n\tsetupMaps () {\n\t\t\n\t\tthis.setup = true;\n\t\t\n\t\t// Settings Map\n\t\t// ---------------------------------------------------------------------\n\t\t\n\t\tthis.settingsMapEl =\n\t\t\tdocument.getElementById(`${this.namespacedId}settingsMap`);\n\t\tthis.settingsMapWrap =\n\t\t\tdocument.getElementById(`${this.namespacedId}settingsMapWrap`);\n\t\t\n\t\tthis.settingsMap = new google.maps.Map(this.settingsMapEl, {\n\t\t\tzoom: this.mapSettings.zoom,\n\t\t\tcenter: new google.maps.LatLng(\n\t\t\t\tthis.mapSettings.lat,\n\t\t\t\tthis.mapSettings.lng\n\t\t\t),\n\t\t\tscrollwheel: false,\n\t\t\tfullscreenControl: false,\n\t\t\tmapTypeControl: false,\n\t\t\tstreetViewControl: false,\n\t\t\trotateControl: false,\n\t\t\tmapTypeId: google.maps.MapTypeId.ROADMAP,\n\t\t});\n\t\t\n\t\tgoogle.maps.event.addListener(\n\t\t\tthis.settingsMap,\n\t\t\t'dragend',\n\t\t\tthis.onSettingsMapReposition\n\t\t);\n\t\t\n\t\tgoogle.maps.event.addListener(\n\t\t\tthis.settingsMap,\n\t\t\t'zoom_changed',\n\t\t\tthis.onSettingsMapZoom\n\t\t);\n\t\t\n\t\t// Resizer\n\t\tdocument.getElementById(`${this.namespacedId}settingsMapHeight`)\n\t\t .addEventListener(\"mousedown\", this.onResizeMouseDown);\n\t\t\n\t\t// Boundary Map\n\t\t// ---------------------------------------------------------------------\n\t\t\n\t\tconst boundaryMapEl =\n\t\t\tdocument.getElementById(`${this.namespacedId}boundaryMap`);\n\t\t\n\t\t// TODO: If we have boundaries, position the map to contain them.\n\t\t// TODO: Add [Clear] button\n\t\t\n\t\tthis.boundaryMap = new google.maps.Map(boundaryMapEl, {\n\t\t\tzoom: this.mapSettings.zoom,\n\t\t\tcenter: new google.maps.LatLng(\n\t\t\t\tthis.mapSettings.lat,\n\t\t\t\tthis.mapSettings.lng\n\t\t\t),\n\t\t\tscrollwheel: false,\n\t\t\tfullscreenControl: false,\n\t\t\tmapTypeControl: false,\n\t\t\tstreetViewControl: false,\n\t\t\trotateControl: false,\n\t\t\tmapTypeId: google.maps.MapTypeId.ROADMAP,\n\t\t});\n\t\t\n\t}\n\t\n\tredrawMaps () {\n\t\tconst xa = this.settingsMap.getZoom()\n\t\t\t, ca = this.settingsMap.getCenter()\n\t\t\t, xb = this.boundaryMap.getZoom()\n\t\t\t, cb = this.boundaryMap.getCenter();\n\t\t\n\t\tsetTimeout(() => {\n\t\t\tgoogle.maps.event.trigger(this.settingsMap, 'resize');\n\t\t\tthis.settingsMap.setZoom(xa);\n\t\t\tthis.settingsMap.setCenter(ca);\n\t\t\t\n\t\t\tgoogle.maps.event.trigger(this.boundaryMap, 'resize');\n\t\t\tthis.boundaryMap.setZoom(xb);\n\t\t\tthis.boundaryMap.setCenter(cb);\n\t\t}, 1);\n\t}\n\t\n}\n\nwindow.SimpleMapSettings = SimpleMapSettings;"],"names":["loadGoogleAPI","key","locale","simpleMapsLoadingGoogle","gmjs","document","createElement","type","src","onreadystatechange","onload","body","appendChild","loadMapsApi","load","replace","join","dispatchEvent","Event","SimpleMapSettings","namespacedId","mapSettings","lat","lng","setup","inputs","settingsMap","settingsMapEl","settingsMapWrap","boundaryMap","mouseMoveLastPos","nextHeight","onHideMapToggle","shouldHide","e","target","getElementsByTagName","value","nextMaxHeight","_this","getBoundingClientRect","height","style","maxHeight","classList","onSettingsMapReposition","center","onSettingsMapZoom","zoom","getZoom","onResizeMouseDown","preventDefault","clientY","pointerEvents","addEventListener","onResizeMouseMove","onResizeMouseUp","c","getCenter","maps","event","trigger","setCenter","removeEventListener","Object","keys","reduce","a","b","getElementById","this","google","window","places","setupMaps","redrawMaps","on","Map","LatLng","MapTypeId","ROADMAP","addListener","boundaryMapEl","xa","ca","xb","cb","_this2","setZoom"],"mappings":"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"} \ No newline at end of file diff --git a/src/templates/field-settings.twig b/src/templates/field-settings.twig index 499f94d..3daf2b2 100644 --- a/src/templates/field-settings.twig +++ b/src/templates/field-settings.twig @@ -1,60 +1,8 @@ {% import "_includes/forms" as forms %} -
-
- -
-

{{ "The maps default latitude"|t("simplemap") }}

-
-
-
- -
-
- -
-
- -
-

{{ "The maps default longitude"|t("simplemap") }}

-
-
-
- -
-
- -{{ forms.textField({ - label: "Zoom Level"|t("simplemap"), - instructions: "The default zoom level"|t("simplemap"), - placeholder: '12', - size: 2, - id: 'zoom', - name: 'zoom', - value: field.zoom, - type: 'number' -}) }} - -{{ forms.textField({ - label: "Height"|t("simplemap"), - instructions: "The maps height in the input"|t("simplemap"), - placeholder: '400', - size: 3, - id: 'height', - name: 'height', - value: field.height, - type: 'number' -}) }} - {{ forms.lightswitchField({ label: "Hide Map"|t("simplemap"), - instructions: "When on, the map will be hidden leaving just the address auto-complete field"|t("simplemap"), + instructions: "When on, the map will be hidden leaving just the address search field"|t("simplemap"), id: 'hideMap', name: 'hideMap', on: field.hideMap @@ -68,78 +16,85 @@ on: field.hideLatLng }) }} + + + + + +{% set settingsMap %} +
+
+{% endset %} +
+ {{ forms.field({ + label: "Configure Map"|t("simplemap"), + instructions: "Move, zoom, and resize the map"|t("simplemap"), + }, settingsMap) }} +
+
{{ forms.selectField({ - label: "County Restriction"|t("simplemap"), - instructions: "Restrict the auto-complete by a specific country"|t("simplemap"), + label: "Restrict by Country"|t("simplemap"), + instructions: "Restrict the address search to a specific country"|t("simplemap"), id: 'countryRestriction', name: 'countryRestriction', options: countries, value: field.countryRestriction }) }} -{{ forms.radioGroupField({ +{{ forms.selectField({ label: "Restrict by Type"|t("simplemap"), - instructions: "Restrict the auto-complete by a specific type"|t("simplemap"), + instructions: "Restrict the address search to a specific type"|t("simplemap"), id: 'typeRestriction', name: 'typeRestriction', options: types, value: field.typeRestriction }) }} -{% set boundaryRestrictionInput %} - - -{% endset %} + + + + +{% set boundaryMap %} +
+{% endset %} {{ forms.field({ label: "Boundary Restriction"|t("simplemap"), - instructions: "Restrict the auto-complete to within a specific square boundary"|t("simplemap"), -}, boundaryRestrictionInput) }} \ No newline at end of file + instructions: "Restrict the address search to within a specific rectangular boundary"|t("simplemap"), +}, boundaryMap) }} \ No newline at end of file diff --git a/src/translations/en/simplemap.php b/src/translations/en/simplemap.php index 6edb318..2a08b0d 100644 --- a/src/translations/en/simplemap.php +++ b/src/translations/en/simplemap.php @@ -25,27 +25,30 @@ 'The maps height in the input' => 'The maps height in the input', 'Hide Map' => 'Hide Map', - 'When on, the map will be hidden leaving just the address auto-complete field' - => 'When on, the map will be hidden leaving just the address auto-complete field', + 'When on, the map will be hidden leaving just the address search field' + => 'When on, the map will be hidden leaving just the address search field', 'Hide Lat/Lng' => 'Hide Lat/Lng', 'When on, the latitude & longitude fields will be hidden' => 'When on, the latitude & longitude fields will be hidden', - 'County Restriction' => 'County Restriction', - 'Restrict the auto-complete by a specific country' - => 'Restrict the auto-complete by a specific country', + 'Restrict by Country' => 'Restrict by Country', + 'Restrict the address search to a specific country' + => 'Restrict the address search to a specific country', 'Restrict by Type' => 'Restrict by Type', - 'Restrict the auto-complete by a specific type' - => 'Restrict the auto-complete by a specific type', + 'Restrict the address search to a specific type' + => 'Restrict the address search to a specific type', 'North-east Corner' => 'North-east Corner', 'South-west Corner' => 'South-west Corner', 'Boundary Restriction' => 'Boundary Restriction', - 'Restrict the auto-complete to within a specific square boundary' - => 'Restrict the auto-complete to within a specific square boundary', + 'Restrict the address search to within a specific rectangular boundary' + => 'Restrict the address search to within a specific rectangular boundary', + + 'Configure Map' => 'Configure Map', + 'Move, zoom, and resize the map' => 'Move, zoom, and resize the map', // Field validation 'Missing Lat/Lng' => 'Missing Lat/Lng', From deee9a02d7966f65884522df94aaf735818813e1 Mon Sep 17 00:00:00 2001 From: Tam Date: Tue, 30 Jan 2018 16:04:59 +0000 Subject: [PATCH 4/5] Tidy --- src/SimpleMap.php | 4 ++-- src/services/MapService.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SimpleMap.php b/src/SimpleMap.php index e58b3b9..01cb451 100644 --- a/src/SimpleMap.php +++ b/src/SimpleMap.php @@ -59,14 +59,14 @@ public function init () // Field Types Event::on( - Fields::className(), + Fields::class, Fields::EVENT_REGISTER_FIELD_TYPES, [$this, 'onRegisterFieldTypes'] ); // Redirect to settings after install Event::on( - Plugins::className(), + Plugins::class, Plugins::EVENT_AFTER_INSTALL_PLUGIN, [$this, 'onAfterInstallPlugin'] ); diff --git a/src/services/MapService.php b/src/services/MapService.php index c543167..5014ef7 100644 --- a/src/services/MapService.php +++ b/src/services/MapService.php @@ -594,7 +594,7 @@ private function _replaceOrderBy (ElementQuery $query, $distanceSearch = false) { $nextOrder = []; - foreach ($query->orderBy as $order => $sort) { + foreach ((array)$query->orderBy as $order => $sort) { if ($order == 'distance' && $distanceSearch) $nextOrder[$distanceSearch] = $sort; elseif ($order != 'distance') $nextOrder[$order] = $sort; } From c637657b47f41869c5be11dc4f3bf5f40c8156cf Mon Sep 17 00:00:00 2001 From: Tam Date: Tue, 30 Jan 2018 17:14:27 +0000 Subject: [PATCH 5/5] Drawable map boundaries! --- CHANGELOG.md | 9 +- composer.json | 2 +- resources/js/Helpers.js | 12 ++- resources/js/SimpleMapSettings.js | 119 +++++++++++++++++++-- src/fields/MapField.php | 5 + src/resources/SimpleMapSettings.css | 37 ++++++- src/resources/SimpleMapSettings.min.js | 2 +- src/resources/SimpleMapSettings.min.js.map | 2 +- src/templates/field-settings.twig | 17 ++- 9 files changed, 184 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97e849f..f09217f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,14 @@ -## 3.2.1 - WIP +## 3.3.0 - 2018-01-30 +### Fixed +- Added a fix for those annoying `Call to a member function getMap() on null` bugs + ### Improved - Map height no longer jumps when page loads - Vastly improved the map fields settings UI/UX + - No more nasty text fields! + - Map height and position is now set by resizing and moving a map + - Auto-complete search bounds can now be drawn directly onto a map + - Radio buttons are now drop-downs ### Changed - Now using the plugins `afterInstall` function instead of the plugin after install event diff --git a/composer.json b/composer.json index e2ad749..f07873a 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "ether/simplemap", "description": "A beautifully simple Google Map field type.", - "version": "3.2.1", + "version": "3.3.0", "type": "craft-plugin", "license": "MIT", "minimum-stability": "dev", diff --git a/resources/js/Helpers.js b/resources/js/Helpers.js index 9689a7d..3e57517 100644 --- a/resources/js/Helpers.js +++ b/resources/js/Helpers.js @@ -5,19 +5,20 @@ * * @param {string} key - Google Maps API key * @param {string} locale - The locale + * @param {boolean=} includeDrawing - Include the drawing library * @static */ -export const loadGoogleAPI = function (key, locale) { +export const loadGoogleAPI = function (key, locale, includeDrawing = false) { window.simpleMapsLoadingGoogle = true; const gmjs = document.createElement("script"); gmjs.type = "text/javascript"; gmjs.src = "https://www.google.com/jsapi?key=" + key; gmjs.onreadystatechange = function () { - loadMapsApi(key, locale); + loadMapsApi(key, locale, includeDrawing); }; gmjs.onload = function () { - loadMapsApi(key, locale); + loadMapsApi(key, locale, includeDrawing); }; document.body.appendChild(gmjs); }; @@ -27,12 +28,13 @@ export const loadGoogleAPI = function (key, locale) { * * @param {string} key - Google Maps API key * @param {string} locale - The locale + * @param {boolean=} includeDrawing - Include the drawing library * @static */ -export const loadMapsApi = function (key, locale) { +export const loadMapsApi = function (key, locale, includeDrawing = false) { google.load("maps", "3", { other_params: [ - "libraries=places", + "libraries=places" + (includeDrawing ? ",drawing" : ""), `key=${key}`, `language=${locale.replace("_", "-")}`, `region=${locale}`, diff --git a/resources/js/SimpleMapSettings.js b/resources/js/SimpleMapSettings.js index 4e63307..1b2765d 100644 --- a/resources/js/SimpleMapSettings.js +++ b/resources/js/SimpleMapSettings.js @@ -14,19 +14,23 @@ class SimpleMapSettings { zoom: 15, height: 400, boundary: { - nw: { lat: 0, lng: 0 }, - se: { lat: 0, lng: 0 }, + ne: { lat: 0, lng: 0 }, + sw: { lat: 0, lng: 0 }, } }; setup = false; inputs = null; + boundaries = null; settingsMap = null; settingsMapEl = null; settingsMapWrap = null; boundaryMap = null; + boundaryButton = null; + drawingManager = null; + boundaryRectangle = null; mouseMoveLastPos = 0; nextHeight = 0; @@ -37,7 +41,9 @@ class SimpleMapSettings { constructor (key, locale, namespacedId, mapSettings) { this.namespacedId = namespacedId; this.mapSettings = Object.keys(mapSettings).reduce((a, b) => { - a[b] = +mapSettings[b]; + a[b] = b === "boundary" + ? JSON.parse(mapSettings[b]) + : +mapSettings[b]; return a; }, {}); @@ -48,14 +54,26 @@ class SimpleMapSettings { height: document.getElementById(`${this.namespacedId}height`), }; + this.boundaries = { + neLat: document.getElementById(`${this.namespacedId}boundaryRestrictionNELat`), + neLng: document.getElementById(`${this.namespacedId}boundaryRestrictionNELng`), + swLat: document.getElementById(`${this.namespacedId}boundaryRestrictionSWLat`), + swLng: document.getElementById(`${this.namespacedId}boundaryRestrictionSWLng`), + }; + + this.boundaryButton = + document.getElementById(`${this.namespacedId}boundaryButton`); + + this.boundaryButton.addEventListener("click", this.onBoundaryButtonClick); + // Load Google APIs if they aren"t already if (typeof google === "undefined") { if (!window.simpleMapsLoadingGoogle) - loadGoogleAPI(key, locale); + loadGoogleAPI(key, locale, true); } else if (!google.maps || !google.maps.places) { // Load Google Maps APIs if the aren"t already if (!window.simpleMapsLoadingGoogle) - loadMapsApi(key, locale); + loadMapsApi(key, locale, true); } else { if (!this.setup) this.setupMaps(); @@ -146,6 +164,46 @@ class SimpleMapSettings { document.removeEventListener("mouseup", this.onResizeMouseUp); }; + onBoundaryButtonClick = () => { + if (this.boundaries.neLat.value) { + this.drawingManager.setOptions({ + drawingMode: null, + }); + + this.boundaryRectangle.setMap(null); + this.boundaryRectangle = null; + + this.boundaries.neLat.value = ""; + this.boundaries.neLng.value = ""; + this.boundaries.swLat.value = ""; + this.boundaries.swLng.value = ""; + + this.boundaryButton.textContent = "Draw Boundaries"; + return; + } + + this.drawingManager.setOptions({ + drawingMode: google.maps.drawing.OverlayType.RECTANGLE, + }); + this.drawingManager.setMap(this.boundaryMap); + this.boundaryButton.textContent = "Clear Boundaries"; + }; + + onDrawingComplete = rectangle => { + this.boundaryRectangle = rectangle; + this.hookBoundaryRectangleEvents(); + + this.storeNextBounds(rectangle.getBounds()); + + this.drawingManager.setOptions({ + drawingMode: null, + }); + }; + + onRectangleEdit = () => { + this.storeNextBounds(this.boundaryRectangle.getBounds()); + }; + // Actions // ========================================================================= @@ -197,8 +255,20 @@ class SimpleMapSettings { const boundaryMapEl = document.getElementById(`${this.namespacedId}boundaryMap`); - // TODO: If we have boundaries, position the map to contain them. - // TODO: Add [Clear] button + this.drawingManager = new google.maps.drawing.DrawingManager({ + drawingMode: null, + drawingControl: false, + rectangleOptions: { + // clickable: true, + editable: true, + } + }); + + google.maps.event.addListener( + this.drawingManager, + "rectanglecomplete", + this.onDrawingComplete + ); this.boundaryMap = new google.maps.Map(boundaryMapEl, { zoom: this.mapSettings.zoom, @@ -214,6 +284,41 @@ class SimpleMapSettings { mapTypeId: google.maps.MapTypeId.ROADMAP, }); + if (this.boundaries.neLat.value) { + this.boundaryRectangle = new google.maps.Rectangle({ + bounds: { + north: +this.mapSettings.boundary.ne.lat, + east: +this.mapSettings.boundary.ne.lng, + south: +this.mapSettings.boundary.sw.lat, + west: +this.mapSettings.boundary.sw.lng, + }, + map: this.boundaryMap, + editable: true, + }); + + this.boundaryMap.fitBounds(this.boundaryRectangle.getBounds()); + + this.hookBoundaryRectangleEvents(); + } + + } + + hookBoundaryRectangleEvents () { + google.maps.event.addListener( + this.boundaryRectangle/*.getPath()*/, + "bounds_changed", + this.onRectangleEdit + ); + } + + storeNextBounds (bounds) { + const ne = bounds.getNorthEast() + , sw = bounds.getSouthWest(); + + this.boundaries.neLat.value = ne.lat(); + this.boundaries.neLng.value = ne.lng(); + this.boundaries.swLat.value = sw.lat(); + this.boundaries.swLng.value = sw.lng(); } redrawMaps () { diff --git a/src/fields/MapField.php b/src/fields/MapField.php index 6f565ee..f8b93b3 100644 --- a/src/fields/MapField.php +++ b/src/fields/MapField.php @@ -535,6 +535,11 @@ public function getElementValidationRules (): array */ public function modifyElementsQuery (ElementQueryInterface $query, $value) { + // For whatever reason, this function can be + // run BEFORE SimpleMap has been initialized + if (!SimpleMap::$plugin) + return null; + SimpleMap::$plugin->getMap()->modifyElementsQuery($query, $value); return null; diff --git a/src/resources/SimpleMapSettings.css b/src/resources/SimpleMapSettings.css index 96d3d91..d80c232 100644 --- a/src/resources/SimpleMapSettings.css +++ b/src/resources/SimpleMapSettings.css @@ -51,7 +51,42 @@ transform: translate3d(-50%, -50%, 0) rotate(90deg); } +.simplemap-settings--boundary-map-wrap { + position: relative; + width: 100%; + padding-top: 75%; +} + .simplemap-settings--boundary-map { - height: 500px; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 4px; +} + +.simplemap-settings--boundary-button { + position: absolute; + z-index: 1; + top: 10px; + right: 10px; + + display: inline-block; + height: 28px; + padding: 0 8px; + + font-size: 11px; + font-weight: bold; + line-height: 26px; + + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: #fff; + border: none; + box-shadow: rgba(0, 0, 0, 0.3) 0 1px 4px -1px; + border-radius: 2px; + cursor: pointer; } \ No newline at end of file diff --git a/src/resources/SimpleMapSettings.min.js b/src/resources/SimpleMapSettings.min.js index da786df..49dec94 100644 --- a/src/resources/SimpleMapSettings.min.js +++ b/src/resources/SimpleMapSettings.min.js @@ -1,2 +1,2 @@ -var loadGoogleAPI=function(e,t){window.simpleMapsLoadingGoogle=!0;var n=document.createElement("script");n.type="text/javascript",n.src="https://www.google.com/jsapi?key="+e,n.onreadystatechange=function(){loadMapsApi(e,t)},n.onload=function(){loadMapsApi(e,t)},document.body.appendChild(n)},loadMapsApi=function(e,t){google.load("maps","3",{other_params:["libraries=places","key="+e,"language="+t.replace("_","-"),"region="+t].join("&"),callback:function(){document.dispatchEvent(new Event("SimpleMapsGAPILoaded"))}})},classCallCheck=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},createClass=function(){function e(e,t){for(var n=0;n2&&void 0!==arguments[2]&&arguments[2];window.simpleMapsLoadingGoogle=!0;var a=document.createElement("script");a.type="text/javascript",a.src="https://www.google.com/jsapi?key="+e,a.onreadystatechange=function(){loadMapsApi(e,t,n)},a.onload=function(){loadMapsApi(e,t,n)},document.body.appendChild(a)},loadMapsApi=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];google.load("maps","3",{other_params:["libraries=places"+(n?",drawing":""),"key="+e,"language="+t.replace("_","-"),"region="+t].join("&"),callback:function(){document.dispatchEvent(new Event("SimpleMapsGAPILoaded"))}})},classCallCheck=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},createClass=function(){function e(e,t){for(var n=0;n {\n\t\t\ta[b] = +mapSettings[b];\n\t\t\treturn a;\n\t\t}, {});\n\t\t\n\t\tthis.inputs = {\n\t\t\tlat: document.getElementById(`${this.namespacedId}lat`),\n\t\t\tlng: document.getElementById(`${this.namespacedId}lng`),\n\t\t\tzoom: document.getElementById(`${this.namespacedId}zoom`),\n\t\t\theight: document.getElementById(`${this.namespacedId}height`),\n\t\t};\n\t\t\n\t\t// Load Google APIs if they aren\"t already\n\t\tif (typeof google === \"undefined\") {\n\t\t\tif (!window.simpleMapsLoadingGoogle)\n\t\t\t\tloadGoogleAPI(key, locale);\n\t\t} else if (!google.maps || !google.maps.places) {\n\t\t\t// Load Google Maps APIs if the aren\"t already\n\t\t\tif (!window.simpleMapsLoadingGoogle)\n\t\t\t\tloadMapsApi(key, locale);\n\t\t} else {\n\t\t\tif (!this.setup)\n\t\t\t\tthis.setupMaps();\n\t\t}\n\t\t\n\t\tdocument.addEventListener(\"SimpleMapsGAPILoaded\", () => {\n\t\t\tif (!this.setup)\n\t\t\t\tthis.setupMaps();\n\t\t});\n\t\t\n\t\t// Re-draw the maps when the type select changes\n\t\t// (otherwise the maps will be grey)\n\t\tdocument.getElementById(\"type\").addEventListener(\"change\", e => {\n\t\t\tif (e.target.value === \"ether\\\\simplemap\\\\fields\\\\MapField\")\n\t\t\t\tthis.redrawMaps();\n\t\t});\n\t\t\n\t\t$(`#${this.namespacedId}hideMap`).on(\"change\", this.onHideMapToggle);\n\t}\n\t\n\t// Events\n\t// =========================================================================\n\t\n\t// Events: Settings Map\n\t// -------------------------------------------------------------------------\n\t\n\tonHideMapToggle = e => {\n\t\tconst shouldHide = !!e.target.getElementsByTagName(\"input\")[0].value;\n\t\t\n\t\tif (shouldHide) {\n\t\t\tconst nextMaxHeight =\n\t\t\t\tthis.settingsMapWrap.getBoundingClientRect().height + \"px\";\n\t\t\t\n\t\t\tif (nextMaxHeight !== 0)\n\t\t\t\tthis.settingsMapWrap.style.maxHeight = nextMaxHeight;\n\t\t}\n\t\t\n\t\tsetTimeout(() => {\n\t\t\tthis.settingsMapWrap\n\t\t\t\t.classList[shouldHide ? \"add\" : \"remove\"](\"hide\");\n\t\t}, 1);\n\t};\n\t\n\tonSettingsMapReposition = () => {\n\t\tthis.inputs.lng.value = this.settingsMap.center.lng();\n\t\tthis.inputs.lat.value = this.settingsMap.center.lat();\n\t};\n\t\n\tonSettingsMapZoom = () => {\n\t\tthis.inputs.zoom.value = this.settingsMap.getZoom();\n\t};\n\t\n\tonResizeMouseDown = e => {\n\t\te.preventDefault();\n\t\t\n\t\tthis.mouseMoveLastPos = e.clientY;\n\t\tthis.nextHeight = this.mapSettings.height;\n\t\t\n\t\tthis.settingsMapEl.style.pointerEvents = \"none\";\n\t\tthis.settingsMapWrap.style.maxHeight = '';\n\t\t\n\t\tdocument.addEventListener(\"mousemove\", this.onResizeMouseMove);\n\t\tdocument.addEventListener(\"mouseup\", this.onResizeMouseUp);\n\t};\n\t\n\tonResizeMouseMove = e => {\n\t\tthis.nextHeight = this.nextHeight + (e.clientY - this.mouseMoveLastPos);\n\t\tthis.mouseMoveLastPos = e.clientY;\n\t\t\n\t\tif (this.nextHeight < 250)\n\t\t\treturn;\n\t\t\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.mapSettings.height = this.nextHeight;\n\t\t\tthis.inputs.height.value = this.nextHeight;\n\t\t\tthis.settingsMapEl.style.height = `${this.nextHeight}px`;\n\t\t\t\n\t\t\tconst c = this.settingsMap.getCenter();\n\t\t\t\n\t\t\tgoogle.maps.event.trigger(this.settingsMap, \"resize\");\n\t\t\tthis.settingsMap.setCenter(c);\n\t\t});\n\t};\n\t\n\tonResizeMouseUp = () => {\n\t\tthis.settingsMapEl.style.pointerEvents = \"\";\n\t\tdocument.removeEventListener(\"mousemove\", this.onResizeMouseMove);\n\t\tdocument.removeEventListener(\"mouseup\", this.onResizeMouseUp);\n\t};\n\t\n\t// Actions\n\t// =========================================================================\n\t\n\tsetupMaps () {\n\t\t\n\t\tthis.setup = true;\n\t\t\n\t\t// Settings Map\n\t\t// ---------------------------------------------------------------------\n\t\t\n\t\tthis.settingsMapEl =\n\t\t\tdocument.getElementById(`${this.namespacedId}settingsMap`);\n\t\tthis.settingsMapWrap =\n\t\t\tdocument.getElementById(`${this.namespacedId}settingsMapWrap`);\n\t\t\n\t\tthis.settingsMap = new google.maps.Map(this.settingsMapEl, {\n\t\t\tzoom: this.mapSettings.zoom,\n\t\t\tcenter: new google.maps.LatLng(\n\t\t\t\tthis.mapSettings.lat,\n\t\t\t\tthis.mapSettings.lng\n\t\t\t),\n\t\t\tscrollwheel: false,\n\t\t\tfullscreenControl: false,\n\t\t\tmapTypeControl: false,\n\t\t\tstreetViewControl: false,\n\t\t\trotateControl: false,\n\t\t\tmapTypeId: google.maps.MapTypeId.ROADMAP,\n\t\t});\n\t\t\n\t\tgoogle.maps.event.addListener(\n\t\t\tthis.settingsMap,\n\t\t\t'dragend',\n\t\t\tthis.onSettingsMapReposition\n\t\t);\n\t\t\n\t\tgoogle.maps.event.addListener(\n\t\t\tthis.settingsMap,\n\t\t\t'zoom_changed',\n\t\t\tthis.onSettingsMapZoom\n\t\t);\n\t\t\n\t\t// Resizer\n\t\tdocument.getElementById(`${this.namespacedId}settingsMapHeight`)\n\t\t .addEventListener(\"mousedown\", this.onResizeMouseDown);\n\t\t\n\t\t// Boundary Map\n\t\t// ---------------------------------------------------------------------\n\t\t\n\t\tconst boundaryMapEl =\n\t\t\tdocument.getElementById(`${this.namespacedId}boundaryMap`);\n\t\t\n\t\t// TODO: If we have boundaries, position the map to contain them.\n\t\t// TODO: Add [Clear] button\n\t\t\n\t\tthis.boundaryMap = new google.maps.Map(boundaryMapEl, {\n\t\t\tzoom: this.mapSettings.zoom,\n\t\t\tcenter: new google.maps.LatLng(\n\t\t\t\tthis.mapSettings.lat,\n\t\t\t\tthis.mapSettings.lng\n\t\t\t),\n\t\t\tscrollwheel: false,\n\t\t\tfullscreenControl: false,\n\t\t\tmapTypeControl: false,\n\t\t\tstreetViewControl: false,\n\t\t\trotateControl: false,\n\t\t\tmapTypeId: google.maps.MapTypeId.ROADMAP,\n\t\t});\n\t\t\n\t}\n\t\n\tredrawMaps () {\n\t\tconst xa = this.settingsMap.getZoom()\n\t\t\t, ca = this.settingsMap.getCenter()\n\t\t\t, xb = this.boundaryMap.getZoom()\n\t\t\t, cb = this.boundaryMap.getCenter();\n\t\t\n\t\tsetTimeout(() => {\n\t\t\tgoogle.maps.event.trigger(this.settingsMap, 'resize');\n\t\t\tthis.settingsMap.setZoom(xa);\n\t\t\tthis.settingsMap.setCenter(ca);\n\t\t\t\n\t\t\tgoogle.maps.event.trigger(this.boundaryMap, 'resize');\n\t\t\tthis.boundaryMap.setZoom(xb);\n\t\t\tthis.boundaryMap.setCenter(cb);\n\t\t}, 1);\n\t}\n\t\n}\n\nwindow.SimpleMapSettings = SimpleMapSettings;"],"names":["loadGoogleAPI","key","locale","simpleMapsLoadingGoogle","gmjs","document","createElement","type","src","onreadystatechange","onload","body","appendChild","loadMapsApi","load","replace","join","dispatchEvent","Event","SimpleMapSettings","namespacedId","mapSettings","lat","lng","setup","inputs","settingsMap","settingsMapEl","settingsMapWrap","boundaryMap","mouseMoveLastPos","nextHeight","onHideMapToggle","shouldHide","e","target","getElementsByTagName","value","nextMaxHeight","_this","getBoundingClientRect","height","style","maxHeight","classList","onSettingsMapReposition","center","onSettingsMapZoom","zoom","getZoom","onResizeMouseDown","preventDefault","clientY","pointerEvents","addEventListener","onResizeMouseMove","onResizeMouseUp","c","getCenter","maps","event","trigger","setCenter","removeEventListener","Object","keys","reduce","a","b","getElementById","this","google","window","places","setupMaps","redrawMaps","on","Map","LatLng","MapTypeId","ROADMAP","addListener","boundaryMapEl","xa","ca","xb","cb","_this2","setZoom"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"SimpleMapSettings.min.js","sources":["../../resources/js/Helpers.js","../../resources/js/SimpleMapSettings.js"],"sourcesContent":["/* globals google */\n\n/**\n * Load the google API into the dom\n *\n * @param {string} key - Google Maps API key\n * @param {string} locale - The locale\n * @param {boolean=} includeDrawing - Include the drawing library\n * @static\n */\nexport const loadGoogleAPI = function (key, locale, includeDrawing = false) {\n\twindow.simpleMapsLoadingGoogle = true;\n\t\n\tconst gmjs = document.createElement(\"script\");\n\tgmjs.type = \"text/javascript\";\n\tgmjs.src = \"https://www.google.com/jsapi?key=\" + key;\n\tgmjs.onreadystatechange = function () {\n\t\tloadMapsApi(key, locale, includeDrawing);\n\t};\n\tgmjs.onload = function () {\n\t\tloadMapsApi(key, locale, includeDrawing);\n\t};\n\tdocument.body.appendChild(gmjs);\n};\n\n/**\n * Load the google maps API into the dom\n *\n * @param {string} key - Google Maps API key\n * @param {string} locale - The locale\n * @param {boolean=} includeDrawing - Include the drawing library\n * @static\n */\nexport const loadMapsApi = function (key, locale, includeDrawing = false) {\n\tgoogle.load(\"maps\", \"3\", {\n\t\tother_params: [\n\t\t\t\"libraries=places\" + (includeDrawing ? \",drawing\" : \"\"),\n\t\t\t`key=${key}`,\n\t\t\t`language=${locale.replace(\"_\", \"-\")}`,\n\t\t\t`region=${locale}`,\n\t\t].join(\"&\"),\n\t\tcallback: function () {\n\t\t\tdocument.dispatchEvent(new Event(\"SimpleMapsGAPILoaded\"));\n\t\t}\n\t});\n};","/* globals google, $ */\n\nimport { loadGoogleAPI, loadMapsApi } from \"./Helpers\";\n\nclass SimpleMapSettings {\n\t\n\t// Variables\n\t// =========================================================================\n\t\n\tnamespacedId = null;\n\tmapSettings = {\n\t\tlat: 51.272154,\n\t\tlng: 0.514951,\n\t\tzoom: 15,\n\t\theight: 400,\n\t\tboundary: {\n\t\t\tne: { lat: 0, lng: 0 },\n\t\t\tsw: { lat: 0, lng: 0 },\n\t\t}\n\t};\n\t\n\tsetup = false;\n\tinputs = null;\n\tboundaries = null;\n\t\n\tsettingsMap = null;\n\tsettingsMapEl = null;\n\tsettingsMapWrap = null;\n\t\n\tboundaryMap = null;\n\tboundaryButton = null;\n\tdrawingManager = null;\n\tboundaryRectangle = null;\n\t\n\tmouseMoveLastPos = 0;\n\tnextHeight = 0;\n\t\n\t// SimpleMapSettings\n\t// =========================================================================\n\t\n\tconstructor (key, locale, namespacedId, mapSettings) {\n\t\tthis.namespacedId = namespacedId;\n\t\tthis.mapSettings = Object.keys(mapSettings).reduce((a, b) => {\n\t\t\ta[b] = b === \"boundary\"\n\t\t\t\t? JSON.parse(mapSettings[b])\n\t\t\t\t: +mapSettings[b];\n\t\t\treturn a;\n\t\t}, {});\n\t\t\n\t\tthis.inputs = {\n\t\t\tlat: document.getElementById(`${this.namespacedId}lat`),\n\t\t\tlng: document.getElementById(`${this.namespacedId}lng`),\n\t\t\tzoom: document.getElementById(`${this.namespacedId}zoom`),\n\t\t\theight: document.getElementById(`${this.namespacedId}height`),\n\t\t};\n\t\t\n\t\tthis.boundaries = {\n\t\t\tneLat: document.getElementById(`${this.namespacedId}boundaryRestrictionNELat`),\n\t\t\tneLng: document.getElementById(`${this.namespacedId}boundaryRestrictionNELng`),\n\t\t\tswLat: document.getElementById(`${this.namespacedId}boundaryRestrictionSWLat`),\n\t\t\tswLng: document.getElementById(`${this.namespacedId}boundaryRestrictionSWLng`),\n\t\t};\n\t\t\n\t\tthis.boundaryButton =\n\t\t\tdocument.getElementById(`${this.namespacedId}boundaryButton`);\n\t\t\n\t\tthis.boundaryButton.addEventListener(\"click\", this.onBoundaryButtonClick);\n\t\t\n\t\t// Load Google APIs if they aren\"t already\n\t\tif (typeof google === \"undefined\") {\n\t\t\tif (!window.simpleMapsLoadingGoogle)\n\t\t\t\tloadGoogleAPI(key, locale, true);\n\t\t} else if (!google.maps || !google.maps.places) {\n\t\t\t// Load Google Maps APIs if the aren\"t already\n\t\t\tif (!window.simpleMapsLoadingGoogle)\n\t\t\t\tloadMapsApi(key, locale, true);\n\t\t} else {\n\t\t\tif (!this.setup)\n\t\t\t\tthis.setupMaps();\n\t\t}\n\t\t\n\t\tdocument.addEventListener(\"SimpleMapsGAPILoaded\", () => {\n\t\t\tif (!this.setup)\n\t\t\t\tthis.setupMaps();\n\t\t});\n\t\t\n\t\t// Re-draw the maps when the type select changes\n\t\t// (otherwise the maps will be grey)\n\t\tdocument.getElementById(\"type\").addEventListener(\"change\", e => {\n\t\t\tif (e.target.value === \"ether\\\\simplemap\\\\fields\\\\MapField\")\n\t\t\t\tthis.redrawMaps();\n\t\t});\n\t\t\n\t\t$(`#${this.namespacedId}hideMap`).on(\"change\", this.onHideMapToggle);\n\t}\n\t\n\t// Events\n\t// =========================================================================\n\t\n\t// Events: Settings Map\n\t// -------------------------------------------------------------------------\n\t\n\tonHideMapToggle = e => {\n\t\tconst shouldHide = !!e.target.getElementsByTagName(\"input\")[0].value;\n\t\t\n\t\tif (shouldHide) {\n\t\t\tconst nextMaxHeight =\n\t\t\t\tthis.settingsMapWrap.getBoundingClientRect().height + \"px\";\n\t\t\t\n\t\t\tif (nextMaxHeight !== 0)\n\t\t\t\tthis.settingsMapWrap.style.maxHeight = nextMaxHeight;\n\t\t}\n\t\t\n\t\tsetTimeout(() => {\n\t\t\tthis.settingsMapWrap\n\t\t\t\t.classList[shouldHide ? \"add\" : \"remove\"](\"hide\");\n\t\t}, 1);\n\t};\n\t\n\tonSettingsMapReposition = () => {\n\t\tthis.inputs.lng.value = this.settingsMap.center.lng();\n\t\tthis.inputs.lat.value = this.settingsMap.center.lat();\n\t};\n\t\n\tonSettingsMapZoom = () => {\n\t\tthis.inputs.zoom.value = this.settingsMap.getZoom();\n\t};\n\t\n\tonResizeMouseDown = e => {\n\t\te.preventDefault();\n\t\t\n\t\tthis.mouseMoveLastPos = e.clientY;\n\t\tthis.nextHeight = this.mapSettings.height;\n\t\t\n\t\tthis.settingsMapEl.style.pointerEvents = \"none\";\n\t\tthis.settingsMapWrap.style.maxHeight = '';\n\t\t\n\t\tdocument.addEventListener(\"mousemove\", this.onResizeMouseMove);\n\t\tdocument.addEventListener(\"mouseup\", this.onResizeMouseUp);\n\t};\n\t\n\tonResizeMouseMove = e => {\n\t\tthis.nextHeight = this.nextHeight + (e.clientY - this.mouseMoveLastPos);\n\t\tthis.mouseMoveLastPos = e.clientY;\n\t\t\n\t\tif (this.nextHeight < 250)\n\t\t\treturn;\n\t\t\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.mapSettings.height = this.nextHeight;\n\t\t\tthis.inputs.height.value = this.nextHeight;\n\t\t\tthis.settingsMapEl.style.height = `${this.nextHeight}px`;\n\t\t\t\n\t\t\tconst c = this.settingsMap.getCenter();\n\t\t\t\n\t\t\tgoogle.maps.event.trigger(this.settingsMap, \"resize\");\n\t\t\tthis.settingsMap.setCenter(c);\n\t\t});\n\t};\n\t\n\tonResizeMouseUp = () => {\n\t\tthis.settingsMapEl.style.pointerEvents = \"\";\n\t\tdocument.removeEventListener(\"mousemove\", this.onResizeMouseMove);\n\t\tdocument.removeEventListener(\"mouseup\", this.onResizeMouseUp);\n\t};\n\t\n\tonBoundaryButtonClick = () => {\n\t\tif (this.boundaries.neLat.value) {\n\t\t\tthis.drawingManager.setOptions({\n\t\t\t\tdrawingMode: null,\n\t\t\t});\n\t\t\t\n\t\t\tthis.boundaryRectangle.setMap(null);\n\t\t\tthis.boundaryRectangle = null;\n\t\t\t\n\t\t\tthis.boundaries.neLat.value = \"\";\n\t\t\tthis.boundaries.neLng.value = \"\";\n\t\t\tthis.boundaries.swLat.value = \"\";\n\t\t\tthis.boundaries.swLng.value = \"\";\n\t\t\t\n\t\t\tthis.boundaryButton.textContent = \"Draw Boundaries\";\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tthis.drawingManager.setOptions({\n\t\t\tdrawingMode: google.maps.drawing.OverlayType.RECTANGLE,\n\t\t});\n\t\tthis.drawingManager.setMap(this.boundaryMap);\n\t\tthis.boundaryButton.textContent = \"Clear Boundaries\";\n\t};\n\t\n\tonDrawingComplete = rectangle => {\n\t\tthis.boundaryRectangle = rectangle;\n\t\tthis.hookBoundaryRectangleEvents();\n\t\t\n\t\tthis.storeNextBounds(rectangle.getBounds());\n\t\t\n\t\tthis.drawingManager.setOptions({\n\t\t\tdrawingMode: null,\n\t\t});\n\t};\n\t\n\tonRectangleEdit = () => {\n\t\tthis.storeNextBounds(this.boundaryRectangle.getBounds());\n\t};\n\t\n\t// Actions\n\t// =========================================================================\n\t\n\tsetupMaps () {\n\t\t\n\t\tthis.setup = true;\n\t\t\n\t\t// Settings Map\n\t\t// ---------------------------------------------------------------------\n\t\t\n\t\tthis.settingsMapEl =\n\t\t\tdocument.getElementById(`${this.namespacedId}settingsMap`);\n\t\tthis.settingsMapWrap =\n\t\t\tdocument.getElementById(`${this.namespacedId}settingsMapWrap`);\n\t\t\n\t\tthis.settingsMap = new google.maps.Map(this.settingsMapEl, {\n\t\t\tzoom: this.mapSettings.zoom,\n\t\t\tcenter: new google.maps.LatLng(\n\t\t\t\tthis.mapSettings.lat,\n\t\t\t\tthis.mapSettings.lng\n\t\t\t),\n\t\t\tscrollwheel: false,\n\t\t\tfullscreenControl: false,\n\t\t\tmapTypeControl: false,\n\t\t\tstreetViewControl: false,\n\t\t\trotateControl: false,\n\t\t\tmapTypeId: google.maps.MapTypeId.ROADMAP,\n\t\t});\n\t\t\n\t\tgoogle.maps.event.addListener(\n\t\t\tthis.settingsMap,\n\t\t\t'dragend',\n\t\t\tthis.onSettingsMapReposition\n\t\t);\n\t\t\n\t\tgoogle.maps.event.addListener(\n\t\t\tthis.settingsMap,\n\t\t\t'zoom_changed',\n\t\t\tthis.onSettingsMapZoom\n\t\t);\n\t\t\n\t\t// Resizer\n\t\tdocument.getElementById(`${this.namespacedId}settingsMapHeight`)\n\t\t .addEventListener(\"mousedown\", this.onResizeMouseDown);\n\t\t\n\t\t// Boundary Map\n\t\t// ---------------------------------------------------------------------\n\t\t\n\t\tconst boundaryMapEl =\n\t\t\tdocument.getElementById(`${this.namespacedId}boundaryMap`);\n\t\t\n\t\tthis.drawingManager = new google.maps.drawing.DrawingManager({\n\t\t\tdrawingMode: null,\n\t\t\tdrawingControl: false,\n\t\t\trectangleOptions: {\n\t\t\t\t// clickable: true,\n\t\t\t\teditable: true,\n\t\t\t}\n\t\t});\n\t\t\n\t\tgoogle.maps.event.addListener(\n\t\t\tthis.drawingManager,\n\t\t\t\"rectanglecomplete\",\n\t\t\tthis.onDrawingComplete\n\t\t);\n\t\t\n\t\tthis.boundaryMap = new google.maps.Map(boundaryMapEl, {\n\t\t\tzoom: this.mapSettings.zoom,\n\t\t\tcenter: new google.maps.LatLng(\n\t\t\t\tthis.mapSettings.lat,\n\t\t\t\tthis.mapSettings.lng\n\t\t\t),\n\t\t\tscrollwheel: false,\n\t\t\tfullscreenControl: false,\n\t\t\tmapTypeControl: false,\n\t\t\tstreetViewControl: false,\n\t\t\trotateControl: false,\n\t\t\tmapTypeId: google.maps.MapTypeId.ROADMAP,\n\t\t});\n\t\t\n\t\tif (this.boundaries.neLat.value) {\n\t\t\tthis.boundaryRectangle = new google.maps.Rectangle({\n\t\t\t\tbounds: {\n\t\t\t\t\tnorth: +this.mapSettings.boundary.ne.lat,\n\t\t\t\t\teast: +this.mapSettings.boundary.ne.lng,\n\t\t\t\t\tsouth: +this.mapSettings.boundary.sw.lat,\n\t\t\t\t\twest: +this.mapSettings.boundary.sw.lng,\n\t\t\t\t},\n\t\t\t\tmap: this.boundaryMap,\n\t\t\t\teditable: true,\n\t\t\t});\n\t\t\t\n\t\t\tthis.boundaryMap.fitBounds(this.boundaryRectangle.getBounds());\n\t\t\t\n\t\t\tthis.hookBoundaryRectangleEvents();\n\t\t}\n\t\t\n\t}\n\t\n\thookBoundaryRectangleEvents () {\n\t\tgoogle.maps.event.addListener(\n\t\t\tthis.boundaryRectangle/*.getPath()*/,\n\t\t\t\"bounds_changed\",\n\t\t\tthis.onRectangleEdit\n\t\t);\n\t}\n\t\n\tstoreNextBounds (bounds) {\n\t\tconst ne = bounds.getNorthEast()\n\t\t\t, sw = bounds.getSouthWest();\n\t\t\n\t\tthis.boundaries.neLat.value = ne.lat();\n\t\tthis.boundaries.neLng.value = ne.lng();\n\t\tthis.boundaries.swLat.value = sw.lat();\n\t\tthis.boundaries.swLng.value = sw.lng();\n\t}\n\t\n\tredrawMaps () {\n\t\tconst xa = this.settingsMap.getZoom()\n\t\t\t, ca = this.settingsMap.getCenter()\n\t\t\t, xb = this.boundaryMap.getZoom()\n\t\t\t, cb = this.boundaryMap.getCenter();\n\t\t\n\t\tsetTimeout(() => {\n\t\t\tgoogle.maps.event.trigger(this.settingsMap, 'resize');\n\t\t\tthis.settingsMap.setZoom(xa);\n\t\t\tthis.settingsMap.setCenter(ca);\n\t\t\t\n\t\t\tgoogle.maps.event.trigger(this.boundaryMap, 'resize');\n\t\t\tthis.boundaryMap.setZoom(xb);\n\t\t\tthis.boundaryMap.setCenter(cb);\n\t\t}, 1);\n\t}\n\t\n}\n\nwindow.SimpleMapSettings = SimpleMapSettings;"],"names":["loadGoogleAPI","key","locale","includeDrawing","simpleMapsLoadingGoogle","gmjs","document","createElement","type","src","onreadystatechange","onload","body","appendChild","loadMapsApi","load","replace","join","dispatchEvent","Event","SimpleMapSettings","namespacedId","mapSettings","lat","lng","setup","inputs","boundaries","settingsMap","settingsMapEl","settingsMapWrap","boundaryMap","boundaryButton","drawingManager","boundaryRectangle","mouseMoveLastPos","nextHeight","onHideMapToggle","shouldHide","e","target","getElementsByTagName","value","nextMaxHeight","_this","getBoundingClientRect","height","style","maxHeight","classList","onSettingsMapReposition","center","onSettingsMapZoom","zoom","getZoom","onResizeMouseDown","preventDefault","clientY","pointerEvents","addEventListener","onResizeMouseMove","onResizeMouseUp","c","getCenter","maps","event","trigger","setCenter","removeEventListener","onBoundaryButtonClick","neLat","setOptions","setMap","neLng","swLat","swLng","textContent","google","drawing","OverlayType","RECTANGLE","onDrawingComplete","rectangle","hookBoundaryRectangleEvents","storeNextBounds","getBounds","onRectangleEdit","Object","keys","reduce","a","b","JSON","parse","getElementById","this","window","places","setupMaps","redrawMaps","on","Map","LatLng","MapTypeId","ROADMAP","addListener","boundaryMapEl","DrawingManager","Rectangle","boundary","ne","sw","fitBounds","bounds","getNorthEast","getSouthWest","xa","ca","xb","cb","_this2","setZoom"],"mappings":"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"} \ No newline at end of file diff --git a/src/templates/field-settings.twig b/src/templates/field-settings.twig index 3daf2b2..cc5e6b3 100644 --- a/src/templates/field-settings.twig +++ b/src/templates/field-settings.twig @@ -89,10 +89,19 @@ > {% set boundaryMap %} -
+ +
+
+
{% endset %} {{ forms.field({ label: "Boundary Restriction"|t("simplemap"),