Skip to content

Commit f3afb01

Browse files
committed
set typeAheadPointer on hover, reset value when options or multiple change
1 parent d937e86 commit f3afb01

File tree

6 files changed

+22156
-68
lines changed

6 files changed

+22156
-68
lines changed

dist/build.js

Lines changed: 22008 additions & 4 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
"babelify"
1818
]
1919
},
20-
"repository" : {
21-
"type" : "git",
22-
"url" : "https://github.com/sagalbot/vue-select.git"
20+
"repository": {
21+
"type": "git",
22+
"url": "https://github.com/sagalbot/vue-select.git"
2323
},
2424
"dependencies": {
2525
"vue": "^1.0.0"

src/App.vue

Lines changed: 89 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,57 @@
11
<template>
2-
<div id="app" class="container">
3-
4-
<h1>Vue Select</h1>
5-
<p class="lead">A simple component that provides similar functionality to Select2 without the overhead of jQuery.</p>
6-
7-
<hr>
2+
<div class="jumbotron">
3+
<div class="container">
4+
<h1>Vue Select</h1>
5+
<p class="lead">A simple component that provides similar functionality to Select2 without the overhead of jQuery.</p>
6+
<a class="btn btn-primary" href="https://github.com/sagalbot/vue-select">View on GitHub</a>
7+
</div>
8+
</div>
89

9-
<div class="row">
10-
<div class="col-md-6">
11-
<v-select
12-
:placeholder="placeholder"
13-
:value.sync="select"
14-
:options="options"
15-
:multiple="multiple">
16-
</v-select>
17-
</div>
10+
<div class="jumbotron" style="background: none;">
11+
<div class="row">
12+
<div class="col-md-6 col-md-offset-3">
13+
<v-select
14+
:placeholder="placeholder"
15+
:value.sync="select"
16+
:options="options[optionType]"
17+
:multiple="multiple">
18+
</v-select>
19+
</div>
1820

19-
<div class="col-md-6">
20-
<pre><strong>Selected:</strong>{{ select | json }}</pre>
21+
<!-- <div class="col-md-6">
22+
<h4>Output</h4>
23+
<pre>{{ select | json }}</pre>
24+
</div> -->
2125
</div>
2226
</div>
2327

24-
<hr>
28+
<div id="app" class="container">
29+
<h4 class="page-header">Component Settings <small>play around with the above vue-select</small></h4>
2530

2631
<div class="row">
2732
<div class="col-md-6">
28-
<h4>Todos:</h4>
29-
<ul>
30-
<li>Fix layout issue where selected tags & text input overflow outside <code>.dropdown</code>.</li>
31-
<li>Clicking the 'caret' icon should toggle the dropdown.</li>
32-
<li>Add boolean prop to disable search.</li>
33-
<li>Add a 'simple' prop that disables search, and the selected 'tags'. Uses an active class on the selected item(s) while keeping the placeholder constant.</li>
34-
</ul>
33+
<label class="control-label">Allow Multiple</label>
34+
<div class="checkbox">
35+
<label class="control-label">
36+
<input v-model="multiple" type="checkbox"> True
37+
</label>
38+
<span class="help-block">Equivalent to the <code>multiple</code> attribute to a <code>&#x3C;select&#x3E;</code>. You'll want to clear any selections you have made before changing this option. It's not one that should be changed after render.</span>
39+
</div>
40+
41+
<label class="control-label">Option Set Type</label><br>
42+
<div class="radio">
43+
<label for="advanced">
44+
<input id="advanced" type="radio" v-model="optionType" value="advanced"> Advanced <code>[{value: 'foo', label: 'Foo'}]</code>
45+
</label>
46+
47+
<label for="simple">
48+
<input id="simple" type="radio" v-model="optionType" value="simple"> Simple <code>['foo', 'bar']</code>
49+
</label>
50+
<span class="help-block">The <code>options</code> property is watched for changes, and the value is reset anytime the options change. This is useful if you have multiple selection boxes that depend on its ancestors values.</span>
51+
</div>
3552
</div>
3653

3754
<div class="col-md-6">
38-
<h4>Component Props</h4>
3955

4056
<div class="form-group">
4157
<label class="control-label">Max Height</label>
@@ -48,34 +64,50 @@
4864
<input type="text" v-model="placeholder" class="form-control">
4965
<span class="help-block">Equivalent to the <code>placeholder</code> attribute.</span>
5066
</div>
51-
52-
53-
<div class="checkbox">
54-
<label class="control-label">
55-
<input v-model="multiple" type="checkbox"> Multiple
56-
</label>
57-
<span class="help-block">Equivalent to the <code>multiple</code> attribute to a <code>&#x3C;select&#x3E;</code>. You'll want to clear any selections you have made before changing this option. It's not one that should be changed after render.</span>
58-
</div>
59-
60-
<div class="form-group">
61-
62-
</div>
6367
</div>
6468
</div>
6569

66-
<hr>
70+
<!-- <h3>Todos:</h3>
71+
<ul>
72+
<li>Fix layout issue where selected tags & text input overflow outside <code>.dropdown</code>.</li>
73+
<li>Clicking the 'caret' icon should toggle the dropdown.</li>
74+
<li>Add boolean prop to disable search.</li>
75+
<li>Add a 'simple' prop that disables search, and the selected 'tags'. Uses an active class on the selected item(s) while keeping the placeholder constant.</li>
76+
</ul> -->
77+
78+
<h2 class="page-header">Installing</h2>
79+
<p><code>npm install sagalbot/vue-select</code></p>
80+
81+
<h2 class="page-header">Usage</h2>
82+
<pre v-pre>
83+
&#x3C;template&#x3E;
84+
&#x3C;div id=&#x22;myApp&#x22;&#x3E;
85+
&#x3C;v-select:value.sync=&#x22;selected&#x22; :options=&#x22;options&#x22;&#x3E;&#x3C;/v-select&#x3E;
86+
&#x3C;/div&#x3E;
87+
&#x3C;/template&#x3E;
88+
89+
&#x3C;script&#x3E;
90+
import vSelect from &#x27;vue-select&#x27;
91+
export default {
92+
components: {vSelect},
93+
94+
data() {
95+
return {
96+
selected: null,
97+
options: [&#x27;foo&#x27;,&#x27;bar&#x27;,&#x27;baz&#x27;]
98+
}
99+
}
100+
}
101+
&#x3C;/script&#x3E;
102+
</pre>
67103

68-
<h3>Build Setup</h3>
69-
<h5>install dependencies</h5>
70-
<p><code>npm install</code></p>
71-
<h5>serve with hot reload at localhost:8080</h5>
72-
<p><code>npm run dev</code></p>
73-
<h5>build for production with minification</h5>
74-
<p><code>npm run build</code></p>
75-
<h5>lint all *.js and *.vue files</h5>
76-
<p><code>npm run lint</code></p>
77-
<h5>run unit tests</h5>
78-
<p><code>npm test</code></p>
104+
<h2 class="page-header">Contributing</h2>
105+
<h4>Build Setup <small>built using the <a href="https://github.com/vuejs-templates/webpack">vue-cli webpack template</a></small></h4>
106+
<p>install dependencies <br/><code>npm install</code></p>
107+
<p>serve with hot reload at localhost:8080 <br><code>npm run dev</code></p>
108+
<p>build for production with minification <br><code>npm run build</code></p>
109+
<p>lint all *.js and *.vue files <br><code>npm run lint</code></p>
110+
<p>run unit tests <br><code>npm test</code></p>
79111

80112
</div>
81113
</template>
@@ -91,14 +123,17 @@ export default {
91123
92124
data() {
93125
return {
94-
// select: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}],
95126
select: null,
96127
placeholder: 'Choose a Country',
97128
multiple: true,
98129
maxHeight: '400px',
99-
options: require('./countries.js')
100-
// options: ['one','two','three']
101-
// options: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}, {label: 'This is Baz', value: 'baz'}]
130+
options: {
131+
advanced: require('./countries.js'),
132+
simple: require('./simpleCountries.js'),
133+
simpler: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}, {label: 'This is Baz', value: 'baz'}]
134+
135+
},
136+
optionType: 'advanced'
102137
}
103138
}
104139
}

src/components/Select.vue

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@
142142
</div>
143143

144144
<ul v-show="open" :transition="transition" :style="{ 'max-height': maxHeight }" class="dropdown-menu animated">
145-
<li v-for="option in filteredOptions" :class="{ active: isOptionSelected(option), highlight: $index === typeAheadPointer }">
145+
<li v-for="option in filteredOptions" :class="{ active: isOptionSelected(option), highlight: $index === typeAheadPointer }" @mouseover="typeAheadPointer = $index">
146146
<a @mousedown.prevent="select(option)">
147147
{{ getOptionLabel(option) }}
148148
</a>
@@ -159,7 +159,6 @@
159159
160160
props: {
161161
value: {
162-
// type: Array,
163162
twoway: true,
164163
required: true
165164
},
@@ -201,17 +200,23 @@
201200
}
202201
},
203202
204-
ready() {
205-
this.$watch('open', function(open) {
203+
watch: {
204+
open( open ) {
206205
if( open ) {
207206
this.$els.search.focus();
208207
} else {
209208
this.$els.search.blur();
210209
this.typeAheadPointer = 0;
211210
}
212-
});
211+
},
212+
options() {
213+
this.$set('value', this.multiple ? [] : null)
214+
},
215+
multiple( val ) {
216+
this.$set('value', val ? [] : null)
217+
}
213218
},
214-
219+
215220
methods: {
216221
select(option) {
217222
if (! this.isOptionSelected(option) ) {

src/simpleCountries.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/unit/Select.spec.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ import Vue from 'vue'
44
import vSelect from '../../src/components/Select.vue'
55

66
describe('Select.vue', () => {
7+
8+
// it('sets open to true when search on focus and false on blur', () => {
9+
// const vm = new Vue({
10+
// template: '<div><v-select :value.sync="value"></v-select></div>',
11+
// components: { vSelect },
12+
// data: {
13+
// value: ['one'],
14+
// options: ['one','two','three']
15+
// }
16+
// }).$mount()
17+
//
18+
// vm.$children[0].$els.search.focus()
19+
// expect(vm.$children[0].$get('open')).toEqual(true)
20+
// })
21+
722
it('can accept an array with pre-selected values', () => {
823
const vm = new Vue({
924
template: '<div><v-select :value.sync="value"></v-select></div>',
@@ -33,7 +48,7 @@ describe('Select.vue', () => {
3348
//
3449
// expect(vm.$children[0].$get('value')).toEqual({label: 'This is Foo', value: 'foo'})
3550
// })
36-
//
51+
//
3752

3853
it('can determine if the value prop is empty', () => {
3954
const vm = new Vue({
@@ -57,6 +72,34 @@ describe('Select.vue', () => {
5772
select.$set('value', null)
5873
expect(select.isValueEmpty).toEqual(true)
5974
})
75+
76+
it('resets the selected values when the options property changes', () => {
77+
const vm = new Vue({
78+
template: '<div><v-select :value.sync="value"></v-select></div>',
79+
components: { vSelect },
80+
data: {
81+
value: ['one'],
82+
options: ['one','two','three']
83+
}
84+
}).$mount()
85+
86+
vm.$children[0].options = ['four','five','six']
87+
expect(vm.$children[0].$get('value')).toEqual([])
88+
})
89+
90+
it('can retain values present in a new array of options', () => {
91+
const vm = new Vue({
92+
template: '<div><v-select :value.sync="value"></v-select></div>',
93+
components: { vSelect },
94+
data: {
95+
value: ['one'],
96+
options: ['one','two','three']
97+
}
98+
}).$mount()
99+
100+
vm.$children[0].$set('options', ['one','five','six'])
101+
expect(vm.$children[0].value).toEqual(['one'])
102+
})
60103
})
61104

62105

0 commit comments

Comments
 (0)