Здравствуйте. Проблема заключается в том что не работают нативные функции JavaScript в методах Vue.JS.
Я делаю свой велосипед, пытаюсь реализовать живой поиск, с возможность выбора результатов стрелочками на клавиатуре.
Пытаюсь реализовать возможность переключения между элементами списка и Input. Что бы когда фокус находится в Inpute, при нажатии стрелочки вниз на клавиатуре, выделяется первый элемент в списке и так далее по списку при нажатии на стрелочку вниз. И по достижению последнего элемента в списке, при нажатии вниз, должен снова выделяться Input, аналогично и при нажатии стрелочки вверх.
Суть проблемы: не могу добавить в массив с элементами по которым идёт выделение в списке, элемент Input. Пытался уже разными способами реализовать эту задачу, так как метод push в принципе не работает, вылезает такая ошибка: "[Vue warn]: Error in v-on handler: "TypeError: this.resultlist.push is not a function"". По коду это появляется в методе initList. Колхоз который дальше, в методах down и up, связан именно с этой ошибкой. пытаюсь её как-то обойти и создал переменную ссылающуюся на элемент input отдельно, но когда я началь прописывать focus в методах down и up, я получил ошибку: "[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'focus' of undefined"".
Что я делаю не так? Подскажите пожалуйста. Документацию облазил вдоль и поперёк, полагаю что-то не заметил, но не могу понять что именно.
Буду благодарен любой конструктивной критике и предложениям по коду (попутно), так как я только учусь.
Далее HTML код:
<div id="search">
<form action="/api/search/" method="get" class="form-inline">
<label class="mr-sm-2 mb-0 sr-only" for="first_name">Название машины</label>
<input type="text" v-model="keywords" @keyup.down="down" @keyup.up="up" name="name" placeholder="Название машины" id="vsearch-input" autocomplete="off" class="form-control mr-sm-2 mb-2 mb-sm-0" value="<?= $_GET['name']; ?>">
<button type="submit" class="btn btn-primary mt-2 mt-sm-0">Найти</button>
</form>
<div class="list-group" style="position: absolute;" @keyup.down="down" @keyup.up="up">
<a v-for="(car, i) in results" :href="'/api/vehicle/?id='+car.id" class="align-items-center list-group-item list-group-item-action text-capitalize">
<span class="badge badge-primary">{{ car.id }}</span>
{{ car.name }}
<span class="badge badge-success">{{ car.name_ru }}</span>
<span class="badge badge-secondary">{{ car.price }}</span>
</a>
</div>
</div>
И JS код:
var search = new Vue({
el: '#search',
data: {
timeoutId: null,
keywords: null,
resultlist: [],
currelement: -1,
vsearch: document.querySelector('#vsearch-input'),
results: null
},
watch: {
keywords: function (newKeyword, oldKeyword) {
clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(this.sendQuery, 500);
}
},
methods: {
highlight(text) {
return text.replace(new RegExp(this.keywords, 'gi'), '<span class="highlighted">$&</span>');
},
initlist: function() {
this.resultlist = document.querySelectorAll('.list-group > a') || [];
this.resultlist.push(123); // Вот здесь ошибка с push, не добавляет даже 123
console.log(this.resultlist);
console.log(this.resultlist.length);
},
resetList: function() {
this.resultlist = [];
},
down: function() {
if(this.resultlist.length == 0) this.initlist();
this.currelement++;
if(this.currelement == this.resultlist.length)
{
this.currelement = -1;
this.vsearch.focus();
return;
}
this.resultlist[this.currelement].focus();
// TODO: добавить к активному элементу класс active
},
up: function() {
if(this.resultlist.length == 0) this.initlist();
this.currelement--;
if(this.currelement == -1)
{
this.vsearch.focus();
return;
}
this.resultlist[this.currelement].focus();
// TODO: добавить к активному элементу класс active
},
sendQuery: function () {
sData = { name: this.keywords };
this.sendPost('/api/search/', sData);
clearTimeout(this.timeoutId);
},
sendPost: function(sendfurl, senddata) {
axios({
method: 'post',
url: sendfurl,
data: senddata
})
.then(response =>
{
console.log(response);
console.log(response.data);
if(response.data.length) {
this.resetList();
this.results = response.data;
}
else this.results = null;
})
.catch(function (error)
{
console.log(error);
});
}
}
})