1

I want to create a few custom controls for an OpenLayers 6 map in a Vue SPA. I have read through a bunch of answers (1, 2, 3, 4 and others), but they all have to do with very simple JS and HTML setups that I am having trouble adapting to a Vue SPA using Vuetify. I would love for someone to make a simple CodePen or JSFiddle that shows how to create a custom controls using Vuetify UI components and how they would interact with the context (this and store) of the rest of a Vue SPA. I know there is the brilliant ol-ext that is out there but it is built with JQuery and it is, for my use case, as difficult to implement as a from scratch solution. I already have built Vue components that work with OpenLayers but I would love to put them as collapsible containers as map controls.

Curious
  • 383
  • 3
  • 13

1 Answers1

1

I ended up abandoning the templates I kept finding on forums and trying to use the addControl function of the Map object and passing as element a v-container with a unique id I wrote just as you would any other component. Here is a snippet of the code that allows for this.

<template>
  <v-container id="expandCustomControl" fluid>
    <v-menu
      close-on-content-click="false"
      bottom
      offset-y
      nudge-bottom="10"
      nudge-left="5"
      content-class="testContentClass"
    >
      <template v-slot:activator="{ on , attrs }">
        <v-btn
          color="primary"
          v-bind="attrs"
          v-on="on"
          x-small
          fab>
          <v-icon>
            {{ attrs["aria-expanded"] === "true" ? 'mdi-chevron-up' : 'mdi-chevron-down' }}
          </v-icon>
        </v-btn>
      </template>

      <v-container id="insideMenuExpansionPanel" @click.stop>
        <v-row class="mt-1 ml-1">
          <span>Custom Controls</span>
        </v-row>
        <v-row>
          <v-divider class="mx-2"/>
        </v-row>
        <v-row>
          <v-hover v-slot="{ hover }">
            <v-autocomplete
              dense
              rounded
              solo
              hide-details
              :style="{ 'width': hover ? '350px' : '150px' }"
              class="mx-2 mt-2"/>
          </v-hover>
        </v-row>
        <v-row justify="start" class="my-0">
          <v-col>
            <v-switch inset v-model="testSwitchValue" :label="`Switch : ${testSwitchValue}`"/>
          </v-col>
        </v-row>
      </v-container>
    </v-menu>
  </v-container>
</template>
<script>
  ...
  var myControl = new Control({element: document.getElementById("expandCustomControl")});
  ...
  this.map.addControl(myControl)
  ...
</script>
<style scoped>
#insideMenuExpansionPanel {
  border-radius: 25px;
}

.testContentClass {
  border-radius: 25px;
  background-color: rgba(240, 248, 255, 0.6);
}

#expandCustomControl {
  position: relative; /* important to ensure the custom control is positioned relative to the top left corner of the map div */
  top: 65px;
  left: 0.1em;
  max-width: 60px;
  max-height: 400px;
  margin: 0px; /* important to ensure the custom control is not centered since the container has margin: auto by default */
}
</style>

EDIT : Confirmed that the Vuetify UI elements in the container have access to the context and they work as expected however now my struggle is to see how to ensure that the container expands on hover

EDIT 2 : I decided to implement it to open on click but hover should not be too different.

Curious
  • 383
  • 3
  • 13