Selaa lähdekoodia

structures search: fields and map reinit ok

Olivier Massot 4 vuotta sitten
vanhempi
commit
bca68f89e5

+ 37 - 10
components/Ui/Map/Structures.vue

@@ -4,6 +4,7 @@
       <no-ssr>
         <l-map
           id="map"
+          ref="vMap"
           :zoom="zoom"
           :center="center"
           :bounds="bounds"
@@ -18,7 +19,8 @@
             <l-marker
               v-for="structure in structures"
               :key="structure.id"
-              :lat-lng="[structure.latitude, structure.longitude]">
+              :lat-lng="[structure.latitude, structure.longitude]"
+            >
               <l-popup>
                 <b>{{ structure.name }}</b><br>
                 {{ structure.postalCode }} {{ structure.addressCity }}<br>
@@ -70,19 +72,44 @@ export default {
       bounds: defaultBounds,
       isFirstRendering: true,
       shortcuts: [
-        { src: '/images/metropole.png', alt: 'Metropole', bounds: { x1: 51.03, y1: -5.78, x2: 41.2, y2: 9.70 } },
-        { src: '/images/guadeloupe.png', alt: 'Guadeloupe', bounds: { x1: 16.62, y1: -62.03, x2: 15.74, y2: -60.97 } },
-        { src: '/images/martinique.png', alt: 'Martinique', bounds: { x1: 14.95, y1: -61.43, x2: 14.28, y2: -60.60 } },
-        { src: '/images/mayotte.png', alt: 'Mayotte', bounds: { x1: -12.51, y1: 44.86, x2: -13.19, y2: 45.45 } },
-        { src: '/images/la_reunion.png', alt: 'La Réunion', bounds: { x1: -20.65, y1: 54.92, x2: -21.65, y2: 56.15 } },
-        { src: '/images/guyane.png', alt: 'Guyane', bounds: { x1: 6.24, y1: -54.62, x2: 1.87, y2: -50.59 } }
-      ]
+        { src: '/images/metropole.png', alt: 'Metropole', bounds: [[51.03, -5.78], [41.2, 9.70]] },
+        { src: '/images/guadeloupe.png', alt: 'Guadeloupe', bounds: [[16.62, -62.03], [15.74, -60.97]] },
+        { src: '/images/martinique.png', alt: 'Martinique', bounds: [[14.95, -61.43], [14.28, -60.60]] },
+        { src: '/images/mayotte.png', alt: 'Mayotte', bounds: [[-12.51, 44.86], [-13.19, 45.45]] },
+        { src: '/images/la_reunion.png', alt: 'La Réunion', bounds: [[-20.65, 54.92], [-21.65, 56.15]] },
+        { src: '/images/guyane.png', alt: 'Guyane', bounds: [[6.24, -54.62], [1.87, -50.59]] }
+      ],
+      zoomRequired: false
+    }
+  },
+  watch: {
+    structures () {
+      if (this.zoomRequired) {
+        this._fitBoundsToMarkers()
+        this.zoomRequired = false
+      }
     }
   },
   methods: {
     setMapBounds (bounds) {
-      this.center = [0, 0] // << without this, the new bounds won't be properly set if you're already inside these new bounds.
-      this.bounds = [[bounds.x1, bounds.y1], [bounds.x2, bounds.y2]]
+      this.bounds = bounds
+      this.$refs.vMap.mapObject.fitBounds(bounds) // << without this, the new bounds may not be properly set when the current view overlaps the new bounds.
+    },
+    resetBounds () {
+      this.setMapBounds(this.defaultBounds)
+    },
+    zoomOnResults () {
+      this.zoomRequired = true
+    },
+    _fitBoundsToMarkers () {
+      const coords = this.structures.filter(
+        (s) => { return s.latitude && s.longitude }
+      ).map(
+        (s) => { return [s.latitude, s.longitude] })
+      if (!coords.length > 0) {
+        return
+      }
+      this.$refs.vMap.mapObject.fitBounds(coords)
     },
     boundsUpdated (newBounds) {
       // do not send and event on first automatic rendering

+ 14 - 0
components/Ui/Search/Address.vue

@@ -29,6 +29,13 @@
 
 <script>
 export default {
+  props: {
+    value: {
+      type: String,
+      required: false,
+      default: ''
+    }
+  },
   data () {
     return {
       model: null,
@@ -74,6 +81,13 @@ export default {
     }
   },
   methods: {
+    clear () {
+      this.model = null
+      this.search = null
+      this.features = []
+      this.loading = false
+      this.errorMsg = ''
+    },
     geolocalizeUser () {
       if (navigator.geolocation) {
         navigator.geolocation.getCurrentPosition(

+ 12 - 8
components/Ui/Search/Text.vue

@@ -1,22 +1,26 @@
 <template>
   <v-text-field
-    v-model="text"
+    v-model="value"
     type="text"
-    class="search-bar"
-    name="search-query"
     outlined
     append-icon="mdi-magnify"
     :label="$t('what') + ' ?'"
-    @change="$emit('change', text)"
-    @click:append="$emit('change', text)"
+    @click:append="$emit('change', value)"
   />
 </template>
 
 <script>
 export default {
-  data () {
-    return {
-      text: ''
+  props: {
+    value: {
+      type: String,
+      required: false,
+      default: ''
+    }
+  },
+  watch: {
+    value () {
+      this.$emit('input', this.value)
     }
   }
 }

+ 17 - 2
pages/structures_adherentes/index.vue

@@ -23,6 +23,7 @@
       <!-- Map Column (hidden in 'list-view' mode)-->
       <v-col v-show="mapview" cols="6">
         <UiMapStructures
+          ref="map"
           :structures="filteredStructures"
           @boundsUpdated="mapBoundsFilterChanged"
         />
@@ -35,11 +36,11 @@
           <v-form method="get" class="mt-8 w100">
             <v-row>
               <v-col cols="6" class="py-2 px-1">
-                <UiSearchText @change="textFilterChanged" />
+                <UiSearchText v-model="textFilter" />
               </v-col>
 
               <v-col cols="6" class="py-2 px-1">
-                <UiSearchAddress @change="locationFilterChanged" />
+                <UiSearchAddress ref="addressSearch" @change="locationFilterChanged" />
               </v-col>
             </v-row>
 
@@ -59,6 +60,7 @@
                       item-value="id"
                       item-text="label"
                       filled
+                      @change="filtersUpdated"
                     />
                   </v-col>
                   <v-col :cols="3" class="py-2 px-1">
@@ -69,6 +71,7 @@
                       item-text="label"
                       :label="$t('department')"
                       filled
+                      @change="filtersUpdated"
                     />
                   </v-col>
                   <v-col :cols="3" class="py-2 px-1">
@@ -79,6 +82,7 @@
                       item-text="name"
                       :label="$t('federation')"
                       filled
+                      @change="filtersUpdated"
                     />
                   </v-col>
                   <v-col :cols="3" class="py-2 px-1">
@@ -94,6 +98,7 @@
                       item-value="distance"
                       item-text="label"
                       filled
+                      @change="filtersUpdated"
                     />
                   </v-col>
                 </v-row>
@@ -1850,12 +1855,20 @@ export default {
     },
     textFilterChanged (newVal) {
       this.textFilter = newVal
+      this.filtersUpdated()
     },
     locationFilterChanged (newVal) {
       this.locationFilter = newVal
       if (this.distanceFilter === null) {
         this.distanceFilter = 10
       }
+      this.filtersUpdated()
+    },
+    filtersUpdated () {
+      this.fitMapToResults()
+    },
+    fitMapToResults () {
+      this.$refs.map.zoomOnResults()
     },
     mapBoundsFilterChanged (newBounds) {
       this.mapBoundsFilter = newBounds
@@ -1868,6 +1881,8 @@ export default {
       this.federationFilter = null
       this.distanceFilter = null
       this.mapBoundsFilter = null
+      this.$refs.addressSearch.clear()
+      this.$refs.map.resetBounds()
     },
     toRad (val) {
       // Converts numeric degrees to radians