1

I am creating a custom dropdown element, with following HTML and some CSS:

<div id="dd" class="col-md-4 col-lg-4 wrapper-dropdown-3 left-divider" tabindex="1">
    <span>Age</span>
    <ul class="dropdown">\
      <li><a href="#"><i class="icon-envelope icon-large"></i>1 Month Old</a></li>
      <li><a href="#"><i class="icon-truck icon-large"></i>11 Month Old</a></li>
    </ul>
</div>

But How do I bind the value selected by the dropdown to some vue variable?

I tried <span v-bind="dataVar">Age</span>, but dataVar does not changes when you change value of dropdown. I had defined dataVar like follwoing

data: function() { 
  return { 
    dataVar: ''
  }
},

How do I have selected value of dropdown in dataVar variable?

Working drop down in jsfiddle, in Go to Foo view.

4
  • Why don't create a Vue component? Commented Dec 13, 2016 at 11:26
  • @GerardReches that seems promising, but still how will I bind a variable as value in HTML is being changed by javascript. Commented Dec 13, 2016 at 11:30
  • Can you please add to the question what you want to achieve? I'm not understanding what do you mean with bind this piece of code to a vue variable. Commented Dec 13, 2016 at 11:33
  • Can't you just use a method for that? updated Fiddle: jsfiddle.net/0xzkv7ko Commented Dec 13, 2016 at 11:43

2 Answers 2

3

I rewrite you custom select. You need use: v-model. Yes it's work not only for inputs. See docs

Example usage:

 <h3>Selected: {{ selected.name }}</h3>

 <custom-select :options="options"
                value-key="id" 
                label-key="name"
                v-model="selected"></custom-select>
             
             
 <div style="margin-top: 40px">
     <h3>Wihtout labels, for simple values, like numbers</h3>
  
     <custom-select :options="options"
                    v-model="selected"></custom-select>
 </div>

Enjoy DEMO with clean source code

Sign up to request clarification or add additional context in comments.

3 Comments

I want to control opening of dropdown from parent component, How can I do this with this approach, should I make opened as props or pass another prop and have watcher over it?
Yes, make "opened" as prop with "default: false".
0

modifications:

1.function DropDown (el,onChange) { this.onChange = onChange

2.obj.opts.on('click', function () { .... obj.onChange(obj.val)

3.<span> this is foo </span> <span> my value is {{selected}} </span>\

https://jsfiddle.net/postor/z79b0ksk/2/

there are two ways for this case:

  1. I choose to use bind change and use vm.$set, since you have the change handle already

  2. you can choose to make selections inside Vue management, that would be something like data:()=>{selected:null,options:['one month','11 month']} <div v-for="opt in options" v-on:click="selected=opt">

/* global $:true */
function DropDown (el,onChange) {
  this.dd = el
  this.placeholder = this.dd.children('span')
  this.opts = this.dd.find('ul.dropdown > li')
  this.val = ''
  this.index = -1
  this.initEvents()
  this.onChange = onChange
}

DropDown.prototype = {
  initEvents: function () {
    var obj = this

    obj.dd.on('click', function (event) {
      $(this).toggleClass('active')
      return false
    })

    obj.opts.on('click', function () {
      var opt = $(this)
      obj.val = opt.text()
      obj.index = opt.index()
      obj.placeholder.text(obj.val)
      obj.onChange(obj.val)
    })
  },
  getValue: function () {
    return this.val
  },
  getIndex: function () {
    return this.index
  }
}


// Define some components
const Foo = {
  template: '<div>\
        <div id="dd" class="col-md-4 col-lg-4 wrapper-dropdown-3 left-divider" tabindex="1">\
        <span>Age</span>\
        <ul class="dropdown">\
          <li><a href="#"><i class="icon-envelope icon-large"></i>1 Month Old</a></li>\
          <li><a href="#"><i class="icon-truck icon-large"></i>11 Month Old</a></li>\
        </ul>\
      </div>\
  <div class="card row" >\
  <div class="col-xs-5" style="height: 100px; background-color: red; position: fixed;">\
  <span> this is foo </span>\
    </div>\
      <div class="col-xs-7" style="height: 100px; background-color: Yellow">\
  <span> this is foo </span>\
  <span> my value is {{selected}} </span>\
    </div>\
  </div>\
</div>',
  data: function() { return {  
  	selected:null
  }},
  mounted () {
	 new DropDown($(this.$el.querySelector('#dd')),(val)=>{
   	this.selected = val
   })    
  }
};

const  Bar = {
  template: '<p>This is bar!</p>',
  data: function() { return {  
  }}
};


// Create a router instance.
// You can pass in additional options here, but let's
// keep it simple for now.
const router = new VueRouter({
  mode: 'history',
    scrollBehavior: (to, from, savedPosition) => {
    if (to.hash) {
      return {selector: to.hash}
    } else {
      return {x: 0, y: 0}
    }
    },
    routes: [
    { path: '/foo', component: Foo },
    { path: '/bar', component: Bar },
  ]
})

const app = new Vue({
  router
}).$mount('#app')

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.