Skip to content

Commit b0f58d7

Browse files
author
Jeff
committed
Merge commit 'b92428101f1c6d4aa1fe864a88eb7079c245e009'
# Conflicts: # test/unit/specs/Select.spec.js
2 parents af4e55c + b924281 commit b0f58d7

File tree

3 files changed

+337
-27
lines changed

3 files changed

+337
-27
lines changed

docs/gitbook/Basics/Options.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,27 @@ If you wanted to display `Canada` in the dropdown, you'd use the `countryName` k
3333

3434
[](codepen://sagalbot/aEjLPB?height=500)
3535

36+
37+
### Option index {#values}
38+
39+
When the `options` array contains objects, `vue-select` returns the whole object as dropdown value upon selection. You can specify your own `index` prop to return only the value contained in the specific property.
40+
41+
For example, consider an object with `value` and `label` properties:
42+
43+
```json
44+
{
45+
value: "CA",
46+
label: "Canada"
47+
}
48+
```
49+
50+
If you wanted to return `CA` in the dropdown when `Canada` is selected, you'd use the `index` key:
51+
52+
```html
53+
<v-select index="value" :options="countries"></v-select>
54+
```
55+
56+
3657
### Null / Empty Options {#null}
3758

3859
`vue-select` requires the `option` property to be an `array`. If you are using Vue in development mode, you will get warnings attempting to pass anything other than an `array` to the `options` prop. If you need a `null`/`empty` value, use an empty array `[]`.

src/components/Select.vue

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -360,13 +360,13 @@
360360
aria-label="Search for option"
361361
>
362362

363-
<button
364-
v-show="showClearButton"
365-
:disabled="disabled"
363+
<button
364+
v-show="showClearButton"
365+
:disabled="disabled"
366366
@click="clearSelection"
367-
type="button"
368-
class="clear"
369-
title="Clear selection"
367+
type="button"
368+
class="clear"
369+
title="Clear selection"
370370
>
371371
<span aria-hidden="true">&times;</span>
372372
</button>
@@ -522,16 +522,36 @@
522522
default: 'label'
523523
},
524524
525+
/**
526+
* Tells vue-select what key to use when generating option
527+
* values when each `option` is an object.
528+
* @type {String}
529+
*/
530+
index: {
531+
type: String,
532+
default: null
533+
},
534+
525535
/**
526536
* Callback to generate the label text. If {option}
527537
* is an object, returns option[this.label] by default.
538+
*
539+
* Label text is used for filtering comparison and
540+
* displaying. If you only need to adjust the
541+
* display, you should use the `option` and
542+
* `selected-option` slots.
543+
*
528544
* @type {Function}
529545
* @param {Object || String} option
530546
* @return {String}
531547
*/
532548
getOptionLabel: {
533549
type: Function,
534550
default(option) {
551+
if( this.index ) {
552+
option = this.findOptionByIndexValue(option)
553+
}
554+
535555
if (typeof option === 'object') {
536556
if (!option.hasOwnProperty(this.label)) {
537557
return console.warn(
@@ -540,9 +560,7 @@
540560
'http://sagalbot.github.io/vue-select/#ex-labels'
541561
)
542562
}
543-
if (this.label && option[this.label]) {
544-
return option[this.label]
545-
}
563+
return option[this.label]
546564
}
547565
return option;
548566
}
@@ -786,7 +804,15 @@
786804
if (this.taggable && !this.optionExists(option)) {
787805
option = this.createOption(option)
788806
}
789-
807+
if(this.index) {
808+
if (!option.hasOwnProperty(this.index)) {
809+
return console.warn(
810+
`[vue-select warn]: Index key "option.${this.index}" does not` +
811+
` exist in options object ${JSON.stringify(option)}.`
812+
)
813+
}
814+
option = option[this.index]
815+
}
790816
if (this.multiple && !this.mutableValue) {
791817
this.mutableValue = [option]
792818
} else if (this.multiple) {
@@ -808,7 +834,7 @@
808834
if (this.multiple) {
809835
let ref = -1
810836
this.mutableValue.forEach((val) => {
811-
if (val === option || typeof val === 'object' && val[this.label] === option[this.label]) {
837+
if (val === option || (this.index && val === option[this.index]) || (typeof val === 'object' && val[this.label] === option[this.label])) {
812838
ref = val
813839
}
814840
})
@@ -867,22 +893,50 @@
867893
* @return {Boolean} True when selected | False otherwise
868894
*/
869895
isOptionSelected(option) {
870-
if (this.multiple && this.mutableValue) {
871896
let selected = false
872-
this.mutableValue.forEach(opt => {
873-
if (typeof opt === 'object' && opt[this.label] === option[this.label]) {
874-
selected = true
875-
} else if (typeof opt === 'object' && opt[this.label] === option) {
876-
selected = true
877-
}
878-
else if (opt === option) {
897+
this.valueAsArray.forEach(value => {
898+
if (typeof value === 'object') {
899+
selected = this.optionObjectComparator(value, option)
900+
} else if (value === option || value === option[this.index]) {
879901
selected = true
880902
}
881903
})
882904
return selected
905+
},
906+
907+
/**
908+
* Determine if two option objects are matching.
909+
*
910+
* @param value {Object}
911+
* @param option {Object}
912+
* @returns {boolean}
913+
*/
914+
optionObjectComparator(value, option) {
915+
if (this.index && value === option[this.index]) {
916+
return true
917+
} else if ((value[this.label] === option[this.label]) || (value[this.label] === option)) {
918+
return true
919+
} else if (this.index && value[this.index] === option[this.index]) {
920+
return true
883921
}
922+
return false;
923+
},
884924
885-
return this.mutableValue === option
925+
/**
926+
* Finds an option from this.options
927+
* where option[this.index] matches
928+
* the passed in value.
929+
*
930+
* @param value {Object}
931+
* @returns {*}
932+
*/
933+
findOptionByIndexValue(value) {
934+
this.options.forEach(_option => {
935+
if (JSON.stringify(_option[this.index]) === JSON.stringify(value)) {
936+
value = _option
937+
}
938+
})
939+
return value
886940
},
887941
888942
/**
@@ -1061,9 +1115,9 @@
10611115
isValueEmpty() {
10621116
if (this.mutableValue) {
10631117
if (typeof this.mutableValue === 'object') {
1064-
return !Object.keys(this.mutableValue).length
1118+
return ! Object.keys(this.mutableValue).length
10651119
}
1066-
return !this.mutableValue.length
1120+
return ! this.valueAsArray.length
10671121
}
10681122
10691123
return true;
@@ -1074,7 +1128,7 @@
10741128
* @return {Array}
10751129
*/
10761130
valueAsArray() {
1077-
if (this.multiple) {
1131+
if (this.multiple && this.mutableValue) {
10781132
return this.mutableValue
10791133
} else if (this.mutableValue) {
10801134
return [].concat(this.mutableValue)

0 commit comments

Comments
 (0)