Reputation: 23
I have a listBoxStyle in data on the component. I've bound it to the listbox. One of the styles is position: absolute
. I need to position the box immediately below the input element. In the mounted hook I'm getting the top, left, and height from input element and I'm modifying the listBoxStyle. Unfortunately this does nothing at all. The listbox stays exactly where it is initially created.
I'm really looking for some way to dynamically move the listbox where I want it.
Here's the code:
Vue.component("employee-search", {
props: ["small"],
data: function () {
return {
searchText: "",
isSmall: (this.small ? true : false),
list: [],
formControlCss: "form-control",
fullWidthCss: "full-width",
smCss: "input-sm",
listBoxStyle: {
position: "absolute",
top: 0,
left: 0,
backgroundColor: "white",
borderStyle: "solid",
borderWidth: "1px",
padding: "5px 25px 5px 0px",
borderColor: "#245580"
}
}
},
template:
'<div>' +
' <input ref="inputBox"' +
' v-model="searchText" ' +
' v-on:input="handleInputChange"' +
' v-bind:class="[formControlCss, fullWidthCss, isSmall ? smCss : \'\']" ' +
' placeholder="Search on name or badge #..." > ' +
' <div ref="listBox" v-bind:style="listBoxStyle">' +
' <ul v-show="list.length > 0" style="margin-top: 10px"> ' +
' <li ' +
' v-for="item in list" ' +
' v-on:click="handleSelect(item)" ' +
' style="cursor: pointer; margin-bottom: 5px;">' +
' {{ item.label }}' +
' </li>' +
' </ul>' +
' </div>' +
'</div>',
methods: {
handleInputChange: function () {
console.log("handleInputChange: " + this.searchText);
var self = this;
if (this.searchText.length > 2) {
$.ajax({
url: "/api/badges?filter=" + this.searchText,
dataType: "json",
type: "GET",
contentType: "application/json; charset=utf-8",
dataFilter: function (data) { return data; },
success: function (data) {
console.log(data);
self.emptyList();
data.forEach(function (item) {
self.list.push(JSON.parse(item));
});
self.positionListBox();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
} else {
this.emptyList();
}
},
handleSelect: function (item) {
console.log(item);
this.searchText = item.label;
this.emptyList();
this.$emit("selected", item);
},
emptyList: function () {
var count = this.list.length;
for (var x = 1; x <= count; x++) {
this.list.shift();
}
},
positionListBox: function () {
}
},
mounted: function () {
console.log("EmpSearch: ", this.$refs.listBox);
this.listBoxStyle.top = this.$refs.inputBox.getBoundingClientRect().top + this.$refs.inputBox.getBoundingClientRect().height;
this.listBoxStyle.left = this.$refs.inputBox.getBoundingClientRect().left;
}
});
Upvotes: 1
Views: 61
Reputation: 4066
When you change listBoxStyle.top
and listBoxStyle.left
you must declare their units. otherwise, they treated as a broken CSS property
mounted: function () {
console.log("EmpSearch: ", this.$refs.listBox);
this.listBoxStyle.top = this.$refs.inputBox.getBoundingClientRect().top + this.$refs.inputBox.getBoundingClientRect().height + 'px';
this.listBoxStyle.left = this.$refs.inputBox.getBoundingClientRect().left + 'px';
}
Upvotes: 2