Address.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <template>
  2. <div>
  3. <v-autocomplete
  4. v-model="model"
  5. :loading="loading"
  6. :items="items"
  7. :search-input.sync="search"
  8. hide-no-data
  9. hide-details
  10. return-object
  11. auto-select-first
  12. clearable
  13. :label="$t('where') + ' ?'"
  14. outlined
  15. append-icon="mdi-crosshairs-gps"
  16. @change="$emit('change', $event ? $event.value : '')"
  17. @click:append="geolocalizeUser"
  18. />
  19. <v-snackbar :value="errorMsg !== ''">
  20. {{ errorMsg }}
  21. <template #action="{ attrs }">
  22. <v-btn text v-bind="attrs" @click="errorMsg=''">
  23. {{ $t('close') }}
  24. </v-btn>
  25. </template>
  26. </v-snackbar>
  27. </div>
  28. </template>
  29. <script>
  30. export default {
  31. props: {
  32. value: {
  33. type: String,
  34. required: false,
  35. default: ''
  36. }
  37. },
  38. data () {
  39. return {
  40. model: null,
  41. search: null,
  42. features: [],
  43. loading: false,
  44. errorMsg: ''
  45. }
  46. },
  47. computed: {
  48. items () {
  49. return this.features.map((f) => {
  50. return {
  51. text: f.properties.name + ' (' + f.properties.postcode + ')',
  52. value: { longitude: f.geometry.coordinates[0], latitude: f.geometry.coordinates[1] },
  53. disabled: false
  54. }
  55. })
  56. }
  57. },
  58. watch: {
  59. search (val) {
  60. if (!val) {
  61. this.features = []
  62. return
  63. }
  64. this.loading = true
  65. // Lazily load input items
  66. fetch('https://api-adresse.data.gouv.fr/search/?type=municipality&autocomplete=1&limit=5&q=' + val)
  67. .then(res => res.json())
  68. .then(({ features }) => {
  69. this.features = features
  70. })
  71. .catch((err) => {
  72. // eslint-disable-next-line no-console
  73. console.error(err)
  74. })
  75. .finally(() => {
  76. this.loading = false
  77. })
  78. }
  79. },
  80. methods: {
  81. clear () {
  82. this.model = null
  83. this.search = null
  84. this.features = []
  85. this.loading = false
  86. this.errorMsg = ''
  87. },
  88. geolocalizeUser () {
  89. if (navigator.geolocation) {
  90. navigator.geolocation.getCurrentPosition(
  91. (position) => {
  92. this.latitude = position.coords.latitude
  93. this.longitude = position.coords.longitude
  94. this.text = this.$t('my_position')
  95. },
  96. () => {
  97. this.errorMsg = this.$t('geolocation_error')
  98. }
  99. )
  100. } else {
  101. this.errorMsg = this.$t('geolocation_not_supported')
  102. }
  103. }
  104. }
  105. }
  106. </script>
  107. <style>
  108. .v-input__control {
  109. height: 56px;
  110. }
  111. </style>