I've been diving into building a Single Page Application using Vue 3, TypeScript, and The Movie Database (TMDB).
Currently, I'm focused on developing a search form within my project.
Within the file src\components\TopBar.vue
, here's what I have:
<template>
<!-- More code -->
<form ref="searchForm" class="search_form w-100 mx-auto mt-2 mt-md-0">
<div class="input-group">
<input v-on:keyup="debounceMovieSearch" v-model="searchTerm" class="form-control search-box" type="text" placeholder="Search movies...">
<div class="input-group-append">
<button class="btn" type="button">
<font-awesome-icon :icon="['fas', 'search']" />
</button>
</div>
</div>
<div v-if="isSearch" @click="isSearch = false" class="search-results shadow-sm">
<div v-if="this.movies.length">
<router-link v-for="movie in movies.slice(0, 10)" :key="movie.id" :to="`/movie/${movie.id}`">
<SearchItem :movie="movie" />
</router-link>
</div>
<div v-else>
<p class="m-0 p-2 text-center">No movies found for this search</p>
</div>
</div>
</form>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import axios from 'axios';
import env from '../env';
import SearchItem from './SearchItem.vue';
export default defineComponent({
name: 'TopBar',
components: {SearchItem},
data() {
return {
searchForm: ref(null),
isSearch: false,
searchTerm: '',
timeOutInterval: 1000,
movies: []
}
},
mounted() {
this.windowEvents();
},
methods: {
windowEvents() {
window.addEventListener('click', (event) => {
if (!(this.$refs.searchForm as HTMLElement).value.contains(event.target)){
console.log('click outside');
}
});
},
debounceMovieSearch() {
setTimeout(this.doMovieSearch, this.timeOutInterval)
},
doMovieSearch() {
if (this.searchTerm.length > 2) {
this.isSearch = true;
axios.get(`${env.api_url}/search/movie?api_key=${env.api_key}&query=${this.searchTerm}`).then(response => {
this.movies = response.data.results;
})
.catch(err => console.log(err));
}
},
}
});
</script>
https://i.stack.imgur.com/4FfRLl.jpg
The main objective is to close the search results list when the user clicks outside of the form. To achieve this functionality, I've implemented the following snippet of code:
windowEvents() {
window.addEventListener('click', (event) => {
if (!(this.$refs.searchForm as HTMLElement).value.contains(event.target)){
console.log('click outside');
}
});
}
The Issue at Hand
The approach above triggers an error stating:
Property 'value' does not exist on type 'HTMLElement'.
Queries to Ponder
- What might be causing this issue?
- How can this problem be reliably rectified?