Skip to content

Commit f0351f3

Browse files
author
Damian Dulisz
committed
Groups and other fixes
Fix: shentao#150 Fix: shentao#144 Fix: shentao#147 Fix: shentao#128 Fix: shentao#109 Fix: shentao#102
1 parent f6f08a2 commit f0351f3

File tree

11 files changed

+117
-53
lines changed

11 files changed

+117
-53
lines changed

docs/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ new Vue({
7878
multiValue: [{ name: 'Vue.js', language: 'JavaScript' }],
7979
multiple: true,
8080
taggingOptions: [{ name: 'Vue.js', code: 'vu' }, { name: 'Javascript', code: 'js' }, { name: 'Monterail', code: 'pl' }, { name: 'Open Source', code: 'os' }],
81-
taggingSelected: [],
81+
taggingSelected: [{ name: 'Javascript', code: 'js' }, { name: 'Custom', code: 'cstm' }],
8282
searchable: true,
8383
placeholder: 'Select props',
8484
countries: moreCountries,

docs/partials/examples/_groups.jade

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
h2.typo__h2#groups Groups
22
p.typo__p
3-
| To enable groups...
3+
| To enable groups
44
.grid__row
55
.grid__column.grid__unit--md-5
66
label.typo__label Groups
@@ -10,7 +10,7 @@ p.typo__p
1010
:multiple="true",
1111
:searchable="true",
1212
:close-on-select="false",
13-
group-key="values",
13+
group-values="values",
1414
group-label="groupLabel",
1515
placeholder="Type to search",
1616
track-by="id",

lib/Multiselect.vue

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<template>
22
<div
3-
tabindex="0"
3+
:tabindex="searchable ? -1 : 0"
44
:class="{ 'multiselect--active': isOpen, 'multiselect--disabled': disabled }"
55
@focus="activate()"
66
@blur="searchable ? false : deactivate()"
77
@keydown.self.down.prevent="pointerForward()"
88
@keydown.self.up.prevent="pointerBackward()"
9-
@keydown.enter.tab.stop.prevent.self="addPointerElement($event)"
9+
@keydown.enter.tab.stop.self="addPointerElement($event)"
1010
@keyup.esc="deactivate()"
1111
class="multiselect">
1212
<div @mousedown.prevent="toggle()" class="multiselect__select"></div>
@@ -31,7 +31,6 @@
3131
<div v-show="loading" class="multiselect__spinner"></div>
3232
</transition>
3333
<input
34-
name="search"
3534
ref="search"
3635
type="text"
3736
autocomplete="off"
@@ -45,7 +44,7 @@
4544
@keyup.esc="deactivate()"
4645
@keydown.down.prevent="pointerForward()"
4746
@keydown.up.prevent="pointerBackward()"
48-
@keydown.enter.tab.stop.prevent.self="addPointerElement($event)"
47+
@keydown.enter.tab.stop.self="addPointerElement($event)"
4948
@keydown.delete="removeLastElement()"
5049
class="multiselect__input"/>
5150
<span
@@ -67,7 +66,7 @@
6766
</span>
6867
</li>
6968
<template v-if="!max || internalValue.length < max">
70-
<li v-for="(option, index) of filteredOptions" :key="index">
69+
<li class="multiselect__element" v-for="(option, index) of filteredOptions" :key="index">
7170
<span
7271
tabindex="0"
7372
v-if="!option.$isLabel"
@@ -278,6 +277,7 @@ fieldset[disabled] .multiselect {
278277
.multiselect__single {
279278
font-family: inherit;
280279
font-size: 14px;
280+
touch-action: manipulation;
281281
}
282282
283283
.multiselect {
@@ -486,6 +486,10 @@ fieldset[disabled] .multiselect {
486486
display: none;
487487
}
488488
489+
.multiselect__element {
490+
display: block;
491+
}
492+
489493
.multiselect__option {
490494
display: block;
491495
padding: 12px;
@@ -557,7 +561,7 @@ fieldset[disabled] .multiselect {
557561
background: #ededed;
558562
color: #a6a6a6;
559563
cursor: text;
560-
/*pointer-events: none;*/
564+
pointer-events: none;
561565
}
562566
563567
.multiselect__option--disabled.multiselect__option--highlight {
@@ -572,7 +576,6 @@ fieldset[disabled] .multiselect {
572576
.multiselect-enter,
573577
.multiselect-leave-active {
574578
opacity: 0;
575-
max-height: 0 !important;
576579
}
577580
578581
@keyframes spinning {

lib/multiselectMixin.js

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -238,24 +238,48 @@ module.exports = {
238238
type: Number,
239239
default: 1000
240240
},
241-
groupKey: {
241+
/**
242+
* Name of the property containing
243+
* the group values
244+
* @default 1000
245+
* @type {String}
246+
*/
247+
groupValues: {
242248
type: String
243249
},
250+
/**
251+
* Name of the property containing
252+
* the group label
253+
* @default 1000
254+
* @type {String}
255+
*/
244256
groupLabel: {
245257
type: String
258+
},
259+
/**
260+
* Array of keyboard keys to block
261+
* when selecting
262+
* @default 1000
263+
* @type {String}
264+
*/
265+
blockKeys: {
266+
type: Array,
267+
default () {
268+
return []
269+
}
246270
}
247271
},
248272
created () {
249273
if (this.searchable) this.adjustSearch()
250274
},
251275
computed: {
252276
filteredOptions () {
253-
let search = this.search || ''
277+
let search = this.search.toLowerCase() || ''
254278

255279
let options = this.options
256280

257281
if (this.localSearch) {
258-
options = this.groupKey
282+
options = this.groupValues
259283
? this.filterAndFlat(options, search, this.label)
260284
: filterOptions(options, search, this.label)
261285

@@ -280,7 +304,7 @@ module.exports = {
280304
}
281305
},
282306
optionKeys () {
283-
const options = this.groupKey ? this.flatAndStrip(this.options) : this.options
307+
const options = this.groupValues ? this.flatAndStrip(this.options) : this.options
284308
return this.label
285309
? options.map(element => element[this.label].toString().toLowerCase())
286310
: options.map(element => element.toString().toLowerCase())
@@ -308,20 +332,30 @@ module.exports = {
308332
}
309333
},
310334
methods: {
335+
/**
336+
* Filters and then flattens the options list
337+
* @param {Array}
338+
* @returns {Array} returns a filtered and flat options list
339+
*/
311340
filterAndFlat (options) {
312341
return flow(
313-
filterGroups(this.search, this.label, this.groupKey, this.groupLabel),
314-
flattenOptions(this.groupKey, this.groupLabel)
342+
filterGroups(this.search, this.label, this.groupValues, this.groupLabel),
343+
flattenOptions(this.groupValues, this.groupLabel)
315344
)(options)
316345
},
346+
/**
347+
* Flattens and then strips the group labels from the options list
348+
* @param {Array}
349+
* @returns {Array} returns a flat options list without group labels
350+
*/
317351
flatAndStrip (options) {
318352
return flow(
319-
flattenOptions(this.groupKey, this.groupLabel),
353+
flattenOptions(this.groupValues, this.groupLabel),
320354
stripGroups
321355
)(options)
322356
},
323357
updateSearch (query) {
324-
this.search = query.trim().toLowerCase().toString()
358+
this.search = query.trim().toString()
325359
},
326360
/**
327361
* Finds out if the given query is already present
@@ -383,15 +417,16 @@ module.exports = {
383417
* @param {Object||String||Integer} option to select/deselect
384418
* @param {Boolean} block removing
385419
*/
386-
select (option, cantRemove) {
420+
select (option, key) {
421+
if (this.blockKeys.indexOf(key) !== -1 || this.disabled) return
387422
if (this.max && this.multiple && this.internalValue.length === this.max) return
388423
if (option.isTag) {
389424
this.$emit('tag', option.label, this.id)
390425
this.search = ''
391426
} else {
392427
if (this.multiple) {
393428
if (this.isSelected(option)) {
394-
if (!cantRemove) this.removeElement(option)
429+
if (key !== 'Tab') this.removeElement(option)
395430
return
396431
} else {
397432
this.internalValue.push(option)
@@ -400,7 +435,7 @@ module.exports = {
400435
const isSelected = this.isSelected(option)
401436

402437
/* istanbul ignore else */
403-
if (isSelected && (!this.allowEmpty || cantRemove)) return
438+
if (isSelected && (!this.allowEmpty || key === 'Tab')) return
404439

405440
this.internalValue = isSelected ? null : option
406441
}
@@ -420,6 +455,7 @@ module.exports = {
420455
*/
421456
removeElement (option) {
422457
/* istanbul ignore else */
458+
if (this.disabled) return
423459
if (!this.allowEmpty && this.internalValue.length <= 1) return
424460

425461
const index = (this.multiple && typeof option === 'object')
@@ -438,6 +474,7 @@ module.exports = {
438474
*/
439475
removeLastElement () {
440476
/* istanbul ignore else */
477+
if (this.blockKeys.indexOf('Delete') !== -1) return
441478
if (this.search.length === 0 && Array.isArray(this.internalValue)) {
442479
this.removeElement(this.internalValue[this.internalValue.length - 1])
443480
}
@@ -449,6 +486,7 @@ module.exports = {
449486
activate () {
450487
/* istanbul ignore else */
451488
if (this.isOpen) return
489+
if (this.disabled) return
452490

453491
this.isOpen = true
454492
/* istanbul ignore else */

lib/pointerMixin.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ module.exports = {
3333
'multiselect__option--selected': this.isSelected(option)
3434
}
3535
},
36-
addPointerElement (e = 'Enter') {
36+
addPointerElement ({ key } = 'Enter') {
3737
if (this.filteredOptions[this.pointer].isLabel) return
3838
if (this.filteredOptions.length > 0) {
39-
this.select(this.filteredOptions[this.pointer], e.key === 'Tab')
39+
this.select(this.filteredOptions[this.pointer], key)
4040
}
4141
this.pointerReset()
4242
},

lib/vue-multiselect.min.js

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

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-multiselect",
3-
"version": "2.0.0-beta.10",
3+
"version": "2.0.0-beta.11",
44
"description": "Multiselect component for vue.js",
55
"author": "Damian Dulisz <damian.dulisz@monterail.com>",
66
"private": false,
@@ -78,11 +78,12 @@
7878
"sinon": "^1.17.3",
7979
"sinon-chai": "^2.8.0",
8080
"url-loader": "^0.5.7",
81-
"vue": "^2.0.7",
81+
"vue": "^2.1.0",
8282
"vue-hot-reload-api": "^1.2.0",
8383
"vue-html-loader": "^1.0.0",
84-
"vue-loader": "^9.7.0",
84+
"vue-loader": "^10.0.0",
8585
"vue-style-loader": "^1.0.0",
86+
"vue-template-compiler": "^2.1.6",
8687
"webpack": "^1.13.0",
8788
"webpack-dev-middleware": "^1.4.0",
8889
"webpack-hot-middleware": "^2.6.0",

src/Multiselect.vue

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<template>
22
<div
3-
tabindex="0"
3+
:tabindex="searchable ? -1 : 0"
44
:class="{ 'multiselect--active': isOpen, 'multiselect--disabled': disabled }"
55
@focus="activate()"
66
@blur="searchable ? false : deactivate()"
77
@keydown.self.down.prevent="pointerForward()"
88
@keydown.self.up.prevent="pointerBackward()"
9-
@keydown.enter.tab.stop.prevent.self="addPointerElement($event)"
9+
@keydown.enter.tab.stop.self="addPointerElement($event)"
1010
@keyup.esc="deactivate()"
1111
class="multiselect">
1212
<div @mousedown.prevent="toggle()" class="multiselect__select"></div>
@@ -44,7 +44,7 @@
4444
@keyup.esc="deactivate()"
4545
@keydown.down.prevent="pointerForward()"
4646
@keydown.up.prevent="pointerBackward()"
47-
@keydown.enter.tab.stop.prevent.self="addPointerElement($event)"
47+
@keydown.enter.tab.stop.self="addPointerElement($event)"
4848
@keydown.delete="removeLastElement()"
4949
class="multiselect__input"/>
5050
<span
@@ -66,7 +66,7 @@
6666
</span>
6767
</li>
6868
<template v-if="!max || internalValue.length < max">
69-
<li v-for="(option, index) of filteredOptions" :key="index">
69+
<li class="multiselect__element" v-for="(option, index) of filteredOptions" :key="index">
7070
<span
7171
tabindex="0"
7272
v-if="!option.$isLabel"
@@ -486,6 +486,10 @@ fieldset[disabled] .multiselect {
486486
display: none;
487487
}
488488
489+
.multiselect__element {
490+
display: block;
491+
}
492+
489493
.multiselect__option {
490494
display: block;
491495
padding: 12px;
@@ -557,7 +561,7 @@ fieldset[disabled] .multiselect {
557561
background: #ededed;
558562
color: #a6a6a6;
559563
cursor: text;
560-
/*pointer-events: none;*/
564+
pointer-events: none;
561565
}
562566
563567
.multiselect__option--disabled.multiselect__option--highlight {
@@ -572,7 +576,6 @@ fieldset[disabled] .multiselect {
572576
.multiselect-enter,
573577
.multiselect-leave-active {
574578
opacity: 0;
575-
max-height: 0 !important;
576579
}
577580
578581
@keyframes spinning {

0 commit comments

Comments
 (0)