Andrew
Andrew

Reputation: 23

Bound style in component not updating

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

Answers (1)

Farnabaz
Farnabaz

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

Related Questions