Bindrid
Bindrid

Reputation: 3735

vuejs with select 2 control missing

enter image description hereI have a very simple Vue js setup that I am trying to used to bind a select2 using a directive. I would rather use a template but for reasons beyond my control I am actual forced to use an asp:DropDownList which means I am forced to have my select boxes inline on the client side.

So I am attempting to set up a Vue.directive but after executing the directive, the select2 is not anywhere to be found. Because the select2 was executed, the original select box get hidden and I end up with nothing showing on the page.

debugging stops are being hit and there are not errors being displayed in the console.

        <div id="tabUserInfo">
            <input id="myid" type="text" required="required"  ref="myid" v-model="firstName" />
            <span>{{firstName}}</span>
            <select id="sel" v-select2="''" v-model="optid">
                <option value="1">1</option>
                <option value="2">2</option>
            </select>

        </div><script type="text/javascript">
            $(document).ready(function () {
                Vue.directive('select2', {
                    bind: function (elem, fieldName) {
                        $(elem).select2();
                        debugger;
                    },
                    unbind: function (elem) {
                        debugger;
                    }
                });
                var me = "Scott";
                var vm = new Vue({

                    el: '#tabUserInfo',
                    data: { firstName: 'Scott', optid:2 },
                });
            });

    </script>

Upvotes: 1

Views: 855

Answers (1)

Bert
Bert

Reputation: 82439

Change the hook from bind to inserted. It seems like select2 needs the element to be in the DOM in order to work correctly.

Vue.directive('select2', {
  inserted: function (elem, fieldName) {
    $(elem).select2();
  },
  unbind: function (elem) {}
});

In order to handle updates to a data value, the directive needs to be modified.

 Vue.directive('select2', {
   inserted: function (elem, binding, vnode) {
     let select = $(elem)
     select.select2();
     select.val(vnode.context[binding.expression]).trigger("change")
     select.on("change", function (evt) {
       vnode.context[binding.expression] = evt.target.value
     })
   },
   update: function (elem, binding, vnode) {
     let select = $(elem)
     select.val(vnode.context[binding.expression]).trigger("change")
   }
 });

Normally, vnode should be treated as a read only parameter, but given the constraints of your situation this directive cheats a little. Your dropdown should now be something like this:

<asp:DropDownList runat="server" ID="Dropdown" v-select2="optid">

Note that the argument of the directive is the data property to bind. It replaces, v-model.

Upvotes: 1

Related Questions