This commit is contained in:
2021-09-06 15:50:36 +02:00
parent c205e8bf23
commit 7545c4ffc9
7 changed files with 183 additions and 76 deletions

View File

@@ -2,7 +2,11 @@
<div> <div>
<panel-item :field="field"> <panel-item :field="field">
<template slot="value"> <template slot="value">
<component :is="'field-' + field.map.type" :field="field" v-model="field.value"></component> <component
:is="'field-' + field.map.type"
:field="field"
v-model="field.value"
></component>
</template> </template>
</panel-item> </panel-item>
</div> </div>
@@ -10,6 +14,6 @@
<script> <script>
export default { export default {
props: ['resource', 'resourceName', 'resourceId', 'field'], props: ["resource", "resourceName", "resourceId", "field"],
} };
</script> </script>

View File

@@ -1,5 +1,5 @@
<template> <template>
<div :style="{'height': field.map.height}"> <div :style="{ height: field.map.height }">
<l-map <l-map
style="z-index: 0" style="z-index: 0"
:zoom="field.map.zoom" :zoom="field.map.zoom"
@@ -7,16 +7,14 @@
:bounds="bounds" :bounds="bounds"
@click="onMapClick" @click="onMapClick"
> >
<l-tile-layer <l-tile-layer :url="url" :attribution="attribution" />
:url="url"
:attribution="attribution"/>
<slot></slot> <slot></slot>
</l-map> </l-map>
</div> </div>
</template> </template>
<script> <script>
import {LMap, LTileLayer} from 'vue2-leaflet' import { LMap, LTileLayer } from "vue2-leaflet";
export default { export default {
props: { props: {
@@ -36,24 +34,25 @@ export default {
data() { data() {
return { return {
attribution: '&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors', attribution:
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' '&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors',
} url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
};
}, },
methods: { methods: {
onMapClick(evt) { onMapClick(evt) {
this.$emit('click', evt); this.$emit("click", evt);
} },
}, },
components: { components: {
LMap, LMap,
LTileLayer, LTileLayer,
} },
} };
</script> </script>
<style scoped> <style scoped>
@import "../../../node_modules/leaflet/dist/leaflet.css" @import "../../../node_modules/leaflet/dist/leaflet.css";
</style> </style>

View File

@@ -1,25 +1,31 @@
<template> <template>
<default-field :field="field" :errors="errors" :full-width-content="true"> <default-field :field="field" :errors="errors" :full-width-content="true">
<template slot="field"> <template slot="field">
<component v-if="value" :is="'field-' + field.map.type" :field="field" :edit="true" v-model="value"></component> <component
v-if="value"
:is="'field-' + field.map.type"
:field="field"
:edit="true"
v-model="value"
></component>
</template> </template>
</default-field> </default-field>
</template> </template>
<script> <script>
import { FormField, HandlesValidationErrors } from 'laravel-nova' import { FormField, HandlesValidationErrors } from "laravel-nova";
export default { export default {
mixins: [FormField, HandlesValidationErrors], mixins: [FormField, HandlesValidationErrors],
props: ['resourceName', 'resourceId', 'field'], props: ["resourceName", "resourceId", "field"],
methods: { methods: {
/* /*
* Set the initial, internal value for the field. * Set the initial, internal value for the field.
*/ */
setInitialValue() { setInitialValue() {
this.value = this.field.value || {} this.value = this.field.value || {};
}, },
/** /**
@@ -33,8 +39,8 @@ export default {
* Update the field's internal value. * Update the field's internal value.
*/ */
handleChange(value) { handleChange(value) {
this.value = value this.value = value;
}, },
}, },
} };
</script> </script>

View File

@@ -4,6 +4,6 @@
<script> <script>
export default { export default {
props: ['resourceName', 'field'], props: ["resourceName", "field"],
} };
</script> </script>

View File

@@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import {LMarker} from 'vue2-leaflet' import { LMarker } from "vue2-leaflet";
export default { export default {
props: { props: {
@@ -20,13 +20,16 @@ export default {
edit: { edit: {
type: Boolean, type: Boolean,
default: false, default: false,
} },
}, },
computed: { computed: {
position() { position() {
return L.latLng(this.value.lat || this.field.map.center.latitude, this.value.lng || this.field.map.center.longitude); return L.latLng(
} this.value.lat || this.field.map.center.latitude,
this.value.lng || this.field.map.center.longitude
);
},
}, },
mounted() { mounted() {
@@ -37,21 +40,29 @@ export default {
onDragEnd(evt) { onDragEnd(evt) {
let latLng = evt.target.getLatLng(); let latLng = evt.target.getLatLng();
this.$emit('input', { this.$emit("input", {
lat: latLng.lat, lat: latLng.lat,
lng: latLng.lng, lng: latLng.lng,
}); });
}, },
registerWatchers() { registerWatchers() {
this.getGlobalFieldComponents().forEach(component => { this.getGlobalFieldComponents().forEach((component) => {
if ([this.field.latitudeField, this.field.longitudeField].includes(component.field.attribute)) { if (
component.$watch('value', (value) => { [
this.field.latitudeField,
this.field.longitudeField,
].includes(component.field.attribute)
) {
component.$watch(
"value",
(value) => {
this.value[component.field.attribute] = value; this.value[component.field.attribute] = value;
}, {immediate: true}) },
{ immediate: true }
);
} }
}); });
}, },
getGlobalFieldComponents(components = null) { getGlobalFieldComponents(components = null) {
@@ -61,12 +72,14 @@ export default {
let returnArray = []; let returnArray = [];
components.forEach(component => { components.forEach((component) => {
if (component.field) { if (component.field) {
return returnArray.push(component); return returnArray.push(component);
} }
returnArray = returnArray.concat(this.getGlobalFieldComponents(component.$children)); returnArray = returnArray.concat(
this.getGlobalFieldComponents(component.$children)
);
}); });
return returnArray; return returnArray;
@@ -75,6 +88,6 @@ export default {
components: { components: {
LMarker, LMarker,
} },
} };
</script> </script>

View File

@@ -1,21 +1,42 @@
<template> <template>
<div @keydown.backspace="removeLastMarker"> <div @keydown.backspace="removeLastMarker">
<field-map :bounds="bounds" :center="center" :field="field" @click="createMarker"> <field-map
<l-marker v-for="(marker, index) in markers" :lat-lng="marker" :draggable="edit" @dragstart="saveDraggingMarker" @dragend="updateMarkerPosition"> :bounds="bounds"
:center="center"
:field="field"
@click="createMarker"
>
<l-marker
v-for="(marker, index) in markers"
:lat-lng="marker"
:draggable="edit"
@dragstart="saveDraggingMarker"
@dragend="updateMarkerPosition"
>
<l-icon <l-icon
:icon-size="[24, 24]" :icon-size="[24, 24]"
:icon-anchor="[12, 12]" :icon-anchor="[12, 12]"
:icon-url="index === markers.length - 1 ? '/images/highlighted-point_marker.svg' : '/images/point_marker.svg'" :icon-url="
index === markers.length - 1
? '/images/highlighted-point_marker.svg'
: '/images/point_marker.svg'
"
/> />
</l-marker> </l-marker>
<l-polygon :lat-lngs="value" :visible="true" /> <l-polygon :lat-lngs="value" :visible="true" />
</field-map> </field-map>
<l-control position="bottomleft" v-if="edit" class="block my-2"> <l-control position="bottomleft" v-if="edit" class="block my-2">
<button @click="removeLastMarker" class="btn btn-default btn-primary"> <button
@click="removeLastMarker"
class="btn btn-default btn-primary"
>
Slett forrige Slett forrige
</button> </button>
<button @click="removeAllMarkers" class="btn btn-default btn-primary"> <button
@click="removeAllMarkers"
class="btn btn-default btn-primary"
>
Slett alle Slett alle
</button> </button>
</l-control> </l-control>
@@ -23,7 +44,7 @@
</template> </template>
<script> <script>
import {LMarker, LIcon, LPolygon} from 'vue2-leaflet' import { LMarker, LIcon, LPolygon } from "vue2-leaflet";
export default { export default {
props: { props: {
@@ -38,15 +59,15 @@ export default {
edit: { edit: {
type: Boolean, type: Boolean,
default: false, default: false,
} },
}, },
data() { data() {
return { return {
startBounds: undefined, startBounds: undefined,
markerBeingDragged: undefined, markerBeingDragged: undefined,
lastMarkerAddedTime: 0 lastMarkerAddedTime: 0,
} };
}, },
computed: { computed: {
@@ -78,13 +99,13 @@ export default {
return null; return null;
} }
return this.startBounds = new L.LatLngBounds(this.markers); return (this.startBounds = new L.LatLngBounds(this.markers));
}, },
}, },
methods: { methods: {
triggerChange(evt) { triggerChange(evt) {
this.$emit('input', this.markers); this.$emit("input", this.markers);
}, },
saveDraggingMarker(evt) { saveDraggingMarker(evt) {
this.markerBeingDragged = evt.target._latlng; this.markerBeingDragged = evt.target._latlng;
@@ -102,7 +123,7 @@ export default {
createMarker(evt) { createMarker(evt) {
if (new Date().getTime() - this.lastMarkerAddedTime < 20) { if (new Date().getTime() - this.lastMarkerAddedTime < 20) {
// Don't want to double register clicks from dragend, if within 20 ms return // Don't want to double register clicks from dragend, if within 20 ms return
return return;
} }
this.markers.push(evt.latlng); this.markers.push(evt.latlng);
this.triggerChange(); this.triggerChange();
@@ -111,9 +132,11 @@ export default {
const newMarker = evt.target._latlng; const newMarker = evt.target._latlng;
const { lat, lng } = this.markerBeingDragged; const { lat, lng } = this.markerBeingDragged;
const markerIndex = this.value.findIndex(marker => marker.lat === lat && marker.lng === lng); const markerIndex = this.value.findIndex(
(marker) => marker.lat === lat && marker.lng === lng
);
this.value.splice(markerIndex, 1, newMarker); this.value.splice(markerIndex, 1, newMarker);
this.lastMarkerAddedTime = new Date().getTime() this.lastMarkerAddedTime = new Date().getTime();
}, },
}, },
@@ -121,6 +144,6 @@ export default {
LMarker, LMarker,
LIcon, LIcon,
LPolygon, LPolygon,
} },
} };
</script> </script>

View File

@@ -1,14 +1,50 @@
<template> <template>
<div @keydown.backspace="removeLastMarker"> <div @keydown.backspace="removeLastMarker">
<field-map :bounds="bounds" :center="center" :field="field" @click="createMarker"> <field-map
<l-marker v-for="marker in markers" :lat-lng="marker" :draggable="edit" @dragend="triggerChange" /> :bounds="bounds"
<l-polyline :lat-lngs="value" :visible="true" /> :center="center"
:field="field"
@click="createMarker"
>
<l-marker
v-for="(marker, index) in markers"
:lat-lng="marker"
:draggable="edit"
@dragstart="saveDraggingMarker"
@dragend="updateMarkerPosition"
>
<l-icon
:icon-size="[24, 24]"
:icon-anchor="[12, 12]"
:icon-url="
index === markers.length - 1
? '/images/highlighted-point_marker.svg'
: '/images/point_marker.svg'
"
/>
</l-marker>
<l-polyline :lat-lngs="value" :visible="true" :fill="false" />
</field-map> </field-map>
<l-control position="bottomleft" v-if="edit" class="block my-2">
<button
@click="removeLastMarker"
class="btn btn-default btn-primary"
>
Slett forrige
</button>
<button
@click="removeAllMarkers"
class="btn btn-default btn-primary"
>
Slett alle
</button>
</l-control>
</div> </div>
</template> </template>
<script> <script>
import {LMarker, LPolyline} from 'vue2-leaflet' import { LMarker, LIcon, LPolyline } from "vue2-leaflet";
export default { export default {
props: { props: {
@@ -23,13 +59,15 @@ export default {
edit: { edit: {
type: Boolean, type: Boolean,
default: false, default: false,
} },
}, },
data() { data() {
return { return {
startBounds: undefined, startBounds: undefined,
} markerBeingDragged: undefined,
lastMarkerAddedTime: 0,
};
}, },
computed: { computed: {
@@ -61,27 +99,51 @@ export default {
return null; return null;
} }
return this.startBounds = new L.LatLngBounds(this.markers); return (this.startBounds = new L.LatLngBounds(this.markers));
}, },
}, },
methods: { methods: {
triggerChange() { triggerChange(evt) {
this.$emit('input', this.markers); this.$emit("input", this.markers);
}, },
removeLastMarker() { saveDraggingMarker(evt) {
this.markerBeingDragged = evt.target._latlng;
},
removeLastMarker(event) {
this.markers.splice(-1, 1); this.markers.splice(-1, 1);
this.triggerChange(); this.triggerChange();
event.preventDefault();
},
removeAllMarkers(event) {
this.value = [];
this.triggerChange();
event.preventDefault();
}, },
createMarker(evt) { createMarker(evt) {
if (new Date().getTime() - this.lastMarkerAddedTime < 20) {
// Don't want to double register clicks from dragend, if within 20 ms return
return;
}
this.markers.push(evt.latlng); this.markers.push(evt.latlng);
this.triggerChange(); this.triggerChange();
} },
updateMarkerPosition(evt) {
const newMarker = evt.target._latlng;
const { lat, lng } = this.markerBeingDragged;
const markerIndex = this.value.findIndex(
(marker) => marker.lat === lat && marker.lng === lng
);
this.value.splice(markerIndex, 1, newMarker);
this.lastMarkerAddedTime = new Date().getTime();
},
}, },
components: { components: {
LMarker, LMarker,
LIcon,
LPolyline, LPolyline,
} },
} };
</script> </script>